Daniele Frasca mi ha chiesto di poter ospitare all'interno di questo blog una sua classe che permette il collegamento a OpenLDAP con .NET FrameWork
Riporto per intero il codice (senza alcuna modifica) e relativa descrizione sperando che possa servire a qualcuno.

Descrizione

Finalmente dopo un bel pò di tempo sono capitato su un progetto + o - interessante che mi ha dato la possibilità di approfondire qualcosina che mi interessava. La nostra bella classe preve prevede 2 metodi di inizializzazione dove setteremo il nostro bel path base:

InitDirectoryEntry() per accedere alla root del nostro repository e l'altro un semplice overload di InitDirectoryEntry(string ou) per accedere in nodo ben preciso del nostro repository.
Ogni ricerca si baserà du una connessione ben precisa, questa potrà essere di questi tipo:

DN = ou=Utenti, dc=dominio,dc=it

o più in dettaglio

DN = an=office, ou=Applicazioni, dc=dominio,dc=it ecc

Partendo da questa base, introduco brevemente lo scopo dei metodi:

public static string[] getObject(string objectClass, string PropertiesToLoad)

Ci permette di recuperare una ben determinata proprietà di un nostro oggetto.
Una volta passato lo schema e la proprietà da caricare avremo un comodissimo array di stringhe da leggere e da stampare.

public static DataTable readObject(string nome, string objectClass, string[]

PropertiesToLoad)

Una volta trovati i singoli oggetti, abbiamo voglia di conoscere le singole proprietà, quindi questo metodo non fa altro che impostare il nome dell'oggetto da ricercare NOME = "cn=daniele"

lo schema da caricare e le varie proprietà che caricheremo nel SearchDirecotry

search.PropertiesToLoad.AddRange(PropertiesToLoad);

che come si potrà notare accetta come input un array di stringhe.

Come ritorno questo metodo ci fornisce un DataTable, ma volendo possiamo crearci altri tipi di oggetti XML ecc.

I restanti metodi:

public static bool addObject(string nome, string objectClass, string[] setProperties, string[] valProperties) public static bool modifyObject(string nome, string objectClass, string[] setProperties, string[] valProperties) public static bool deleteObject(string nome, string objectClass) non fanno altro che ricercare il nome passatogli e in caso che questo sia presente o meno aggiungere, cancellare o modificare l'oggetto nel repository.

Il metodo addObject e modifyObject come potete notare accettano 2 array di stringhe ("si potrebbe fare meglio, ma questa è la mia beta1") che contengono i nomi delle proprietà e i rispettivi valori che andremo a settare grazie al metodo

SettaProprieta(user, setProperties, valProperties);

Una cosa abbastanza banale ma può tornare sempre utile averla a disposizione.

Codice

using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Collections;
using System.DirectoryServices;

namespace clsLDAP
{
    
class LDAP
    {

        
#region Proprietà
        static 
DirectoryEntry de;

        
static string username;
        
static public string ADusr
        {
            
get
            
{
                
return ConfigurationManager.AppSettings["OpenLDAP_username_connection"].ToString();
            }
        }

        
static string password;
        
static public string ADpwd
        {
            
get
            
{
                
return ConfigurationManager.AppSettings["OpenLDAP_password_connection"].ToString();
            }
        }

        
static string server;
        
static public string ADserver
        {
            
get
            
{
                
return ConfigurationManager.AppSettings["OpenLDAP_connection_machine"].ToString();
            }
        }

        
static string dc;
        
static public string ADdc
        {
            
get
            
{
                
return ConfigurationManager.AppSettings["OpenLDAP_base_path"].ToString();
            }
        }
        
#endregion

        static void 
CommonInit()
        {
            de.Username = ADusr;
            de.Password = ADpwd;
            de.AuthenticationType = AuthenticationTypes.None;
        }

        
#region Overload dell'inizializzazione di DirectoryEntry
        public static void 
InitDirectoryEntry()
        {

            de = 
new DirectoryEntry();
            de.Path = "LDAP://" + ADserver + "/" + ADdc;
            CommonInit();

        }
        
public static void InitDirectoryEntry(string DN)
        {
            
//DN = an=office, ou=Applicazioni, dc=dominio,dc=it
            //DN = ou=Applicazioni, dc=dominio,dc=it
            
de = new DirectoryEntry();
            de.Path = "LDAP://" + ADserver + "/" + DN;
            CommonInit();
        }
        
#endregion

