LCOV - code coverage report
Current view: top level - Modules - message.c (source / functions) Hit Total Coverage
Test: python-ldap LCOV report Lines: 70 166 42.2 %
Date: 2017-12-08 13:03:20 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /* See https://www.python-ldap.org/ for details. */
       2             : 
       3             : #include "common.h"
       4             : #include "message.h"
       5             : #include "berval.h"
       6             : #include "ldapcontrol.h"
       7             : #include "constants.h"
       8             : 
       9             : /*
      10             :  * Converts an LDAP message into a Python structure.
      11             :  *
      12             :  * On success, returns a list of dictionaries.
      13             :  * On failure, returns NULL, and sets an error.
      14             :  *
      15             :  * The message m is always freed, regardless of return value.
      16             :  *
      17             :  * If add_ctrls is non-zero, per-entry/referral/partial/intermediate
      18             :  * controls will be added as a third item to each entry tuple
      19             :  *
      20             :  * If add_intermediates is non-zero, intermediate/partial results will
      21             :  * be returned
      22             :  */
      23             : PyObject *
      24         158 : LDAPmessage_to_python(LDAP *ld, LDAPMessage *m, int add_ctrls, int add_intermediates)
      25             : {
      26             :     /* we convert an LDAP message into a python structure.
      27             :      * It is always a list of dictionaries.
      28             :      * We always free m.
      29             :      */
      30             : 
      31         158 :      PyObject *result, *pyctrls = 0;
      32             :      LDAPMessage* entry;
      33         158 :      LDAPControl **serverctrls = 0;
      34             :      int rc;
      35             : 
      36         158 :      result = PyList_New(0);
      37         158 :      if (result == NULL) {
      38           0 :         ldap_msgfree( m );
      39         158 :         return NULL;
      40             :      }
      41             : 
      42         394 :      for(entry = ldap_first_entry(ld,m);
      43             :          entry != NULL;
      44         156 :          entry = ldap_next_entry(ld,entry))
      45             :      {
      46             :          char *dn;
      47             :          char *attr;
      48          78 :          BerElement *ber = NULL;
      49             :          PyObject* entrytuple; 
      50             :          PyObject* attrdict; 
      51             :          PyObject* pydn;
      52             : 
      53          78 :          dn = ldap_get_dn( ld, entry );
      54          78 :          if (dn == NULL)  {
      55           0 :              Py_DECREF(result);
      56           0 :              ldap_msgfree( m );
      57           0 :              return LDAPerror( ld, "ldap_get_dn" );
      58             :          }
      59             : 
      60          78 :          attrdict = PyDict_New();
      61          78 :          if (attrdict == NULL) {
      62           0 :                 Py_DECREF(result);
      63           0 :                 ldap_msgfree( m );
      64           0 :                 ldap_memfree(dn);
      65           0 :                 return NULL;
      66             :          }
      67             : 
      68          78 :          rc = ldap_get_entry_controls( ld, entry, &serverctrls );
      69          78 :          if (rc) {
      70           0 :             Py_DECREF(result);
      71           0 :             ldap_msgfree( m );
      72           0 :             ldap_memfree(dn);
      73           0 :             return LDAPerror( ld, "ldap_get_entry_controls" );
      74             :          }
      75             : 
      76             :          /* convert serverctrls to list of tuples */
      77          78 :          if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
      78           0 :             int err = LDAP_NO_MEMORY;
      79           0 :             ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
      80           0 :             Py_DECREF(result);
      81           0 :             ldap_msgfree( m );
      82           0 :             ldap_memfree(dn);
      83           0 :             ldap_controls_free(serverctrls);
      84           0 :             return LDAPerror( ld, "LDAPControls_to_List" );
      85             :          }
      86          78 :          ldap_controls_free(serverctrls);
      87             : 
      88             :          /* Fill attrdict with lists */
      89         309 :          for( attr = ldap_first_attribute( ld, entry, &ber );
      90             :               attr != NULL;
      91         153 :               attr = ldap_next_attribute( ld, entry, ber )
      92             :          ) {
      93             :              PyObject* valuelist;
      94             :              PyObject* pyattr;
      95             :              struct berval **bvals;
      96             : 
      97         153 :              pyattr = PyUnicode_FromString(attr);
      98             : 
      99         153 :              bvals = ldap_get_values_len( ld, entry, attr );
     100             : 
     101             :              /* Find which list to append to */
     102         153 :              if ( PyDict_Contains( attrdict, pyattr ) ) {
     103           0 :                  valuelist = PyDict_GetItem( attrdict, pyattr );
     104             :              } else {
     105         153 :                  valuelist = PyList_New(0);
     106         153 :                  if (valuelist != NULL && PyDict_SetItem(attrdict,
     107             :                      pyattr, valuelist) == -1) {
     108           0 :                         Py_DECREF(valuelist);
     109           0 :                         valuelist = NULL;       /* catch error later */
     110             :                  }
     111             :              }
     112             : 
     113         153 :              if (valuelist == NULL) {
     114           0 :                 Py_DECREF(pyattr);
     115           0 :                 Py_DECREF(attrdict);
     116           0 :                 Py_DECREF(result);
     117           0 :                 if (ber != NULL)
     118           0 :                     ber_free(ber, 0);
     119           0 :                 ldap_msgfree( m );
     120           0 :                 ldap_memfree(attr);
     121           0 :                 ldap_memfree(dn);
     122           0 :                 Py_XDECREF(pyctrls);
     123           0 :                 return NULL;
     124             :              }
     125             : 
     126         153 :              if (bvals != NULL) {
     127             :                 Py_ssize_t i;
     128        1023 :                 for (i=0; bvals[i]; i++) {
     129             :                     PyObject *valuestr;
     130             : 
     131         870 :                     valuestr = LDAPberval_to_object(bvals[i]);
     132         870 :                     if (PyList_Append( valuelist, valuestr ) == -1) {
     133           0 :                         Py_DECREF(pyattr);
     134           0 :                         Py_DECREF(attrdict);
     135           0 :                         Py_DECREF(result);
     136           0 :                         Py_DECREF(valuestr);
     137           0 :                         Py_DECREF(valuelist);
     138           0 :                         if (ber != NULL)
     139           0 :                             ber_free(ber, 0);
     140           0 :                         ldap_msgfree( m );
     141           0 :                         ldap_memfree(attr);
     142           0 :                         ldap_memfree(dn);
     143           0 :                         Py_XDECREF(pyctrls);
     144           0 :                         return NULL;
     145             :                     }
     146         870 :                     Py_DECREF(valuestr);
     147             :                 }
     148         153 :                 ldap_value_free_len(bvals);
     149             :              }
     150         153 :              Py_DECREF(pyattr);
     151         153 :              Py_DECREF( valuelist );
     152         153 :              ldap_memfree(attr);
     153             :          }
     154             : 
     155          78 :          pydn = PyUnicode_FromString(dn);
     156          78 :          if (pydn == NULL) {
     157           0 :              Py_DECREF(result);
     158           0 :              ldap_msgfree( m );
     159           0 :              ldap_memfree(dn);
     160           0 :              return NULL;
     161             :          }
     162             : 
     163          78 :          if (add_ctrls) {
     164          28 :             entrytuple = Py_BuildValue("(OOO)", pydn, attrdict, pyctrls);
     165             :          } else {
     166          50 :             entrytuple = Py_BuildValue("(OO)", pydn, attrdict);
     167             :          }
     168          78 :          Py_DECREF(pydn);
     169          78 :          ldap_memfree(dn);
     170          78 :          Py_DECREF(attrdict);
     171          78 :          Py_XDECREF(pyctrls);
     172          78 :          PyList_Append(result, entrytuple);
     173          78 :          Py_DECREF(entrytuple);
     174          78 :          if (ber != NULL)
     175          70 :                  ber_free(ber, 0);
     176             :      }
     177         316 :      for(entry = ldap_first_reference(ld,m);
     178             :          entry != NULL;
     179           0 :          entry = ldap_next_reference(ld,entry))
     180             :      {
     181           0 :          char **refs = NULL;
     182             :          PyObject* entrytuple;
     183           0 :          PyObject* reflist = PyList_New(0);
     184             : 
     185           0 :          if (reflist == NULL)  {
     186           0 :              Py_DECREF(result);
     187           0 :              ldap_msgfree( m );
     188           0 :              return NULL;
     189             :          }
     190           0 :          if (ldap_parse_reference(ld, entry, &refs, &serverctrls, 0) != LDAP_SUCCESS) {
     191           0 :              Py_DECREF(reflist);
     192           0 :              Py_DECREF(result);
     193           0 :              ldap_msgfree( m );
     194           0 :              return LDAPerror( ld, "ldap_parse_reference" );
     195             :          }
     196             :          /* convert serverctrls to list of tuples */
     197           0 :          if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
     198           0 :              int err = LDAP_NO_MEMORY;
     199           0 :              ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
     200           0 :              Py_DECREF(reflist);
     201           0 :              Py_DECREF(result);
     202           0 :              ldap_msgfree( m );
     203           0 :              ldap_controls_free(serverctrls);
     204           0 :              return LDAPerror( ld, "LDAPControls_to_List" );
     205             :          }
     206           0 :          ldap_controls_free(serverctrls);
     207           0 :          if (refs) {
     208             :              Py_ssize_t i;
     209           0 :              for (i=0; refs[i] != NULL; i++) {
     210             :                  /* A referal is a distinguishedName => unicode */
     211           0 :                  PyObject *refstr = PyUnicode_FromString(refs[i]);
     212           0 :                  PyList_Append(reflist, refstr);
     213           0 :                  Py_DECREF(refstr);
     214             :              }
     215           0 :              ber_memvfree( (void **) refs );
     216             :          }
     217           0 :          if (add_ctrls) {
     218           0 :             entrytuple = Py_BuildValue("(sOO)", NULL, reflist, pyctrls);
     219             :          } else {
     220           0 :             entrytuple = Py_BuildValue("(sO)", NULL, reflist);
     221             :          }
     222           0 :          Py_DECREF(reflist);
     223           0 :          Py_XDECREF(pyctrls);
     224           0 :          PyList_Append(result, entrytuple);
     225           0 :          Py_DECREF(entrytuple);
     226             :      }
     227         158 :      if (add_intermediates) {
     228          96 :         for(entry = ldap_first_message(ld,m);
     229             :             entry != NULL;
     230          32 :             entry = ldap_next_message(ld,entry))
     231             :            {
     232             :               /* list of tuples */
     233             :               /* each tuple is OID, Berval, controllist */
     234          32 :               if ( LDAP_RES_INTERMEDIATE == ldap_msgtype( entry ) ) {
     235             :                  PyObject* valtuple;
     236             :                  PyObject *valuestr;
     237           3 :                  char *retoid = 0;
     238             :                  PyObject *pyoid;
     239           3 :                  struct berval *retdata = 0;
     240             : 
     241           3 :                  if (ldap_parse_intermediate( ld, entry, &retoid, &retdata, &serverctrls, 0 ) != LDAP_SUCCESS) {
     242           0 :                     Py_DECREF(result);
     243           0 :                     ldap_msgfree( m );
     244           0 :                     return LDAPerror( ld, "ldap_parse_intermediate" );
     245             :                  }
     246             :                  /* convert serverctrls to list of tuples */
     247           3 :                  if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
     248           0 :                     int err = LDAP_NO_MEMORY;
     249           0 :                     ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
     250           0 :                     Py_DECREF(result);
     251           0 :                     ldap_msgfree( m );
     252           0 :                     ldap_controls_free(serverctrls);
     253           0 :                     ldap_memfree( retoid );
     254           0 :                     ber_bvfree( retdata );
     255           0 :                     return LDAPerror( ld, "LDAPControls_to_List" );
     256             :                  }
     257           3 :                  ldap_controls_free(serverctrls);
     258             : 
     259           3 :                  valuestr = LDAPberval_to_object(retdata);
     260           3 :                  ber_bvfree( retdata );
     261           3 :                  pyoid = PyUnicode_FromString(retoid);
     262           3 :                  ldap_memfree( retoid );
     263           3 :                  if (pyoid == NULL)  {
     264           0 :                         Py_DECREF(result);
     265           0 :                         ldap_msgfree( m );
     266           0 :                         return NULL;
     267             :                  }
     268           3 :                  valtuple = Py_BuildValue("(OOO)", pyoid,
     269             :                                           valuestr ? valuestr : Py_None,
     270             :                                           pyctrls);
     271           3 :                  Py_DECREF(pyoid);
     272           3 :                  Py_DECREF(valuestr);
     273           3 :                  Py_XDECREF(pyctrls);
     274           3 :                  PyList_Append(result, valtuple);
     275           3 :                  Py_DECREF(valtuple);
     276             :               }
     277             :            }
     278             :      }
     279         158 :      ldap_msgfree( m );
     280         158 :      return result;
     281             : }

Generated by: LCOV version 1.12