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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "ldap_common.h" 30 31 /* bootparams attributes filters */ 32 #define _B_HOSTNAME "cn" 33 #define _B_PARAMETER "bootparameter" 34 #define _F_GETBOOTPARAMBYNAME "(&(objectClass=bootableDevice)(cn=%s))" 35 #define _F_GETBOOTPARAMBYNAME_SSD "(&(%%s)(cn=%s))" 36 37 static const char *bootparams_attrs[] = { 38 _B_HOSTNAME, 39 _B_PARAMETER, 40 (char *)NULL 41 }; 42 43 /* 44 * _nss_ldap_bootparams2ent is the data marshaling method for the 45 * bootparams getXbyY (e.g., getbyname()) backend processes. This 46 * method is called after a successful ldap search has been performed. 47 * This method will parse the ldap search values into argp->buf.buffer 48 * Three error conditions are expected and returned to nsswitch. 49 * 50 * A host's bootparameters are returned on one line separated by white 51 * space. Slapd stores each boot parameter as a separate entry. If more 52 * than one bootparameter is available, a white space separated buffer 53 * must be constructed and returned. 54 */ 55 56 static int 57 _nss_ldap_bootparams2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) 58 { 59 int i, j, nss_result; 60 int buflen = (int)0; 61 int firstime = (int)1; 62 unsigned long len = 0L; 63 char *cp = (char *)NULL; 64 char *buffer = (char *)NULL; 65 ns_ldap_result_t *result = be->result; 66 ns_ldap_attr_t *attrptr; 67 68 buffer = argp->buf.buffer; 69 buflen = (size_t)argp->buf.buflen; 70 71 nss_result = (int)NSS_STR_PARSE_SUCCESS; 72 (void) memset(buffer, 0, buflen); 73 74 attrptr = getattr(result, 0); 75 if (attrptr == NULL) { 76 nss_result = (int)NSS_STR_PARSE_PARSE; 77 goto result_bp2ent; 78 } 79 80 for (i = 0; i < result->entry->attr_count; i++) { 81 attrptr = getattr(result, i); 82 if (attrptr == NULL) { 83 nss_result = (int)NSS_STR_PARSE_PARSE; 84 goto result_bp2ent; 85 } 86 if (strcasecmp(attrptr->attrname, _B_PARAMETER) == 0) { 87 for (j = 0; j < attrptr->value_count; j++) { 88 if ((attrptr->attrvalue[j] == NULL) || 89 (len = strlen(attrptr->attrvalue[j])) < 1) { 90 *buffer = 0; 91 nss_result = (int)NSS_STR_PARSE_PARSE; 92 goto result_bp2ent; 93 } 94 if (len > buflen) { 95 nss_result = (int)NSS_STR_PARSE_ERANGE; 96 goto result_bp2ent; 97 } 98 if (firstime) { 99 (void) strcpy(buffer, 100 attrptr->attrvalue[j]); 101 firstime = (int)0; 102 } else { 103 if ((cp = strrchr(buffer, '\0')) 104 != NULL) 105 *cp = ' '; 106 (void) strcat(buffer, 107 attrptr->attrvalue[j]); 108 } 109 } 110 } 111 } 112 113 #ifdef DEBUG 114 (void) fprintf(stdout, "\n[bootparams_getbyname.c: " 115 "_nss_ldap_bootparams2ent]\n"); 116 (void) fprintf(stdout, " bootparameter: [%s]\n", buffer); 117 #endif /* DEBUG */ 118 119 result_bp2ent: 120 121 (void) __ns_ldap_freeResult(&be->result); 122 return ((int)nss_result); 123 } 124 125 /* 126 * getbyname gets bootparameters by host name. This function constructs an 127 * ldap search filter using the host name invocation parameter and the 128 * getbootparambyname search filter defined. Once the filter is 129 * constructed, we search for matching entries and marshal the data 130 * results into argp->buf.buffer for the frontend process. The function 131 * _nss_ldap_bootparams2ent performs the data marshaling. 132 * 133 * RFC 2307, An Approach for Using LDAP as a Network Information Service, 134 * indicates that dn's be fully qualified. Host name searches will be on 135 * fully qualified host names (e.g., foo.bar.sun.com). 136 */ 137 138 static nss_status_t 139 getbyname(ldap_backend_ptr be, void *a) 140 { 141 char hostname[3 * MAXHOSTNAMELEN]; 142 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 143 char searchfilter[SEARCHFILTERLEN]; 144 char userdata[SEARCHFILTERLEN]; 145 int ret; 146 147 if (_ldap_filter_name(hostname, argp->key.name, sizeof (hostname)) != 0) 148 return ((nss_status_t)NSS_NOTFOUND); 149 150 ret = snprintf(searchfilter, sizeof (searchfilter), 151 _F_GETBOOTPARAMBYNAME, hostname); 152 if (ret >= sizeof (searchfilter) || ret < 0) 153 return ((nss_status_t)NSS_NOTFOUND); 154 155 ret = snprintf(userdata, sizeof (userdata), 156 _F_GETBOOTPARAMBYNAME_SSD, hostname); 157 if (ret >= sizeof (userdata) || ret < 0) 158 return ((nss_status_t)NSS_NOTFOUND); 159 160 return ((nss_status_t)_nss_ldap_lookup(be, argp, 161 _BOOTPARAMS, searchfilter, NULL, 162 _merge_SSD_filter, userdata)); 163 } 164 165 166 static ldap_backend_op_t bootparams_ops[] = { 167 _nss_ldap_destr, 168 getbyname 169 }; 170 171 172 /* 173 * _nss_ldap_bootparams_constr is where life begins. This function calls 174 * the generic ldap constructor function to define and build the abstract 175 * data types required to support ldap operations. 176 */ 177 178 /*ARGSUSED0*/ 179 nss_backend_t * 180 _nss_ldap_bootparams_constr(const char *dummy1, const char *dummy2, 181 const char *dummy3) 182 { 183 184 return ((nss_backend_t *)_nss_ldap_constr(bootparams_ops, 185 sizeof (bootparams_ops)/sizeof (bootparams_ops[0]), 186 _BOOTPARAMS, bootparams_attrs, _nss_ldap_bootparams2ent)); 187 } 188