home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / getdn.c < prev    next >
C/C++ Source or Header  |  2001-07-22  |  6KB  |  324 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/getdn.c,v 1.18.2.4 2001/07/21 19:01:39 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6. /*  Portions
  7.  *  Copyright (c) 1994 Regents of the University of Michigan.
  8.  *  All rights reserved.
  9.  *
  10.  *  getdn.c
  11.  */
  12.  
  13. #include "portable.h"
  14.  
  15. #include <stdio.h>
  16.  
  17. #include <ac/stdlib.h>
  18.  
  19. #include <ac/ctype.h>
  20. #include <ac/socket.h>
  21. #include <ac/string.h>
  22. #include <ac/time.h>
  23.  
  24. #include "ldap-int.h"
  25.  
  26. #define NAME_TYPE_LDAP_RDN    0
  27. #define NAME_TYPE_LDAP_DN    1
  28. #define NAME_TYPE_DCE_DN    2
  29.  
  30. static char **explode_name( const char *name, int notypes, int is_type );
  31.  
  32. char *
  33. ldap_get_dn( LDAP *ld, LDAPMessage *entry )
  34. {
  35.     char        *dn;
  36.     BerElement    tmp;
  37.  
  38.     Debug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
  39.  
  40.     if ( entry == NULL ) {
  41.         ld->ld_errno = LDAP_PARAM_ERROR;
  42.         return( NULL );
  43.     }
  44.  
  45.     tmp = *entry->lm_ber;    /* struct copy */
  46.     if ( ber_scanf( &tmp, "{a" /*}*/, &dn ) == LBER_ERROR ) {
  47.         ld->ld_errno = LDAP_DECODING_ERROR;
  48.         return( NULL );
  49.     }
  50.  
  51.     return( dn );
  52. }
  53.  
  54. char *
  55. ldap_dn2ufn( LDAP_CONST char *dn )
  56. {
  57.     char    *ufn;
  58.     char    **vals;
  59.     int i;
  60.  
  61.     Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
  62.  
  63.     /* produces completely untyped UFNs */
  64.  
  65.     if( dn == NULL ) {
  66.         return NULL;
  67.     }
  68.  
  69.     vals = ldap_explode_dn( dn , 0 );
  70.     if( vals == NULL ) {
  71.         return NULL;
  72.     }
  73.  
  74.     for ( i = 0; vals[i]; i++ ) {
  75.         char **rvals;
  76.  
  77.         rvals = ldap_explode_rdn( vals[i] , 1 );
  78.         if ( rvals == NULL ) {
  79.             LDAP_VFREE( vals );
  80.             return NULL;
  81.         }
  82.  
  83.         LDAP_FREE( vals[i] );
  84.         vals[i] = ldap_charray2str( rvals, " + " );
  85.         LDAP_VFREE( rvals );
  86.     }
  87.  
  88.     ufn = ldap_charray2str( vals, ", " );
  89.  
  90.     LDAP_VFREE( vals );
  91.     return ufn;
  92. }
  93.  
  94. char **
  95. ldap_explode_dn( LDAP_CONST char *dn, int notypes )
  96. {
  97.     Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
  98.  
  99.     return explode_name( dn, notypes, NAME_TYPE_LDAP_DN );
  100. }
  101.  
  102. char **
  103. ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
  104. {
  105.     Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
  106.     return explode_name( rdn, notypes, NAME_TYPE_LDAP_RDN );
  107. }
  108.  
  109. char *
  110. ldap_dn2dcedn( LDAP_CONST char *dn )
  111. {
  112.     char *dce, *q, **rdns, **p;
  113.     int len = 0;
  114.  
  115.     Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
  116.  
  117.     rdns = explode_name( dn, 0, NAME_TYPE_LDAP_DN );
  118.     if ( rdns == NULL ) {
  119.         return NULL;
  120.     }
  121.     
  122.     for ( p = rdns; *p != NULL; p++ ) {
  123.         len += strlen( *p ) + 1;
  124.     }
  125.  
  126.     q = dce = LDAP_MALLOC( len + 1 );
  127.     if ( dce == NULL ) {
  128.         return NULL;
  129.     }
  130.  
  131.     p--; /* get back past NULL */
  132.  
  133.     for ( ; p != rdns; p-- ) {
  134.         strcpy( q, "/" );
  135.         q++;
  136.         strcpy( q, *p );
  137.         q += strlen( *p );
  138.     }
  139.  
  140.     strcpy( q, "/" );
  141.     q++;
  142.     strcpy( q, *p );
  143.     
  144.     return dce;
  145. }
  146.  
  147. char *
  148. ldap_dcedn2dn( LDAP_CONST char *dce )
  149. {
  150.     char *dn, *q, **rdns, **p;
  151.     int len;
  152.  
  153.     Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
  154.  
  155.     rdns = explode_name( dce, 0, NAME_TYPE_DCE_DN );
  156.     if ( rdns == NULL ) {
  157.         return NULL;
  158.     }
  159.  
  160.     len = 0;
  161.  
  162.     for ( p = rdns; *p != NULL; p++ ) {
  163.         len += strlen( *p ) + 1;
  164.     }
  165.  
  166.     q = dn = LDAP_MALLOC( len );
  167.     if ( dn == NULL ) {
  168.         return NULL;
  169.     }
  170.  
  171.     p--;
  172.  
  173.     for ( ; p != rdns; p-- ) {
  174.         strcpy( q, *p );
  175.         q += strlen( *p );
  176.         strcpy( q, "," );
  177.         q++;
  178.     }
  179.  
  180.     if ( *dce == '/' ) {
  181.         /* the name was fully qualified, thus the most-significant
  182.          * RDN was empty. trash the last comma */
  183.         q--;
  184.         *q = '\0';
  185.     } else {
  186.         /* the name was relative. copy the most significant RDN */
  187.         strcpy( q, *p );
  188.     }
  189.  
  190.     return dn;
  191. }
  192.  
  193. #define INQUOTE        1
  194. #define OUTQUOTE    2
  195.  
  196. static char **
  197. explode_name( const char *name, int notypes, int is_type )
  198. {
  199.     const char *p, *q, *rdn;
  200.     char **parts = NULL;
  201.     int    offset, state, have_equals, count = 0, endquote, len;
  202.  
  203.     /* safe guard */
  204.     if(name == NULL) name = "";
  205.  
  206.     /* skip leading whitespace */
  207.     while( ldap_utf8_isspace( name )) {
  208.         LDAP_UTF8_INCR( name );
  209.     }
  210.  
  211.     p = rdn = name;
  212.     offset = 0;
  213.     state = OUTQUOTE;
  214.     have_equals=0;
  215.  
  216.     do {
  217.         /* step forward */
  218.         p += offset;
  219.         offset = 1;
  220.  
  221.         switch ( *p ) {
  222.         case '\\':
  223.             if ( p[1] != '\0' ) {
  224.                 offset = LDAP_UTF8_OFFSET(++p);
  225.             }
  226.             break;
  227.         case '"':
  228.             if ( state == INQUOTE )
  229.                 state = OUTQUOTE;
  230.             else
  231.                 state = INQUOTE;
  232.             break;
  233.         case '=':
  234.             if( state == OUTQUOTE ) have_equals++;
  235.             break;
  236.         case '+':
  237.             if (is_type == NAME_TYPE_LDAP_RDN)
  238.                 goto end_part;
  239.             break;
  240.         case '/':
  241.             if (is_type == NAME_TYPE_DCE_DN)
  242.                 goto end_part;
  243.             break;
  244.         case ';':
  245.         case ',':
  246.             if (is_type == NAME_TYPE_LDAP_DN)
  247.                 goto end_part;
  248.             break;
  249.         case '\0':
  250.         end_part:
  251.             if ( state == OUTQUOTE ) {
  252.                 ++count;
  253.                 have_equals=0;
  254.  
  255.                 if ( parts == NULL ) {
  256.                     if (( parts = (char **)LDAP_MALLOC( 8
  257.                          * sizeof( char *))) == NULL )
  258.                         return( NULL );
  259.                 } else if ( count >= 8 ) {
  260.                     if (( parts = (char **)LDAP_REALLOC( parts,
  261.                         (count+1) * sizeof( char *)))
  262.                         == NULL )
  263.                         return( NULL );
  264.                 }
  265.  
  266.                 parts[ count ] = NULL;
  267.                 endquote = 0;
  268.  
  269.                 if ( notypes ) {
  270.                     for ( q = rdn; q < p && *q != '='; ++q ) {
  271.                         /* EMPTY */;
  272.                     }
  273.  
  274.                     if ( q < p ) {
  275.                         rdn = ++q;
  276.                     }
  277.  
  278.                     if ( *rdn == '"' ) {
  279.                         ++rdn;
  280.                     }
  281.                     
  282.                     if ( p[-1] == '"' ) {
  283.                         endquote = 1;
  284.                         --p;
  285.                     }
  286.                 }
  287.  
  288.                 len = p - rdn;
  289.  
  290.                 if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
  291.                     len + 1 )) != NULL )
  292.                 {
  293.                        AC_MEMCPY( parts[ count-1 ], rdn, len );
  294.  
  295.                     if( !endquote ) {
  296.                         /* skip trailing spaces */
  297.                         while( len > 0 && ldap_utf8_isspace(
  298.                             &parts[count-1][len-1] ) )
  299.                         {
  300.                             --len;
  301.                         }
  302.                     }
  303.  
  304.                     parts[ count-1 ][ len ] = '\0';
  305.                 }
  306.  
  307.                 /*
  308.                  *  Don't forget to increment 'p' back to where
  309.                  *  it should be.  If we don't, then we will
  310.                  *  never get past an "end quote."
  311.                  */
  312.                 if ( endquote == 1 )
  313.                     p++;
  314.  
  315.                 rdn = *p ? &p[1] : p;
  316.                 while ( ldap_utf8_isspace( rdn ) )
  317.                     ++rdn;
  318.             } break;
  319.         }
  320.     } while ( *p );
  321.  
  322.     return( parts );
  323. }
  324.