Back to index

openldap  2.4.31
service.c
Go to the documentation of this file.
00001 /* service.c - service lookup routines */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 
00004  *
00005  * Copyright 2008-2012 The OpenLDAP Foundation.
00006  * Portions Copyright 2008 by Howard Chu, Symas Corp.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in the file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This code references portions of the nss-ldapd package
00019  * written by Arthur de Jong. The nss-ldapd code was forked
00020  * from the nss-ldap library written by Luke Howard.
00021  */
00022 
00023 #include "nssov.h"
00024 
00025 /* ( nisSchema.2.3 NAME 'ipService' SUP top STRUCTURAL
00026  *      DESC 'Abstraction an Internet Protocol service.
00027  *                           Maps an IP port and protocol (such as tcp or udp)
00028  *                           to one or more names; the distinguished value of
00029  *                           the cn attribute denotes the service's canonical
00030  *                           name'
00031  *      MUST ( cn $ ipServicePort $ ipServiceProtocol )
00032  *      MAY ( description ) )
00033  */
00034 
00035 /* the basic search filter for searches */
00036 static struct berval service_filter = BER_BVC("(objectClass=ipService)");
00037 
00038 /* the attributes to request with searches */
00039 static struct berval service_keys[] = {
00040        BER_BVC("cn"),
00041        BER_BVC("ipServicePort"),
00042        BER_BVC("ipServiceProtocol"),
00043        BER_BVNULL
00044 };
00045 
00046 static int mkfilter_service_byname(nssov_mapinfo *mi,struct berval *name,
00047                                                          struct berval *protocol,struct berval *buf)
00048 {
00049        char buf2[1024],buf3[1024];
00050        struct berval bv2 = {sizeof(buf2),buf2};
00051        struct berval bv3 = {sizeof(buf3),buf3};
00052 
00053        /* escape attributes */
00054        if (nssov_escape(name,&bv2))
00055               return -1;
00056        if (!BER_BVISNULL(protocol)) {
00057               if (nssov_escape(protocol,&bv3))
00058                      return -1;
00059               if (bv2.bv_len + mi->mi_filter.bv_len + mi->mi_attrs[0].an_desc->ad_cname.bv_len +
00060                      bv3.bv_len + mi->mi_attrs[2].an_desc->ad_cname.bv_len + 9 > buf->bv_len )
00061                      return -1;
00062               buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s)(%s=%s))",
00063                      mi->mi_filter.bv_val,
00064                      mi->mi_attrs[0].an_desc->ad_cname.bv_val, bv2.bv_val,
00065                      mi->mi_attrs[2].an_desc->ad_cname.bv_val, bv3.bv_val );
00066        } else {
00067               if (bv2.bv_len + mi->mi_filter.bv_len + mi->mi_attrs[0].an_desc->ad_cname.bv_len + 6 >
00068                      buf->bv_len )
00069                      return -1;
00070               buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s))",
00071                      mi->mi_filter.bv_val, mi->mi_attrs[0].an_desc->ad_cname.bv_val,
00072                      bv2.bv_val );
00073        }
00074        return 0;
00075 }
00076 
00077 static int mkfilter_service_bynumber(nssov_mapinfo *mi,struct berval *numb,
00078                                                          struct berval *protocol,struct berval *buf)
00079 {
00080        char buf2[1024];
00081        struct berval bv2 = {sizeof(buf2),buf2};
00082 
00083        /* escape attribute */
00084        if (!BER_BVISNULL(protocol)) {
00085               if (nssov_escape(protocol,&bv2))
00086                      return -1;
00087               if (numb->bv_len + mi->mi_filter.bv_len + mi->mi_attrs[1].an_desc->ad_cname.bv_len +
00088                      bv2.bv_len + mi->mi_attrs[2].an_desc->ad_cname.bv_len + 9 > buf->bv_len )
00089                      return -1;
00090               buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s)(%s=%s))",
00091                      mi->mi_filter.bv_val,
00092                      mi->mi_attrs[1].an_desc->ad_cname.bv_val, numb->bv_val,
00093                      mi->mi_attrs[2].an_desc->ad_cname.bv_val, bv2.bv_val );
00094        } else {
00095               if (numb->bv_len + mi->mi_filter.bv_len + mi->mi_attrs[1].an_desc->ad_cname.bv_len + 6 >
00096                      buf->bv_len )
00097                      return -1;
00098               buf->bv_len = snprintf(buf->bv_val, buf->bv_len, "(&%s(%s=%s))",
00099                      mi->mi_filter.bv_val, mi->mi_attrs[1].an_desc->ad_cname.bv_val,
00100                      numb->bv_val );
00101        }
00102        return 0;
00103 }
00104 
00105 NSSOV_INIT(service)
00106 
00107 NSSOV_CBPRIV(service,
00108        char nbuf[256];
00109        char pbuf[256];
00110        struct berval name;
00111        struct berval prot;);
00112 
00113 static int write_service(nssov_service_cbp *cbp,Entry *entry)
00114 {
00115        int32_t tmpint32,tmp2int32,tmp3int32;
00116        struct berval name,*names,*ports,*protos;
00117        struct berval tmparr[2];
00118        Attribute *a;
00119        char *tmp;
00120        int port;
00121        int i,numname,dupname,numprot;
00122 
00123        /* get the most canonical name */
00124        nssov_find_rdnval( &entry->e_nname, cbp->mi->mi_attrs[0].an_desc, &name );
00125        /* get the other names for the rpc */
00126        a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[0].an_desc );
00127        if ( !a || !a->a_vals )
00128        {
00129               Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value\n",
00130                      entry->e_name.bv_val, cbp->mi->mi_attrs[0].an_desc->ad_cname.bv_val, 0 );
00131               return 0;
00132        }
00133        names = a->a_vals;
00134        numname = a->a_numvals;
00135        /* if the name is not yet found, get the first entry from names */
00136        if (BER_BVISNULL(&name)) {
00137               name=names[0];
00138               dupname = 0;
00139        } else {
00140               dupname = -1;
00141               for (i=0; i<numname; i++) {
00142                      if ( bvmatch(&name, &a->a_nvals[i])) {
00143                             dupname = i;
00144                             break;
00145                      }
00146               }
00147        }
00148        /* get the service number */
00149        a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[1].an_desc );
00150        if ( !a || !a->a_vals )
00151        {
00152               Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value\n",
00153                      entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 );
00154               return 0;
00155        } else if ( a->a_numvals > 1 ) {
00156               Debug(LDAP_DEBUG_ANY,"service entry %s contains multiple %s values\n",
00157                      entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 );
00158        }
00159        port=(int)strtol(a->a_vals[0].bv_val,&tmp,0);
00160        if (*tmp)
00161        {
00162               Debug(LDAP_DEBUG_ANY,"service entry %s contains non-numeric %s value\n",
00163                      entry->e_name.bv_val, cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val, 0 );
00164               return 0;
00165        }
00166        /* get protocols */
00167        if (BER_BVISNULL(&cbp->prot))
00168        {
00169               a = attr_find( entry->e_attrs, cbp->mi->mi_attrs[2].an_desc );
00170               if ( !a || !a->a_vals )
00171               {
00172                      Debug(LDAP_DEBUG_ANY,"service entry %s does not contain %s value\n",
00173                             entry->e_name.bv_val, cbp->mi->mi_attrs[2].an_desc->ad_cname.bv_val, 0 );
00174                      return 0;
00175               }
00176               protos = a->a_vals;
00177               numprot = a->a_numvals;
00178        }
00179        else
00180        {
00181               protos=tmparr;
00182               protos[0]=cbp->prot;
00183               BER_BVZERO(&protos[1]);
00184               numprot = 1;
00185        }
00186        /* write the entries */
00187        for (i=0;i<numprot;i++)
00188        {
00189               int j;
00190               WRITE_INT32(cbp->fp,NSLCD_RESULT_BEGIN);
00191               WRITE_BERVAL(cbp->fp,&name);
00192               if ( dupname >= 0 ) {
00193                      WRITE_INT32(cbp->fp,numname-1);
00194               } else {
00195                      WRITE_INT32(cbp->fp,numname);
00196               }
00197               for (j=0;j<numname;j++) {
00198                      if (j == dupname) continue;
00199                      WRITE_BERVAL(cbp->fp,&names[j]);
00200               }
00201               WRITE_INT32(cbp->fp,port);
00202               WRITE_BERVAL(cbp->fp,&protos[i]);
00203        }
00204        return 0;
00205 }
00206 
00207 NSSOV_CB(service)
00208 
00209 NSSOV_HANDLE(
00210        service,byname,
00211        char fbuf[1024];
00212        struct berval filter = {sizeof(fbuf)};
00213        filter.bv_val = fbuf;
00214        READ_STRING(fp,cbp.nbuf);
00215        cbp.name.bv_len = tmpint32;
00216        cbp.name.bv_val = cbp.nbuf;
00217        READ_STRING(fp,cbp.pbuf);
00218        cbp.prot.bv_len = tmpint32;
00219        cbp.prot.bv_val = tmpint32 ? cbp.pbuf : NULL;,
00220        Debug(LDAP_DEBUG_TRACE,"nssov_service_byname(%s,%s)\n",cbp.name.bv_val,cbp.prot.bv_val,0);,
00221        NSLCD_ACTION_SERVICE_BYNAME,
00222        mkfilter_service_byname(cbp.mi,&cbp.name,&cbp.prot,&filter)
00223 )
00224 
00225 NSSOV_HANDLE(
00226        service,bynumber,
00227        int number;
00228        char fbuf[1024];
00229        struct berval filter = {sizeof(fbuf)};
00230        filter.bv_val = fbuf;
00231        READ_INT32(fp,number);
00232        cbp.name.bv_val = cbp.nbuf;
00233        cbp.name.bv_len = snprintf(cbp.nbuf,sizeof(cbp.nbuf),"%d",number);
00234        READ_STRING(fp,cbp.pbuf);
00235        cbp.prot.bv_len = tmpint32;
00236        cbp.prot.bv_val = tmpint32 ? cbp.pbuf : NULL;,
00237        Debug(LDAP_DEBUG_TRACE,"nssov_service_bynumber(%s,%s)\n",cbp.name.bv_val,cbp.prot.bv_val,0);,
00238        NSLCD_ACTION_SERVICE_BYNUMBER,
00239        mkfilter_service_bynumber(cbp.mi,&cbp.name,&cbp.prot,&filter)
00240 )
00241 
00242 NSSOV_HANDLE(
00243        service,all,
00244        struct berval filter;
00245        /* no parameters to read */
00246        BER_BVZERO(&cbp.prot);,
00247        Debug(LDAP_DEBUG_TRACE,"nssov_service_all()\n",0,0,0);,
00248        NSLCD_ACTION_SERVICE_ALL,
00249        (filter=cbp.mi->mi_filter,0)
00250 )