"Fossies" - the Fresh Open Source Software Archive

Member "ldapexplorertool-2.0.1/src/schema.cc" (15 Oct 2006, 15094 Bytes) of package /linux/privat/old/ldapexplorertool-2.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "schema.cc" see the Fossies "Dox" file reference documentation.

    1 #ifdef __GNUG__
    2     #pragma implementation "ldapclass.h"
    3 #endif
    4 #include "wx/wxprec.h"
    5 
    6 #ifdef __BORLANDC__
    7     #pragma hdrstop
    8 #endif
    9 
   10 #ifndef WX_PRECOMP
   11     #include "wx/wx.h"
   12 #endif
   13 
   14 #include <wx/config.h>
   15 #include <wx/fileconf.h>
   16 #include <wx/wfstream.h>
   17 
   18 #include "ldapentry.h"
   19 #include "ldapclass.h"
   20 #include "schema.h"
   21 
   22 wxChar* DEFAULT_SUBSCHEMASUBENTRY=wxT( "cn=subschema" );
   23 
   24 
   25 void SchemaUtil::SetConfig( const wxString& p_Name )
   26 {
   27     m_ConfigName = p_Name ;
   28     m_SearchId = -1 ;
   29     m_HasSchema = false ;
   30     m_GuessBinary = false ;
   31 }
   32 SchemaUtil::SchemaUtil( void ) : LdapClass()
   33 {
   34     m_SearchId = -1 ;
   35 }
   36 SchemaUtil::~SchemaUtil()
   37 {
   38     Close();
   39 }
   40 
   41 bool SchemaUtil::HasSchema( void )
   42 {
   43     return m_HasSchema;
   44 }
   45 
   46 void SchemaUtil::Close( void )
   47 {
   48     LdapClass::Close();
   49     std::vector< LDAPObjectClass* >::iterator iter1 ;
   50     for( iter1 = m_ObjectClasses.begin(); iter1 != m_ObjectClasses.end(); iter1++ )
   51     {
   52         ldap_objectclass_free( (*iter1) );
   53     }
   54     m_ObjectClasses.clear();
   55 
   56     std::vector< LDAPAttributeType* >::iterator iter2 ;
   57     for( iter2 = m_AttributeTypes.begin(); iter2 != m_AttributeTypes.end(); iter2++ )
   58     {
   59         ldap_attributetype_free( (*iter2) );
   60     }
   61     m_AttributeTypes.clear();
   62     
   63     std::vector< LDAPSyntax* >::iterator iter3 ;
   64     for( iter3 = m_Syntaxes.begin(); iter3 != m_Syntaxes.end(); iter3++ )
   65     {
   66         ldap_syntax_free( (*iter3) );
   67     }
   68     m_Syntaxes.clear();
   69 }
   70 
   71 int SchemaUtil::FindSchemaEntry( const wxString& p_BaseDN )
   72 {
   73     int Ret ;
   74     wxString    SchemaEntry ;   
   75     int Id ;    
   76     
   77     /*
   78     *   Is a subschema subentry configured
   79     */
   80     SchemaEntry = wxConfig::Get()->Read( wxString::Format( wxT( "/configurations/%s/subschemasubentry" ), 
   81     m_ConfigName.c_str() ) );
   82 
   83     if( SchemaEntry.Len() == 0 )
   84     {   
   85         /*
   86         *   Try to find the subschemasubentry attribute in the baseDN
   87         */
   88         Ret = Search( Id, p_BaseDN, LDAP_SCOPE_BASE, wxT( "objectclass=*" ), 
   89         NULL, true, LF_ALL_OPERATIONAL );
   90         if( Ret == LDAP_SUCCESS )
   91         {
   92 
   93             int NbEntries = GetEntryCount( Id ) ;
   94             if( NbEntries > 0 )
   95             {
   96                 LdapEntry Entry ;
   97                 if( !GetEntry( Id, 0, Entry ) )
   98                 {
   99                     ::wxLogError( wxT( "FindSchemaEntry: %d - %s" ),m_Err, GetErrorStr().c_str() );
  100                 }
  101                 else
  102                 {
  103                     LdapAttribute *Attribute = Entry.GetAttribute( wxT( "subschemasubentry" ), true );
  104                     if( Attribute != NULL )
  105                     {
  106                         SchemaEntry = Attribute->GetValue( 0 ) ;
  107                     }
  108                 }
  109             }
  110             CloseSearch( Id );
  111         }
  112     }
  113     if( SchemaEntry.Len() == 0 )
  114     {   
  115         /*
  116         *   Try to find the subschemasubentry attribute in the rootDN
  117         */
  118         Ret = Search( Id, wxT( "" ), LDAP_SCOPE_BASE, wxT( "objectclass=*" ), 
  119         NULL, true, LF_ALL_OPERATIONAL );
  120         if( Ret != LDAP_SUCCESS )
  121         {
  122             SchemaEntry = DEFAULT_SUBSCHEMASUBENTRY ;
  123         }
  124         else
  125         {
  126             int NbEntries = GetEntryCount( Id ) ;
  127             if( NbEntries > 0 )
  128             {
  129                 LdapEntry Entry ;
  130                 if( !GetEntry( Id, 0, Entry ) )
  131                 {
  132                     ::wxLogError( wxT( "FindSchemaEntry: %d - %s" ),m_Err, GetErrorStr().c_str() );
  133                 }
  134                 LdapAttribute *Attribute = Entry.GetAttribute( wxT( "subschemasubentry" ), true );
  135                 if( Attribute != NULL )
  136                 {
  137                     SchemaEntry = Attribute->GetValue( 0 ) ;
  138                 }
  139                 else
  140                 {
  141                     SchemaEntry = DEFAULT_SUBSCHEMASUBENTRY ;
  142                 }
  143             }
  144             else
  145             {
  146                 /*
  147                 * Try the default value for subschemasubentry
  148                 */
  149                 SchemaEntry = DEFAULT_SUBSCHEMASUBENTRY ;
  150             }
  151             CloseSearch( Id );
  152         }
  153     }
  154     /*
  155     *   get the schema entry
  156     */
  157     Ret = Search( m_SearchId, SchemaEntry, LDAP_SCOPE_BASE, wxT( "objectclass=*" ), 
  158     NULL, true, LF_ALL_OPERATIONAL );
  159     if( Ret != LDAP_SUCCESS )
  160     {
  161         ::wxLogError( wxT( "FindSchemaEntry: %d - %s" ),m_Err, GetErrorStr().c_str() );
  162         return Ret ;
  163     }
  164     return LDAP_SUCCESS ;
  165 }
  166 int SchemaUtil::GetSchema( const wxString& p_BaseDN )
  167 {
  168     
  169     
  170     m_Err = FindSchemaEntry( p_BaseDN );
  171     if( m_Err != LDAP_SUCCESS )
  172     {
  173         m_HasSchema = false ;
  174         return m_Err;
  175     }
  176     
  177 
  178     int NbEntries = GetEntryCount( m_SearchId ) ;
  179     if( NbEntries <= 0 )
  180     {
  181         m_HasSchema = false ;
  182         return LDAP_SUCCESS ;
  183     }
  184     
  185     LdapEntry Entry ;
  186     
  187     GetEntry( m_SearchId, 0, Entry );
  188     LdapAttribute *ObjectClasses = Entry.GetAttribute( wxT( "objectClasses" ), true );
  189     LdapAttribute *AttributeTypes = Entry.GetAttribute( wxT( "attributeTypes" ), true );
  190     LdapAttribute *Syntaxes = Entry.GetAttribute( wxT( "ldapSyntaxes" ), true );
  191     
  192     long nValues ;
  193     long i;
  194     wxString Value ;
  195     int Err;
  196     const char *Errp ;
  197     if( ObjectClasses != NULL )
  198     {
  199         nValues = ObjectClasses->CountValues() ;
  200         for( i = 0; i < nValues ; i++ )
  201         {
  202             Value = ObjectClasses->GetValue( i ) ;
  203             LDAPObjectClass *Oc = ldap_str2objectclass( Value.mb_str(wxConvUTF8), &Err, &Errp, LDAP_SCHEMA_ALLOW_ALL );
  204             if( Oc != NULL )
  205             {
  206                 m_ObjectClasses.insert( m_ObjectClasses.end(), Oc );
  207             }
  208         }
  209     }
  210 
  211     if( AttributeTypes != NULL )
  212     {
  213         nValues = AttributeTypes->CountValues() ;
  214         for( i = 0; i < nValues ; i++ )
  215         {
  216             Value = AttributeTypes->GetValue( i ) ;
  217             LDAPAttributeType *At = ldap_str2attributetype( Value.mb_str(wxConvUTF8), &Err, &Errp, LDAP_SCHEMA_ALLOW_ALL );
  218             if( At != NULL )
  219             {
  220                 m_AttributeTypes.insert( m_AttributeTypes.end(), At );
  221             }
  222         }
  223     }
  224     if( Syntaxes != NULL )
  225     {
  226         nValues = Syntaxes->CountValues() ;
  227         for( i = 0; i < nValues ; i++ )
  228         {
  229             Value = Syntaxes->GetValue( i ) ;
  230             LDAPSyntax *Syn = ldap_str2syntax( Value.mb_str(wxConvUTF8), &Err, &Errp, LDAP_SCHEMA_ALLOW_ALL );
  231             if( Syn != NULL )
  232             {
  233                 m_Syntaxes.insert( m_Syntaxes.end(), Syn );
  234                 /*::wxMessageBox( wxString( Syn->syn_names[0], wxConvUTF8 ) );*/
  235             }
  236         }
  237     }
  238     m_HasSchema = true ;
  239     return LDAP_SUCCESS ;
  240 }
  241 
  242 int SchemaUtil::GetObjectClasses( wxArrayString& p_Array )
  243 {
  244     std::vector< LDAPObjectClass* >::iterator iter ;
  245     
  246     p_Array.Clear();
  247     for( iter = m_ObjectClasses.begin(); iter != m_ObjectClasses.end(); iter++ )
  248     {
  249         LDAPObjectClass* Class = (*iter);
  250         if( Class->oc_names == NULL )
  251             continue;
  252             
  253         for( long i = 0; Class->oc_names[ i ] != NULL; i++ )
  254         {
  255             p_Array.Add( wxString( Class->oc_names[ i ], wxConvUTF8 ) );
  256         }
  257     }
  258     p_Array.Sort();
  259     return p_Array.Count() ;
  260 }
  261 int SchemaUtil::GetAttributeTypes( wxArrayString& p_Array )
  262 {
  263     std::vector< LDAPAttributeType* >::iterator iter ;
  264     
  265     p_Array.Clear();
  266     for( iter = m_AttributeTypes.begin(); iter != m_AttributeTypes.end(); iter++ )
  267     {
  268         LDAPAttributeType* Type = (*iter);
  269         if( Type->at_names == NULL )
  270             continue;
  271             
  272         for( long i = 0; Type->at_names[ i ] != NULL; i++ )
  273         {
  274             p_Array.Add( wxString( Type->at_names[ i ], wxConvUTF8 ) );
  275         }
  276     }
  277     p_Array.Sort();
  278     return p_Array.Count() ;
  279 }
  280 
  281 int SchemaUtil::GetSyntaxes( wxArrayString& p_Array )
  282 {
  283     std::vector< LDAPSyntax* >::iterator iter ;
  284     
  285     p_Array.Clear();
  286     for( iter = m_Syntaxes.begin(); iter != m_Syntaxes.end(); iter++ )
  287     {
  288         LDAPSyntax* Syn = (*iter);
  289         if( /*Syn->syn_names == NULL && */Syn->syn_desc == NULL )
  290             continue;
  291             
  292         p_Array.Add( wxString( Syn->syn_desc, wxConvUTF8 ) );   
  293         /*
  294         for( long i = 0; Syn->syn_names[ i ] != NULL; i++ )
  295         {
  296             p_Array.Add( wxString( Syn->syn_names[ i ], wxConvUTF8 ) );
  297         }
  298         */
  299     }
  300     p_Array.Sort();
  301     return p_Array.Count() ;
  302 }
  303 
  304 LDAPObjectClass* SchemaUtil::FindObjectClass( const wxString& p_Name )
  305 {
  306     LDAPObjectClass* Ret = NULL ;
  307     std::vector< LDAPObjectClass* >::iterator iter ;
  308     
  309     for( iter = m_ObjectClasses.begin(); iter != m_ObjectClasses.end(); iter++ )
  310     {
  311         LDAPObjectClass* Class = (*iter);
  312         if( Class->oc_names == NULL )
  313             continue;
  314             
  315         for( long i = 0; Class->oc_names[ i ] != NULL; i++ )
  316         {
  317             if( p_Name.Cmp( wxString( Class->oc_names[ i ], wxConvUTF8 ) ) == 0 )
  318             {
  319                 Ret = Class ;
  320                 return Ret;
  321             }
  322         }
  323     }
  324     return Ret ;
  325 }
  326 
  327 LDAPObjectClass* SchemaUtil::FindObjectClassByOID( const wxString& p_Oid )
  328 {
  329     LDAPObjectClass* Ret = NULL ;
  330     std::vector< LDAPObjectClass* >::iterator iter ;
  331     
  332     for( iter = m_ObjectClasses.begin(); iter != m_ObjectClasses.end(); iter++ )
  333     {
  334         LDAPObjectClass* Class = (*iter);
  335         if( Class->oc_oid == NULL )
  336             continue;
  337             
  338         if( p_Oid.Cmp( wxString( Class->oc_oid, wxConvUTF8 ) ) == 0 )
  339         {
  340             Ret = Class ;
  341             return Ret;
  342         }
  343     }
  344     return Ret ;
  345 }
  346 
  347 LDAPAttributeType* SchemaUtil::GetAttributeTypeByOID( const wxString& p_OID )
  348 {
  349     LDAPAttributeType* Ret = NULL ;
  350     std::vector< LDAPAttributeType* >::iterator iter ;
  351     
  352     
  353     for( iter = m_AttributeTypes.begin(); iter != m_AttributeTypes.end(); iter++ )
  354     {
  355         LDAPAttributeType* Type = (*iter);
  356         
  357         if( p_OID.Cmp( wxString( Type->at_oid, wxConvUTF8 ) ) == 0 )
  358         {
  359             Ret = Type ;
  360             break;
  361         }
  362     }
  363     
  364     return Ret;
  365 }
  366 
  367 LDAPSyntax* SchemaUtil::GetSyntaxByOID( const wxString& p_OID )
  368 {
  369     LDAPSyntax* Ret = NULL ;
  370     std::vector< LDAPSyntax* >::iterator iter ;
  371     
  372     
  373     for( iter = m_Syntaxes.begin(); iter != m_Syntaxes.end(); iter++ )
  374     {
  375         LDAPSyntax* Syn = (*iter);
  376         
  377         if( p_OID.Cmp( wxString( Syn->syn_oid, wxConvUTF8 ) ) == 0 )
  378         {
  379             Ret = Syn ;
  380             break;
  381         }
  382     }
  383     
  384     return Ret;
  385 }
  386 
  387 LDAPSyntax* SchemaUtil::GetSyntaxByName( const wxString& p_Name )
  388 {
  389     LDAPSyntax* Ret = NULL ;
  390     std::vector< LDAPSyntax* >::iterator iter ;
  391     
  392     
  393     for( iter = m_Syntaxes.begin(); iter != m_Syntaxes.end(); iter++ )
  394     {
  395         LDAPSyntax* Syn = (*iter);
  396         
  397         if( Syn->syn_names != NULL && p_Name.Cmp( wxString( Syn->syn_names[0], wxConvUTF8 ) ) == 0 )
  398         {
  399             Ret = Syn ;
  400             break;
  401         }
  402         if( Syn->syn_desc != NULL && p_Name.Cmp( wxString( Syn->syn_desc, wxConvUTF8 ) ) == 0 )
  403         {
  404             Ret = Syn ;
  405             break;
  406         }
  407     }
  408     
  409     return Ret;
  410 }
  411 
  412 LDAPAttributeType* SchemaUtil::GetAttributeTypeByName( const wxString& p_OID )
  413 {
  414     LDAPAttributeType* Ret = NULL ;
  415     std::vector< LDAPAttributeType* >::iterator iter ;
  416     
  417     
  418     for( iter = m_AttributeTypes.begin(); iter != m_AttributeTypes.end(); iter++ )
  419     {
  420         LDAPAttributeType* Type = (*iter);
  421         if( Type->at_names == NULL )
  422             continue;
  423         
  424         for( long i = 0; Type->at_names[ i ] != NULL; i++ )
  425         {
  426             if( p_OID.Cmp( wxString( Type->at_names[ i ], wxConvUTF8 ) ) == 0 )
  427             {
  428                 Ret = Type ;
  429                 return Ret;
  430             }
  431         }
  432     }
  433     
  434     return Ret;
  435 }
  436 
  437 int SchemaUtil::GetMUSTAttributeTypes( const wxString& p_ObjectClass, wxArrayString& p_Array )
  438 {
  439     LDAPObjectClass* Class = FindObjectClass( p_ObjectClass );
  440     if( Class != NULL )
  441     {
  442         if( Class->oc_at_oids_must != NULL )
  443         {
  444             for( long i = 0; Class->oc_at_oids_must[ i ] != NULL; i++ )
  445             {
  446                 p_Array.Add( wxString( Class->oc_at_oids_must[ i ], wxConvUTF8 ) );
  447             }
  448         }
  449         if( Class->oc_sup_oids != NULL )
  450         {
  451             for( long i = 0; Class->oc_sup_oids[ i ] != NULL; i++)
  452             {
  453                 GetMUSTAttributeTypes( wxString( Class->oc_sup_oids[ i ], wxConvUTF8 ), p_Array );
  454             }
  455         }
  456     }   
  457     return p_Array.Count() ;
  458 }
  459 
  460 int SchemaUtil::GetMAYAttributeTypes( const wxString& p_ObjectClass, wxArrayString& p_Array )
  461 {
  462     LDAPObjectClass* Class = FindObjectClass( p_ObjectClass );
  463     if( Class != NULL )
  464     {
  465         if( Class->oc_at_oids_may != NULL )
  466         {
  467             for( long i = 0; Class->oc_at_oids_may[ i ] != NULL; i++ )
  468             {
  469                 p_Array.Add( wxString( Class->oc_at_oids_may[ i ], wxConvUTF8 ) );
  470             }
  471         }
  472         if( Class->oc_sup_oids != NULL )
  473         {
  474             for( long i = 0; Class->oc_sup_oids[ i ] != NULL; i++)
  475             {
  476                 GetMAYAttributeTypes( wxString( Class->oc_sup_oids[ i ], wxConvUTF8 ), p_Array );
  477             }
  478         }
  479     }   
  480     return p_Array.Count() ;
  481 }
  482 
  483 bool SchemaUtil::IsBinaryAttribute( const wxString& p_Name )
  484 {
  485     LDAPAttributeType* Type = NULL ;
  486     LDAPSyntax *Syntax = NULL ;
  487     
  488     if( !m_GuessBinary )
  489         return false ;
  490     
  491     if( p_Name.Contains( wxT( ";binary" ) ) )
  492     {
  493         ::wxMessageBox( wxT( "Name Contains ;binary" ) );
  494     }
  495     Type = GetAttributeTypeByName( p_Name );
  496     if( Type != NULL )
  497     {
  498         if( m_CheckAttDescription == 1 )
  499         {
  500             /*
  501             *   Search for the word binary in the description
  502             */
  503             wxString Desc = wxString( Type->at_desc, wxConvUTF8 ) ;
  504             Desc.MakeLower();
  505             if( Desc.Contains( wxT( "binary" ) ) )
  506             {
  507                 ::wxMessageBox( wxT( "Desc Contains binary" ) );
  508                 return true ;
  509 
  510             }
  511         }
  512         
  513         if( m_CheckAttExtension == 1 )
  514         {
  515             /*
  516             *   Search for the word binary in the attribute's extensions
  517             */
  518             for( long i = 0; Type->at_extensions != NULL && Type->at_extensions[ i ] != NULL ; i++ )
  519             {
  520                 wxString Extension = wxString( Type->at_extensions[ i ]->lsei_name, wxConvUTF8 ) ;
  521                 if( Extension.CmpNoCase( wxT( "binary" ) ) == 0 )
  522                 {
  523                     ::wxMessageBox( wxT( "Att Ext Contains binary" ) );
  524                     return true;
  525                 }
  526             }
  527         }
  528         if( Type->at_syntax_oid != NULL )
  529         {
  530             Syntax = GetSyntaxByOID( wxString( Type->at_syntax_oid, wxConvUTF8 ) );
  531             if( Syntax != NULL )
  532             {
  533                 wxString Desc = wxString( Syntax->syn_desc, wxConvUTF8 ) ;
  534                 Desc.MakeLower();
  535                 for( long i= 0; i < m_BinarySyntaxes.Count(); i++ )
  536                 {
  537                     if( Desc.Contains( m_BinarySyntaxes[i] ) )
  538                     {
  539                         ::wxMessageBox( wxString::Format( wxT( "Syntax Contains %s" ), m_BinarySyntaxes[i].c_str() ) );
  540                         return true;
  541                     }
  542                 }
  543                 
  544                 for( long i = 0; Syntax->syn_extensions != NULL && Syntax->syn_extensions[ i ] != NULL; i++ )
  545                 {
  546                     wxString Name,Value ;
  547                     Name = wxString( Syntax->syn_extensions[ i ]->lsei_name, wxConvUTF8 ) ;
  548                     
  549                     StringMap::iterator iter ;
  550                     for( iter = m_BinaryExtensions.begin(); iter != m_BinaryExtensions.end(); iter ++ )
  551                     {
  552                         if( Name.CmpNoCase( (*iter).first ) == 0 )
  553                         {
  554                             for( long j = 0; Syntax->syn_extensions[ i ]->lsei_values != NULL &&
  555                             Syntax->syn_extensions[ i ]->lsei_values[ j ] != NULL; j++ )
  556                             {
  557                                 Value = wxString( Syntax->syn_extensions[ i ]->lsei_values[ j ], wxConvUTF8 ) ;
  558                                 if( Value.CmpNoCase( (*iter).second ) )
  559                                 {
  560                                     ::wxMessageBox( wxString::Format( wxT( "Syntax Ext Contains Contains %s" ), (*iter).second.c_str() ) );
  561                                     return true;
  562                                 }
  563                             }
  564                         }
  565                     }
  566                 }
  567             }
  568         }
  569     }
  570     
  571     return false ;
  572 }
  573 
  574 void SchemaUtil::GuessBinary( bool p_Guess )
  575 {
  576     m_GuessBinary = p_Guess ;
  577     if( m_GuessBinary )
  578     {
  579         m_CheckAttDescription = 1;
  580         m_CheckAttExtension = 1;
  581     }
  582 }
  583 
  584 
  585 bool SchemaUtil::ReplaceAttributeType( LDAPAttributeType* p_New )
  586 {
  587     wxString Oid( p_New->at_oid, wxConvUTF8 ) ;
  588     
  589     LdapEntry Entry ;
  590     LdapEntry NewEntry ;
  591     
  592     GetEntry( m_SearchId, 0, Entry );
  593 
  594     LdapAttribute *AttributeTypes = Entry.GetAttribute( wxT( "attributeTypes" ), true );
  595     
  596     long nValues ;
  597     long i;
  598     wxString Value ;
  599     int Err;
  600     const char *Errp ;
  601 
  602     if( AttributeTypes == NULL )
  603     {
  604         return false ;
  605     }
  606     
  607     NewEntry.SetDn( Entry.GetDn() );
  608     
  609     nValues = AttributeTypes->CountValues() ;
  610     for( i = 0; i < nValues ; i++ )
  611     {
  612         Value = AttributeTypes->GetValue( i ) ;
  613         LDAPAttributeType *At = ldap_str2attributetype( Value.mb_str(wxConvUTF8), &Err, &Errp, LDAP_SCHEMA_ALLOW_ALL );
  614         if( At != NULL && strcmp( At->at_oid, p_New->at_oid) == 0 )
  615         {
  616             char* NewValue = ldap_attributetype2str( p_New );
  617             NewEntry.AddValue( wxT("attributeTypes"),wxString( NewValue, wxConvUTF8 ) );
  618             free( NewValue );   
  619         }
  620         else
  621         {
  622             NewEntry.AddValue( wxT("attributeTypes"),Value );
  623         }
  624     }
  625     
  626     if( ReplaceEntry( NewEntry ) != LDAP_SUCCESS )
  627     {
  628         return false ;
  629     }
  630     return true ;
  631 }
  632 
  633 bool SchemaUtil::AddAttributeType( LDAPAttributeType* p_New )
  634 {
  635     LdapEntry Entry ;
  636     int Err ;
  637 
  638 
  639     GetEntry( m_SearchId, 0, Entry );
  640 
  641     
  642     char* NewValue = ldap_attributetype2str( p_New );
  643 
  644     if( NewValue != NULL )
  645     {
  646         ::wxMessageBox( wxString( NewValue, wxConvUTF8 ) );
  647         Err = AddAttributeValue( Entry.GetDn(), wxT("attributeTypes"), wxString( NewValue,wxConvUTF8 ) );
  648         free( NewValue );
  649         if( Err != LDAP_SUCCESS )
  650         {
  651             return false;
  652         }
  653     }
  654     return true ;
  655 }
  656