1 /* service.c - service lookup routines */ 2 /* $OpenLDAP: pkg/ldap/contrib/slapd-modules/nssov/service.c,v 1.1.2.1 2008/07/08 18:53:57 quanah Exp $ */ 3 /* 4 * Copyright 2008 by Howard Chu, Symas Corp. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 /* 16 * This code references portions of the nss-ldapd package 17 * written by Arthur de Jong. The nss-ldapd code was forked 18 * from the nss-ldap library written by Luke Howard. 19 */ 20 21 #include "nssov.h" 22 23 /* ( nisSchema.2.3 NAME 'ipService' SUP top STRUCTURAL 24 * DESC 'Abstraction an Internet Protocol service. 25 * Maps an IP port and protocol (such as tcp or udp) 26 * to one or more names; the distinguished value of 27 * the cn attribute denotes the service's canonical 28 * name' 29 * MUST ( cn $ ipServicePort $ ipServiceProtocol ) 30 * MAY ( description ) ) 31 */ 32 33 /* the basic search filter for searches */ 34 static struct berval service_filter = BER_BVC("(objectClass=ipService)"); 35 36 /* the attributes to request with searches */ 37 static struct berval service_keys[] = { 38 BER_BVC("cn"), 39 BER_BVC("ipServicePort"), 40 BER_BVC("ipServiceProtocol"), 41 BER_BVNULL 42 }; 43 44 static int mkfilter_service_byname(nssov_mapinfo *mi,struct berval *name, 45 struct berval *protocol,struct berval *buf) 46 { 47 char buf2[1024],buf3[1024]; 48 struct berval bv2 = {sizeof(buf2),buf2}; 49 struct berval bv3 = {sizeof(buf3),buf3}; 50 51 /* escape attributes */ 52 if (nssov_escape(name,&bv2)) 53 return -1; 54 if (!BER_BVISNULL(protocol)) { 55 if (nssov_escape(protocol,&bv3)) 56 return -1; 57 if (bv2.bv_len + mi->mi_filter.bv_len + mi->mi_attrs[0].an_desc->ad_cname.bv_len + 58 bv3.bv_len + mi->mi_attrs[2].an_desc->ad_cname.bv_len + 9 > buf->bv_len ) 59 return -1; 60 buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s)(%s=%s))", 61 mi->mi_filter.bv_val, 62 mi->mi_attrs[0].an_desc->ad_cname.bv_val, bv2.bv_val, 63 mi->mi_attrs[2].an_desc->ad_cname.bv_val, bv3.bv_val ); 64 } else { 65 if (bv2.bv_len + mi->mi_filter.bv_len + mi->mi_attrs[0].an_desc->ad_cname.bv_len + 6 > 66 buf->bv_len ) 67 return -1; 68 buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s))", 69 mi->mi_filter.bv_val, mi->mi_attrs[0].an_desc->ad_cname.bv_val, 70 bv2.bv_val ); 71 } 72 return 0; 73 } 74 75 static int mkfilter_service_bynumber(nssov_mapinfo *mi,struct berval *numb, 76 struct berval *protocol,struct berval *buf) 77 { 78 char buf2[1024]; 79 struct berval bv2 = {sizeof(buf2),buf2}; 80 81 /* escape attribute */ 82 if (!BER_BVISNULL(protocol)) { 83 if (nssov_escape(protocol,&bv2)) 84 return -1; 85 if (numb->bv_len + mi->mi_filter.bv_len + mi->mi_attrs[1].an_desc->ad_cname.bv_len + 86 bv2.bv_len + mi->mi_attrs[2].an_desc->ad_cname.bv_len + 9 > buf->bv_len ) 87 return -1; 88 buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s)(%s=%s))", 89 mi->mi_filter.bv_val, 90 mi->mi_attrs[1].an_desc->ad_cname.bv_val, numb->bv_val, 91 mi->mi_attrs[2].an_desc->ad_cname.bv_val, bv2.bv_val ); 92 } else { 93 if (numb->bv_len + mi->mi_filter.bv_len + mi->mi_attrs[1].an_desc->ad_cname.bv_len + 6 > 94 buf->bv_len ) 95 return -1; 96 buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s))", 97 mi->mi_filter.bv_val, mi->mi_attrs[1].an_desc->ad_cname.bv_val, 98 numb->bv_val ); 99 } 100 return 0; 101 } 102 103 NSSOV_INIT(service) 104 105 NSSOV_CBPRIV(service, 106 char nbuf[256]; 107 char pbuf[256]; 108 struct berval name; 109 struct berval prot;); 110 111 static int write_service(nssov_service_cbp *cbp,Entry *entry) 112 { 113 int32_t tmpint32,tmp2int32,tmp3int32; 114 struct berval name,*names,*ports,*protos; 115 struct berval tmparr[2]; 116 Attribute *a; 117 char *tmp; 118 int port; 119 int i,numname,dupname,numprot; 120 121 /* get the most canonical name */ 122 nssov_find_rdnval( &entry->e_nname, cbp->mi->mi_attrs[0].an_desc, &name ); 123 /* get the other names for the rpc */ 124 a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[0].an_desc ); 125 if ( !a || !a->a_vals ) 126 { 127 Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value", 128 entry->e_name.bv_val, cbp->mi->mi_attrs[0].an_desc->ad_cname.bv_val, 0 ); 129 return 0; 130 } 131 names = a->a_vals; 132 numname = a->a_numvals; 133 /* if the name is not yet found, get the first entry from names */ 134 if (BER_BVISNULL(&name)) { 135 name=names[0]; 136 dupname = 0; 137 } else { 138 dupname = -1; 139 for (i=0; i<numname; i++) { 140 if ( ber_bvmatch(&name, &a->a_nvals[i])) { 141 dupname = i; 142 break; 143 } 144 } 145 } 146 /* get the service number */ 147 a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[1].an_desc ); 148 if ( !a || !a->a_vals ) 149 { 150 Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value", 151 entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 ); 152 return 0; 153 } else if ( a->a_numvals > 1 ) { 154 Debug(LDAP_DEBUG_ANY,"service entry %s contains multiple %s values", 155 entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 ); 156 } 157 port=(int)strtol(a->a_vals[0].bv_val,&tmp,0); 158 if (*tmp) 159 { 160 Debug(LDAP_DEBUG_ANY,"service entry %s contains non-numeric %s value", 161 entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 ); 162 return 0; 163 } 164 /* get protocols */ 165 if (BER_BVISNULL(&cbp->prot)) 166 { 167 a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[2].an_desc ); 168 if ( !a || !a->a_vals ) 169 { 170 Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value", 171 entry->e_name.bv_val, cbp->mi->mi_attrs[2].an_desc->ad_cname.bv_val, 0 ); 172 return 0; 173 } 174 protos = a->a_vals; 175 numprot = a->a_numvals; 176 } 177 else 178 { 179 protos=tmparr; 180 protos[0]=cbp->prot; 181 BER_BVZERO(&protos[1]); 182 numprot = 1; 183 } 184 /* write the entries */ 185 for (i=0;i<numprot;i++) 186 { 187 int j; 188 WRITE_INT32(cbp->fp,NSLCD_RESULT_SUCCESS); 189 WRITE_BERVAL(cbp->fp,&name); 190 if ( dupname >= 0 ) { 191 WRITE_INT32(cbp->fp,numname-1); 192 } else { 193 WRITE_INT32(cbp->fp,numname); 194 } 195 for (j=0;j<numname;j++) { 196 if (j == dupname) continue; 197 WRITE_BERVAL(cbp->fp,&names[j]); 198 } 199 WRITE_INT32(cbp->fp,port); 200 WRITE_BERVAL(cbp->fp,&protos[i]); 201 } 202 return 0; 203 } 204 205 NSSOV_CB(service) 206 207 NSSOV_HANDLE( 208 service,byname, 209 char fbuf[1024]; 210 struct berval filter = {sizeof(fbuf)}; 211 filter.bv_val = fbuf; 212 READ_STRING_BUF2(fp,cbp.nbuf,sizeof(cbp.nbuf)); 213 cbp.name.bv_len = tmpint32; 214 cbp.name.bv_val = cbp.nbuf; 215 READ_STRING_BUF2(fp,cbp.pbuf,sizeof(cbp.pbuf)); 216 cbp.prot.bv_len = tmpint32; 217 cbp.prot.bv_val = tmpint32 ? cbp.pbuf : NULL;, 218 Debug(LDAP_DEBUG_TRACE,"nssov_service_byname(%s,%s)",cbp.name.bv_val,cbp.prot.bv_val,0);, 219 NSLCD_ACTION_SERVICE_BYNAME, 220 mkfilter_service_byname(cbp.mi,&cbp.name,&cbp.prot,&filter) 221 ) 222 223 NSSOV_HANDLE( 224 service,bynumber, 225 int number; 226 char fbuf[1024]; 227 struct berval filter = {sizeof(fbuf)}; 228 filter.bv_val = fbuf; 229 READ_INT32(fp,number); 230 cbp.name.bv_val = cbp.nbuf; 231 cbp.name.bv_len = snprintf(cbp.nbuf,sizeof(cbp.nbuf),"%d",number); 232 READ_STRING_BUF2(fp,cbp.pbuf,sizeof(cbp.pbuf)); 233 cbp.prot.bv_len = tmpint32; 234 cbp.prot.bv_val = tmpint32 ? cbp.pbuf : NULL;, 235 Debug(LDAP_DEBUG_TRACE,"nssov_service_bynumber(%s,%s)",cbp.name.bv_val,cbp.prot.bv_val,0);, 236 NSLCD_ACTION_SERVICE_BYNUMBER, 237 mkfilter_service_bynumber(cbp.mi,&cbp.name,&cbp.prot,&filter) 238 ) 239 240 NSSOV_HANDLE( 241 service,all, 242 struct berval filter; 243 /* no parameters to read */ 244 BER_BVZERO(&cbp.prot);, 245 Debug(LDAP_DEBUG_TRACE,"nssov_service_all()",0,0,0);, 246 NSLCD_ACTION_SERVICE_ALL, 247 (filter=cbp.mi->mi_filter,0) 248 ) 249