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 "ldap_common.h" 27 28 /* bootparams attributes filters */ 29 #define _B_HOSTNAME "cn" 30 #define _B_PARAMETER "bootparameter" 31 #define _F_GETBOOTPARAMBYNAME "(&(objectClass=bootableDevice)(cn=%s))" 32 #define _F_GETBOOTPARAMBYNAME_SSD "(&(%%s)(cn=%s))" 33 34 static const char *bootparams_attrs[] = { 35 _B_HOSTNAME, 36 _B_PARAMETER, 37 (char *)NULL 38 }; 39 40 /* 41 * _nss_ldap_bootparams2str is the data marshaling method for the 42 * bootparams bootparams_getbyname backend processes. 43 * This method is called after a successful ldap search has been performed. 44 * This method will parse the ldap search values into the file format. 45 * 46 * A host's bootparameters are returned on one line separated by white 47 * space. The LDAP server stores each boot parameter as a separate entry. 48 * If more than one bootparameter is available, a white space separated buffer 49 * must be constructed and returned. 50 * 51 */ 52 53 static int 54 _nss_ldap_bootparams2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 55 { 56 uint_t i; 57 int buflen = 0, len = 0; 58 int nss_result, firsttime; 59 ns_ldap_attr_t *bparams; 60 char *buffer, **names; 61 ns_ldap_result_t *result = be->result; 62 63 if (result == NULL) 64 return (NSS_STR_PARSE_PARSE); 65 buflen = argp->buf.buflen; 66 if (argp->buf.result != NULL) { 67 if ((be->buffer = calloc(1, buflen)) == NULL) { 68 nss_result = NSS_STR_PARSE_PARSE; 69 goto result_bp2str; 70 } 71 buffer = be->buffer; 72 } else 73 buffer = argp->buf.buffer; 74 75 nss_result = NSS_STR_PARSE_SUCCESS; 76 (void) memset(argp->buf.buffer, 0, buflen); 77 78 names = __ns_ldap_getAttr(result->entry, _B_HOSTNAME); 79 if (names == NULL || names[0] == NULL || 80 (strlen(names[0]) < 1)) { 81 nss_result = NSS_STR_PARSE_PARSE; 82 goto result_bp2str; 83 } 84 bparams = __ns_ldap_getAttrStruct(result->entry, _B_PARAMETER); 85 if (bparams == NULL || bparams->attrvalue == NULL) { 86 nss_result = NSS_STR_PARSE_PARSE; 87 goto result_bp2str; 88 } 89 firsttime = 1; 90 for (i = 0; i < bparams->value_count; i++) { 91 if (bparams->attrvalue[i] == NULL) { 92 nss_result = NSS_STR_PARSE_PARSE; 93 goto result_bp2str; 94 } 95 /* 96 * Skip client host name. The early version of ldapaddent 97 * adds hostname as a boot param and it should be filtered. 98 */ 99 if (strcasecmp(names[0], bparams->attrvalue[i]) != 0) { 100 if (firsttime) { 101 firsttime = 0; 102 len = snprintf(buffer, buflen, "%s", 103 bparams->attrvalue[i]); 104 } else 105 len = snprintf(buffer, buflen, " %s", 106 bparams->attrvalue[i]); 107 TEST_AND_ADJUST(len, buffer, buflen, result_bp2str); 108 } 109 } 110 /* The front end marshaller doesn't need to copy trailing nulls */ 111 if (argp->buf.result != NULL) 112 be->buflen = strlen(be->buffer); 113 114 result_bp2str: 115 116 (void) __ns_ldap_freeResult(&be->result); 117 return (nss_result); 118 } 119 120 /* 121 * getbyname gets bootparameters by host name. This function constructs an 122 * ldap search filter using the host name invocation parameter and the 123 * getbootparambyname search filter defined. Once the filter is 124 * constructed, we search for matching entries and marshal the data 125 * results into argp->buf.buffer for the frontend process. The function 126 * _nss_ldap_bootparams2ent performs the data marshaling. 127 * 128 * RFC 2307, An Approach for Using LDAP as a Network Information Service, 129 * indicates that dn's be fully qualified. Host name searches will be on 130 * fully qualified host names (e.g., foo.bar.sun.com). 131 */ 132 133 static nss_status_t 134 getbyname(ldap_backend_ptr be, void *a) 135 { 136 char hostname[3 * MAXHOSTNAMELEN]; 137 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 138 char searchfilter[SEARCHFILTERLEN]; 139 char userdata[SEARCHFILTERLEN]; 140 int ret; 141 142 if (_ldap_filter_name(hostname, argp->key.name, sizeof (hostname)) != 0) 143 return ((nss_status_t)NSS_NOTFOUND); 144 145 ret = snprintf(searchfilter, sizeof (searchfilter), 146 _F_GETBOOTPARAMBYNAME, hostname); 147 if (ret >= sizeof (searchfilter) || ret < 0) 148 return ((nss_status_t)NSS_NOTFOUND); 149 150 ret = snprintf(userdata, sizeof (userdata), 151 _F_GETBOOTPARAMBYNAME_SSD, hostname); 152 if (ret >= sizeof (userdata) || ret < 0) 153 return ((nss_status_t)NSS_NOTFOUND); 154 return ((nss_status_t)_nss_ldap_lookup(be, argp, 155 _BOOTPARAMS, searchfilter, NULL, 156 _merge_SSD_filter, userdata)); 157 } 158 159 160 static ldap_backend_op_t bootparams_ops[] = { 161 _nss_ldap_destr, 162 getbyname 163 }; 164 165 166 /* 167 * _nss_ldap_bootparams_constr is where life begins. This function calls 168 * the generic ldap constructor function to define and build the abstract 169 * data types required to support ldap operations. 170 */ 171 172 /*ARGSUSED0*/ 173 nss_backend_t * 174 _nss_ldap_bootparams_constr(const char *dummy1, const char *dummy2, 175 const char *dummy3) 176 { 177 178 return ((nss_backend_t *)_nss_ldap_constr(bootparams_ops, 179 sizeof (bootparams_ops)/sizeof (bootparams_ops[0]), 180 _BOOTPARAMS, bootparams_attrs, _nss_ldap_bootparams2str)); 181 } 182