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