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