        #region Funzioni Generiche sugli Oggetti: Lista, Aggiunta, Modifica, Eliminazione

        
/// 
        /// Recupera il nome degli oggetti ricercati.
        
/// 

        /// 
schema di LDAP (person, applicazioneLottomatica...)
        /// 
Proprità da caricare
        /// 
un'array di stringhe
        
public static string[] getObject(string objectClass, string PropertiesToLoad)
        {

            DirectorySearcher search = 
new DirectorySearcher();
            search.SearchRoot = de;
            
string filtro = "(objectClass="+ objectClass +")";

            search.Filter = filtro;
            search.PropertiesToLoad.Add(PropertiesToLoad);

            
//search.PropertiesToLoad.AddRange(New String() {"cn", "mail"})

            //SearchResult result = search.FindOne();


            
SearchResultCollection resultc = search.FindAll();

            ArrayList userNames = 
new ArrayList();
            
if (resultc != null)
            {
                
foreach (SearchResult result in resultc)
                {
                    ResultPropertyCollection props = result.Properties;
                    
foreach (string propName in props.PropertyNames)
                    {
                        
string app = propName + " " + props[propName][0];
                        
if (propName.Equals(PropertiesToLoad))
                            userNames.Add(props[propName][0]);
                    }
                }
            }
            search.Dispose();
            
string[] vNames;
            vNames = (
string[])userNames.ToArray(typeof(string));

            
return vNames;
        }

        
/// 
        /// Recupera le proprietà dell'oggetto richiesto.
        
/// 

        /// 
schema di LDAP (person, applicazioneLottomatica...)
        /// 
Proprità da caricare
        /// 
Un dataTable
        
public static DataTable readObject(string nome, string objectClass, string[] PropertiesToLoad)
        {

            DirectorySearcher search = 
new DirectorySearcher();
            search.SearchRoot = de;
            search.Filter = "(&(objectClass=" + objectClass + ")(" + nome
+ "))"; ;

            search.PropertiesToLoad.AddRange(PropertiesToLoad);
            
            SearchResult result = search.FindOne();

            
//Creo il dataTable
            
DataTable table = new DataTable("Proprieta");
            DataColumn column;

            
//Genero le colonne
            
for (int i = 0; i < PropertiesToLoad.Length; i++)
            {
                column = 
new DataColumn();
                column.Caption = PropertiesToLoad[i];
                column.ColumnName = PropertiesToLoad[i];
                
//Aggiungo la colonna alla tabella
                
table.Columns.Add(column); 
            }            

            
if (result != null)
            {

                
//recupero l'oggetto
                
DirectoryEntry user = result.GetDirectoryEntry();

                DataRow row;
                
int i = 0;
                
foreach (string propName in user.Properties.PropertyNames)
                {
                   
// string app = propName + " " + props[propName][0];
                    
if (propName.Equals(PropertiesToLoad[i]))
                    {
                        row = table.NewRow();
                        row[PropertiesToLoad[i]] = user.Properties[propName][0];

                        
//Aggiungo la riga alla tabella
                        
table.Rows.Add(row); 

                    }
                    
//userNames.Add(props[propName][0]);
                
}
              
            }
            search.Dispose();

            
return table;
               
        }

        
/// 
        /// Inserisce un oggetto nel repository partendo da una base data
        
/// 

        /// 
Nome dell'oggetto (cn=pippo, pn=lettore...)
        /// 
schema di LDAP (person, applicazioneLottomatica...)
        /// 
Proprietà da settare
        /// 
Valori da settare
        /// 
TRUE in caso positivo, FALSE in caso negativo
        
public static bool addObject(string nome, string objectClass, string[] setProperties, string[] valProperties)
        {
            
try
            
{
                
//cerco l'oggetto
                
DirectorySearcher search = new DirectorySearcher();
                search.SearchRoot = de;
                search.Filter = "(&(objectClass=" + objectClass + ")("+ nome
+"))";
                SearchResult result = search.FindOne();

                
if (result != null)
                {
                    
//ottengo i metodi che consento di gestire gli oggetti
                    
DirectoryEntries users = de.Children;

                    
//aggiungo un nuovo oggetto
                    //DirectoryEntry newuser = users.Add("cn=" + nome, "person");
                    
DirectoryEntry newuser = users.Add(nome, objectClass);

                    
//setto le proprietà
                    
SettaProprieta(newuser, setProperties, valProperties);

                    
//SetProperty(newuser, "cn", nome);
                    //SetProperty(newuser, "sn", nome);


                    //scarico la cache
                    
newuser.CommitChanges();
                    newuser.Close();
                    
return true;
                }
                search.Dispose();
                
return false;
            }
            
catch (Exception ex)
            {
                
return false;
            }
        }

        
/// 
        /// Modifica un oggetto nel repository partendo da una base data
        
/// 

