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 <rpc/rpcent.h> 27 #include "ns_internal.h" 28 #include "ldap_common.h" 29 30 /* rpc attributes filters */ 31 #define _R_NAME "cn" 32 #define _R_NUMBER "oncrpcnumber" 33 34 35 #define _F_GETRPCBYNAME "(&(objectClass=oncRpc)(cn=%s))" 36 #define _F_GETRPCBYNAME_SSD "(&(%%s)(cn=%s))" 37 #define _F_GETRPCBYNUMBER "(&(objectClass=oncRpc)(oncRpcNumber=%d))" 38 #define _F_GETRPCBYNUMBER_SSD "(&(%%s)(oncRpcNumber=%d))" 39 40 static const char *rpc_attrs[] = { 41 _R_NAME, 42 _R_NUMBER, 43 (char *)NULL 44 }; 45 46 /* 47 * _nss_ldap_rpc2str is the data marshaling method for the rpc getXbyY 48 * (e.g., getbyname(), getbynumber(), getrpcent()) backend processes. 49 * This method is called after a successful ldap search has been performed. 50 * This method will parse the ldap search values into the file format. 51 * e.g. 52 * 53 * nfs_acl 100227 54 * snmp 100122 na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk 55 */ 56 static int 57 _nss_ldap_rpc2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 58 { 59 uint_t i; 60 int nss_result; 61 int buflen = 0, len; 62 char *cname = NULL; 63 char *buffer = NULL; 64 ns_ldap_result_t *result = be->result; 65 ns_ldap_attr_t *names; 66 char **rpcnumber; 67 68 if (result == NULL) 69 return (NSS_STR_PARSE_PARSE); 70 nss_result = NSS_STR_PARSE_SUCCESS; 71 (void) memset(argp->buf.buffer, 0, buflen); 72 73 buflen = argp->buf.buflen; 74 if (argp->buf.result != NULL) { 75 if ((be->buffer = calloc(1, buflen)) == NULL) { 76 nss_result = NSS_STR_PARSE_PARSE; 77 goto result_rpc2str; 78 } 79 buffer = be->buffer; 80 } else 81 buffer = argp->buf.buffer; 82 83 84 names = __ns_ldap_getAttrStruct(result->entry, _R_NAME); 85 if (names == NULL || names->attrvalue == NULL) { 86 nss_result = NSS_STR_PARSE_PARSE; 87 goto result_rpc2str; 88 } 89 /* Get the canonical rpc name */ 90 cname = __s_api_get_canonical_name(result->entry, names, 1); 91 if (cname == NULL || (len = strlen(cname)) < 1) { 92 nss_result = NSS_STR_PARSE_PARSE; 93 goto result_rpc2str; 94 } 95 rpcnumber = __ns_ldap_getAttr(result->entry, _R_NUMBER); 96 if (rpcnumber == NULL || rpcnumber[0] == NULL || 97 (len = strlen(rpcnumber[0])) < 1) { 98 nss_result = NSS_STR_PARSE_PARSE; 99 goto result_rpc2str; 100 } 101 len = snprintf(buffer, buflen, "%s %s", cname, rpcnumber[0]); 102 TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str); 103 /* Append aliases */ 104 for (i = 0; i < names->value_count; i++) { 105 if (names->attrvalue[i] == NULL) { 106 nss_result = NSS_STR_PARSE_PARSE; 107 goto result_rpc2str; 108 } 109 /* Skip the canonical name */ 110 if (strcasecmp(names->attrvalue[i], cname) != 0) { 111 len = snprintf(buffer, buflen, " %s", 112 names->attrvalue[i]); 113 TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str); 114 } 115 } 116 117 /* The front end marshaller doesn't need to copy trailing nulls */ 118 if (argp->buf.result != NULL) 119 be->buflen = strlen(be->buffer); 120 121 result_rpc2str: 122 123 (void) __ns_ldap_freeResult(&be->result); 124 return (nss_result); 125 } 126 127 /* 128 * getbyname gets struct rpcent values by rpc name. This function 129 * constructs an ldap search filter using the rpc name invocation 130 * parameter and the getrpcbyname search filter defined. Once the 131 * filter is constructed, we search for a matching entry and marshal 132 * the data results into *rpc = (struct rpcent *)argp->buf.result. 133 * The function _nss_ldap_rpc2ent performs the data marshaling. 134 */ 135 136 static nss_status_t 137 getbyname(ldap_backend_ptr be, void *a) 138 { 139 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 140 char searchfilter[SEARCHFILTERLEN]; 141 char userdata[SEARCHFILTERLEN]; 142 char name[SEARCHFILTERLEN]; 143 int ret; 144 145 if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) 146 return ((nss_status_t)NSS_NOTFOUND); 147 148 ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETRPCBYNAME, 149 name); 150 if (ret >= sizeof (searchfilter) || ret < 0) 151 return ((nss_status_t)NSS_NOTFOUND); 152 153 ret = snprintf(userdata, sizeof (userdata), _F_GETRPCBYNAME_SSD, name); 154 if (ret >= sizeof (userdata) || ret < 0) 155 return ((nss_status_t)NSS_NOTFOUND); 156 157 return ((nss_status_t)_nss_ldap_lookup(be, argp, _RPC, searchfilter, 158 NULL, _merge_SSD_filter, userdata)); 159 } 160 161 162 /* 163 * getbynumber gets struct rpcent values by rpc number. This function 164 * constructs an ldap search filter using the rpc number invocation 165 * parameter and the getrpcbynumber search filter defined. Once the 166 * filter is constructed, we search for a matching entry and marshal 167 * the data results into *rpc = (struct rpcent *)argp->buf.result. 168 * The function _nss_ldap_rpc2ent performs the data marshaling. 169 */ 170 171 static nss_status_t 172 getbynumber(ldap_backend_ptr be, void *a) 173 { 174 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 175 char searchfilter[SEARCHFILTERLEN]; 176 char userdata[SEARCHFILTERLEN]; 177 int ret; 178 179 ret = snprintf(searchfilter, sizeof (searchfilter), 180 _F_GETRPCBYNUMBER, argp->key.number); 181 if (ret >= sizeof (searchfilter) || ret < 0) 182 return ((nss_status_t)NSS_NOTFOUND); 183 184 ret = snprintf(userdata, sizeof (userdata), 185 _F_GETRPCBYNUMBER_SSD, argp->key.number); 186 if (ret >= sizeof (userdata) || ret < 0) 187 return ((nss_status_t)NSS_NOTFOUND); 188 189 return ((nss_status_t)_nss_ldap_lookup(be, argp, _RPC, searchfilter, 190 NULL, _merge_SSD_filter, userdata)); 191 } 192 193 194 static ldap_backend_op_t rpc_ops[] = { 195 _nss_ldap_destr, 196 _nss_ldap_endent, 197 _nss_ldap_setent, 198 _nss_ldap_getent, 199 getbyname, 200 getbynumber 201 }; 202 203 204 /* 205 * _nss_ldap_rpc_constr is where life begins. This function calls the generic 206 * ldap constructor function to define and build the abstract data types 207 * required to support ldap operations. 208 */ 209 210 /*ARGSUSED0*/ 211 nss_backend_t * 212 _nss_ldap_rpc_constr(const char *dummy1, const char *dummy2, 213 const char *dummy3) 214 { 215 216 return ((nss_backend_t *)_nss_ldap_constr(rpc_ops, 217 sizeof (rpc_ops)/sizeof (rpc_ops[0]), 218 _RPC, rpc_attrs, _nss_ldap_rpc2str)); 219 } 220