        /// 
Nome dell'oggetto (cn=pippo, pn=lettore...)
        /// 
schema di LDAP (person, applicazioneLottomatica...)
        /// 
Proprietà da settare
        /// 
Valori da settare
        /// 
TRUE in caso positivo, FALSE in caso negativo
        
public static bool modifyObject(string nome, string objectClass, string[] setProperties, string[] valProperties)
        {
            
try
            
{
                DirectorySearcher search = 
new DirectorySearcher();
                search.SearchRoot = de;
                search.Filter = "(&(objectClass=" + objectClass + ")("+ nome
+"))"; ;
                SearchResult result = search.FindOne();

                
if (result != null)
                {
                    
//recupero l'oggetto
                    
DirectoryEntry user = result.GetDirectoryEntry();

                    
//setto le proprietà
                    
SettaProprieta(user, setProperties, valProperties);

                    
//salvo
                    
user.CommitChanges();
                    user.Close();

                    search.Dispose();
                    
return true;
                }
                search.Dispose();
                
return false;

            }
            
catch (Exception ex)
            {
                
return false;
            }


        }

        
/// 
        /// Elimina un oggetto nel repository partendo da una base data
        
/// 

        /// 
Nome dell'oggetto (cn=pippo, pn=lettore...)
        /// 
schema di LDAP (person, applicazioneLottomatica...)
        /// 
TRUE in caso positivo, FALSE in caso negativo
        
public static bool deleteObject(string nome, string objectClass)
        {
            
try
            
{
                DirectorySearcher search = 
new DirectorySearcher();
                search.SearchRoot = de;
                search.Filter = "(&(objectClass=" + objectClass + ")(" + nome  + "))"; ;
                SearchResult result = search.FindOne();
                
if (result != null)
                {
                    DirectoryEntry myDE = result.GetDirectoryEntry();

                    
//rimuovo l'oggetto
                    
de.Children.Remove(myDE);
                    myDE.Close();
                    de.CommitChanges();
                    de.Close();
                    search.Dispose();
                    
return true;
                }
                search.Dispose();
                
return false;

            }
            
catch (Exception ex)
            {
                
return false;
            }
        }

        
#endregion

        public static bool 
resetPassword(string nome, string pwd, string
objectClass)
        {
            
try
            
{
                DirectorySearcher search = 
new DirectorySearcher();
                search.SearchRoot = de;
                search.Filter = "(&(objectClass=" + objectClass + ")(" + nome + "))"; ;
                SearchResult result = search.FindOne();

                
if (result != null)
                {
                    
//recupero l'oggetto
                    
DirectoryEntry usr = result.GetDirectoryEntry();

                    usr.AuthenticationType = AuthenticationTypes.Secure;
                    
object[] password = new object[] { pwd };
                    
object ret = usr.Invoke("SetPassword", password);
                    usr.CommitChanges();
                    usr.Close();
                    search.Dispose();
                    
return true;
                }
                search.Dispose();
                
return false;
            }
            
catch (Exception ex)
            {
                
return false;
            }

        }

        
#region Funzioni varie

        static void 
SettaProprieta(DirectoryEntry myDE, string[] setProperties, string[] valProperties)
        {
             
//setto le proprietà
                
for(int i=0;i                    SetProperty(myDE, setProperties[i], valProperties[i]);
        }

        
static string SetSecurePassword()
        {
            
return "test123";
        }

        
static void SetPassword(string path)
        {
            DirectoryEntry usr = 
new DirectoryEntry();
            usr.Path = path;
            usr.AuthenticationType = AuthenticationTypes.Secure;
            
object[] password = new object[] { SetSecurePassword() };
            
object ret = usr.Invoke("SetPassword", password);
            usr.CommitChanges();
            usr.Close();
        }

        
static void SetProperty(DirectoryEntry de, string PropertyName, string
PropertyValue)
        {
            
if (PropertyValue != null)
            {
                
if (de.Properties.Contains(PropertyName))
                {
                    de.Properties[PropertyName][0] = PropertyValue;
                }
                
else
                
{
                    de.Properties[PropertyName].Add(PropertyValue);
                }
            }
        }

        
#endregion

    
}
}