Archive for Aprile, 2007

Apr 30 2007

Sincronizzare l’ora di un DC 2003 con una fonte esterna

Published by Lorenzo under Networking, Server, Windows Server

Se si vuole sincronizzare l’ora del nostro domain controller (DC) con un time server esterno per avere sempre l’ora corretta impostata su tutto il dominio, i passi da compiere sono pochi e semplici. La sincronizzazione avviene per mezzo del protocollo NTP, che serve proprio a questo scopo.

Per sincronizzare l’ora del server, basta digitare questi due semplici comandi:

w32tm /config /syncfromflags:manual /manualpeerlist:time.ien.it,www.clock.org
w32tm /config /update

Da notare l’ultimo parametro del primo comando, /manualpeerlist, dove di seguito sono indicati due time server (time.ien.it e www.clock.org) tramite i quali sincronizzare la nostra rete locale, o meglio, si sincronizza l’ora del server, il quale a sua volta funge da time server per i client della rete.

One response so far

Apr 28 2007

Scaricare posta da server POP3 con Exchange Standard

Exchange Server in edizione Standard ha il problema di non poter scaricare mail da server POP3 per poi recapitarle alle caselle di posta locali, poiché questa versione non ha un connettore POP3, presente invece nella versione Small Business di Exchange. Per ovviare a questo problema, esistono diversi connettori POP3 per Exchange, ma, per quel che ho visto io, sono tutti a pagamento. Se non si vogliono spendere altri soldi per acquistare un connettore POP3 (per quanto diversi connettori non hanno certo importi proibitivi) e si ha un’altro PC a disposizione, è possibile installare hMailServer, un mail server open source per Windows dall’interfaccia semplice e funzionale, e che permette di scaricare la posta elettronica da un server POP3 e di inoltrarla all’indirizzo desiderato sul server Exchange. Detto così è semplice, e in effetti non è una soluzione molto complicata da utilizzare, ma bisogna prestare un po’ di attenzione a ciò che si fa.

Dando per scontato di avere Exchange Standard 2003 funzionante e correttamente configurato, dovremo installare hMailServer sull’altra macchina Windows (meglio un Windows Server, ovviamente se dobbiamo installare una macchina "solo" per quello scopo, conviene acquistare un connettore POP3), la cui installazione non è complicata ed è spiegata piuttosto bene nella documentazione presente sul sito di hMailServer. Tenere presente che hMailServer ha bisogno di un database di appoggio, che può essere MySQL o SQL Server (la stessa installazione di hMailServer può installare una propria versione minimale di MySQL, personalmente preferisco installarmi autonomamente MySQL).

Dopo aver installato hMailServer, va creato il dominio della posta; è consigliabile scegliere un nome di dominio differente sia dal dominio "ufficiale" di posta elettronica sia dal dominio Active Directory, e quindi, sotto il cappello di questo dominio, vanno create le caselle di posta elettronica, una per ogni casella accessibile sul server POP3 da cui dobbiamo scaricare la posta.

Per ogni casella di posta creata in hMailServer, dovremo andare nella scheda "Account esterni", cliccare sul pulsante "Aggiungi" ed inserire le informazioni relative a server POP3, nome utente e password - parametri che vengono forniti dal fornitore del servizio - inoltre, bisogna indicare ogni quanti minuti si scaricheranno i messaggi dal server e se si vogliono cancellare o meno i messaggi sul server POP3; inserite queste impostazioni, bisogna indicare a quale indirizzo vanno inoltrati tutti i messaggi ricevuti sulla casella di posta definita su hMailServer andando sulla scheda "Inoltro", in cui bisogna indicare l’indirizzo al quale inviare i messaggi. Qui bisogna prestare particolare attenzione alla situazione un po’ particolare: su Exchange sono definite le caselle con indirizzo di posta primario quello "ufficiale" corrispondente al dominio aziendale - ad esempio azienda.it - quindi, la policy predefinita per gli indirizzi di posta sarà "@azienda.it"; in tal caso, se su hMailServer inoltriamo le mail verso gli indirizzi di posta "@azienda.it", queste verranno di nuovo ricevute sul server di posta del nostro fornitore di servizio, ed hMailServer le riscaricherà, creando un circolo vizioso che porterà in un tempo più o meno breve alla saturazione del servizio. A questo punto abbiamo due soluzioni:

  1. creare per ogni utente di Active Directory un indirizzo di posta secondario (e non predefinito) che termina con il dominio definito in AD stessa (ad esempio, @azienda.lan) ed inoltrare le mail verso quest’indirizzo;
  2. creare una zona azienda.it sul DNS del domain controller e definire come record MX del dominio il server Exchange.

Se seguiamo la soluzione numero 1), dovremo definire nella scheda "Inoltro" di ogni casella di hMailServer l’indirizzo di posta corrispondente all’utente e che termina con "@azienda.lan", se invece seguiamo la soluzione numero 2), utilizzeremo come indirizzo di inoltro gli indirizzi di posta "ufficiali" (@azienda.it), avendo cura di impostare come server DNS del server hMailServer l’indirizzo IP del domain controller, cosa che si deve fare in ogni caso. Personalmente preferisco la soluzione numero 1), poiché in questo modo si evita di far confusione con gli indirizzi, identici in tutte le situazioni, mentre utilizzando indirizzi "@azienda.lan", la parte amministrativa è più impegnativa ma le due situazioni sono ben distinte, senza contare che così facendo non si va ad impiastricciare il DNS di Active Directory, particolare non trascurabile. L’utilizzo di hMailServer come connettore POP3 presenta un vantaggio da prendere in considerazione, cioé il fatto che è possibile mantenere il messaggio nella cartella di hMailServer, in questo modo si ha una copia di tutti i messaggi ricevuti, cosa utile in caso di disastri con il server Exchange, anche se ovviamente la cosa migliore è avere una buona strategia di backup.

No responses yet

Apr 25 2007

Creare un firewall basilare con iptables

E’ ormai una pratica consolidata, in una rete aziendale, quella di avere un firewall perimetrale attraverso cui passa tutto il traffico in uscita della rete locale, e che regola il traffico in arrivo dall’esterno. La situazione ideale è quella di permettere il traffico in uscita verso Internet e di bloccare tutto il traffico in ingresso da Internet ad eccezione delle risposte alle richieste generate all’interno della rete locale, poi ovviamente succede sempre che devi aprire una porta per il tal servizio, poi l’altro vuole l’accesso remoto, quindi magari pensi che ci starebbe bene una VPN, ecc…

Esistono diversi firewall hardware che svolgono ottimamente questo compito, ma se abbiamo già disponibile un vecchio PC con due schede di rete, possiamo costruirci in modo autonomo un firewall utilizzando una qualsiasi distribuzione Linux. Un’ottima distribuzione da utilizzare per questo scopo è una Debian con installato solamente il sistema di base, infatti tutto ciò che serve per gestire il firewall è compreso nel kernel e più precisamente nel componente Netfilter, che permette appunto di gestire firewall e natting sulla propria macchina Linux tramite diverse regole che vengono definite dall’amministratore tramite il programma iptables.

Iptables raggruppa logicamente i pacchetti in transito sul firewall in base al loro "comportamento" e li suddivide in tre catene generali: INPUT (i pacchetti in ingresso), OUTPUT (i pacchetti in uscita) e FORWARD (i pacchetti in transito tra una scheda di rete e l’altra), quindi, all’interno di queste tre catene, è possibile regolare il traffico di rete in modo anche molto sofisticato. Nel nostro caso invece dovremo semplicemente creare un firewall e non avremo bisogno di un elevato grado di sofisticazione.

Il nostro firewall si posiziona tra la rete locale ed il router Internet che avrà un indirizzo IP pubblico, per cui, il firewall avrà un’interfaccia di rete chiamata eth0 con un indirizzo IP valido sulla LAN, ed un’interfaccia di rete eth1 connessa direttamente col router e con un indirizzo IP pubblico assegnato in grado di comunicare con il router; a questo punto possiamo cominciare con la definizione delle regole del nostro firewall.

Per farlo, creiamo un piccolo script che posizioniamo nella directory /etc/default/ (in realtà penso si possa posizionare più o meno ovunque, io lo metterei comunque dentro /etc) chiamato semplicemente firewall (o comunque lo vogliamo chiamare), quindi lo rendiamo eseguibile e lo andiamo ad editare:

# touch /etc/default/firewall
# chmod 755 /etc/default/firewall
# nano /etc/default/firewall

Come primo passo, dobbiamo abilitare il "routing" tra le due schede di rete, scrivendo all’interno del file l’istruzione

echo 1 > /proc/sys/net/ipv4/ip_forward # abilita il routing tra le due schede di rete

Ora dobbiamo cancellare qualsiasi altra impostazione precedente data a Netfilter e specificare il comportamento predefinito delle tre catene principali:

iptables -F #cancella le impostazioni delle tre catene principali
iptables -X #cancella eventuali catene personalizzate
iptables -P INPUT DROP #rifiuta le connessioni in ingresso
iptables -P OUTPUT DROP #rifiuta le connessioni in uscita
iptables -P FORWARD DROP #rifiuta le connessioni in transito

Trattandosi di un firewall, dobbiamo grossolanamente specificare che le connessioni in uscita sono abilitate mentre non lo sono quelle in ingresso ed in transito, per evitare che le connessioni richieste dalla rete Internet verso la rete LAN possano essere accettate; in questo modo però non sono accettate nemmeno le richieste di connessione dalla rete LAN verso il firewall, ed anche se fossero accettate, non riuscirebbero ad arrivare all’interfaccia eth1 a causa del comportamento predefinito della catena FORWARD, si tratta quindi di raffinare il comportamento del firewall. Inoltre, in questo caso, blocchiamo anche le connessioni in uscita, che non è quel che ci serve, ma come politica predefinita è più sicura, poiché se un pacchetto in uscita non sa come comportarsi, viene scartato. Come prima cosa, accettiamo le connessioni in ingresso su eth0 provenienti dalla nostra LAN, non strettamente necessario ma sicuramente molto utile per amministrare il firewall:

iptables -A INPUT -s 192.168.10.0/24 -i eth0 -j ACCEPT #accetta le connessioni in ingresso dalla propria LAN

ora dobbiamo permettere che i pacchetti in transito da eth0 a eth1 non vengano filtrati dal firewall, quindi dobbiamo fare in modo che i pacchetti di ritorno di connessioni generate dalla nostra rete locale possano transitare nella direzione opposta, cioè da eth1 a eth0:

iptables -A FORWARD -s 192.168.10.0/24 -i eth0 -o eth1 -j ACCEPT #permette il transito di pacchetti provenienti dalla nostra rete locale con destinazione il mondo esterno
iptables -A FORWARD -i eth1 -o eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT #consente ai pacchetti di ritorno di transitare da eth1 a eth0 solo se la connessione era stata già stabilita

Così facendo, i client possono accedere ad Internet ma il firewall non può, cosa che non è positiva visto che di tanto in tanto è necessario aggiornare la nostra distribuzione, quindi vanno aggiunte queste due righe, di cui la seconda ha effetto anche per :

iptables -A INPUT -i eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT #consente ai pacchetti generati direttamente dal firewall di tornare indietro
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE #abilita il natting in modo tale che tutti gli IP mittente vengano cambiati con l’IP di eth1

A questo punto, bisogna fare due operazioni, la prima permettere che i pacchetti che arrivano in ingresso su eth0 possano tornare verso la rete locale (operazione necessaria essendo la catena OUTPUT impostata su DROP come comportamento predefinito), quindi, per fare uscire il firewall verso Internet, bisogna che l’interfaccia eth1 sia abilitata in uscita:

iptables -A OUTPUT -d 192.168.10.0/24 -o eth0 -m state –state ESTABLISHED,RELATED -j ACCEPT #consente l’invio dei pacchetti di risposta generati in seguito a richieste della rete locale
iptables -A OUTPUT -o eth1 -j ACCEPT #consente il transito dei pacchetti in uscita da eth1

Ora i nostri client e il nostro firewall sono in grado di navigare, ovviamente però i client dovranno avere come default gateway l’indirizzo IP di eth0 del firewall. Per rendere attive queste impostazioni, è sufficiente lanciare lo script appena creato, il problema è che così facendo le modifiche andrebbero perse al successivo riavvio del firewall, per cui, è possibile richiamare questo script dal file /etc/network/interfaces in modo da applicare le regole di iptables ad ogni riavvio della rete, e quindi ad ogni riavvio del firewall; per farlo, è sufficiente aggiungere al file /etc/network/interfaces questa riga:

pre-up /etc/default/firewall

ed a questo punto abbiamo il nostro firewall pronto per entrare in funzione.

Possiamo vedere un’ultima casistica, e cioè quella dell’apertura di porte al mondo esterno sul nostro firewall. Ad esempio, potrebbe essere utile aprire la porta 22 del nostro firewall per consentirne l’amministrazione tramite SSH, quindi aggiungere la seguente riga al nostro script

iptables -A INPUT -s 1.1.1.1 -i eth0 -p tcp –dport 22 -j ACCEPT #consente l’accesso via SSH al nostro firewall esclusivamente all’indirizzo IP 1.1.1.1

che consente di accedere ad SSH sul firewall solo all’indirizzo IP 1.1.1.1, se limitare l’accesso SSH per indirizzo IP non è possibile, allora va levata l’opzione -s.

AGGIORNAMENTO

Questa configurazione dà alcuni problemi se si cerca di iniziare una sessione FTP dall’interno della nostra rete locale verso un server FTP esterno, in particolare, connessione ed autenticazione funzionano senza problemi, ma non si riesce ad aprire la sessione dati col server FTP; per ovviare a questo inconveniente, basta mettere nel nostro script contenente le regole di iptables l’istruzione:

modprobe ip_nat_ftp

a questo punto basta far ripartire lo script e sarà possibile effettuare il normale trasferimento di file via FTP.

Link utili
http://guide.debianizzati.org/index.php/Condividere_la_connessione_a_internet
http://it.wikipedia.org/wiki/Netfilter/iptables

2 responses so far

Apr 22 2007

Regolare l’accesso di software in Rete con Squid

In una rete locale aziendale un grosso problema può essere quello di impedire che gli utenti della rete utilizzino programmi che sfruttano la rete Internet per scopi non attinenti con l’attività lavorativa, e che soprattutto possono creare problemi legali o d’immagine all’azienda. Ad esempio, pensiamo a quei programmi come i software di instant messagging (che comunque possono essere anche usati a scopo lavorativo), e soprattutto ai programmi di file sharing, la cui utilità in campo lavorativo è nulla, e che anzi tendono a saturare la banda disponibile sulla connessione Internet.

Per ovviare a questi problemi, è possibile utilizzare un server proxy, in particolare gli esempi esposti in seguito sono stati testati con un client Windows XP e con un server Windows Server 2003 con installato Squid 2.6. Per conseguire i nostri scopi, dobbiamo configurare i client in modo tale che non accedano alla rete tramite un router, ma esclusivamente tramite un proxy; ciò è possibile configurando in modo opportuno un server DHCP e impedendo tramite policy che gli utenti possano modificare le loro impostazioni TCP/IP. Purtroppo questo passo si rende necessario in quanto su Windows non è possibile far agire Squid come transparent proxy, così come invece accade su Linux.

Già facendo questi pochi passi, si eliminano gran parte delle connessioni indesiderate verso Internet, infatti la maggior parte degli utenti non sa nemmeno cos’è un server proxy e non è quindi in grado di impostare la connessione di un software verso Internet utilizzando un server proxy. Queste considerazioni però non portano molto lontano, poiché bisogna sempre considerare la possibilità di avere a che fare con un utente smanettone, che ad esempio, potrebbe sapere che programmi come Emule possono usare un server proxy per la connessione (che comunque in questa situazione non avverrà mai con ID alto), e potrebbe essere a conoscenza del fatto che Emule funziona anche in modalità standalone, e che quindi può funzionare anche senza essere installato sulla macchina e in assenza dei privilegi di amministratore.

Con Squid ho testato (solo in un ambiente di test, finora) con successo due metodi, uno che funziona anche se non molto flessibile, l’altro invece molto più adattabile a diverse situazioni. Il primo metodo consiste nell’abilitare solamente certe porte ad uscire verso il Web su protocollo HTTP, tramite una ACL simile a questa:

acl porteConcesse port 21 80 443

Questa ACL descrive quelle connessioni a server che rispondono sulle porte 21, 80 e 443 (tipicamente FTP e navigazione Web), per cui, dovremo specificare che le uniche connessioni concesse sono quelle verso le porte citate in precedenza, utilizzando questa regola d’accesso:

http_access deny !porteConcesse

che significa "nega tutto ciò che si connette su porte diverse da quelle indicate nella ACL porteConcesse". In questo caso, applicazioni come Emule non possono connettersi ai vari server che tipicamente rispondono su porte diverse da quelle indicate e superiori alla 1024, mentre con queste impostazioni continua ad essere accessibile la rete Messenger per l’utilizzo di Windows Live Messenger.

Un altro metodo consiste nell’intercettare gli user-agent utilizzati dai vari software che si connettono via proxy, ed abilitare solo quei software che contengono nella stringa identificativa dello user-agent solo determinate parole; ad esempio se prendiamo in esame la seguente ACL

acl userAgent browser Mozilla

notiamo che sono definiti tutti quei software che si identificano con uno user-agent che contiene la parola Mozilla al suo interno, come i browser Internet Explorer e Firefox. Prendendo quindi spunto da questa ACL, andiamo a definire una regola d’accesso che consente agli utenti della rete locale di connettersi verso Internet solamente con programmi con user-agent contenenti la sottostringa Mozilla:

http_access deny !useragent

In questo modo Emule continua a non connettersi, mentre continua ad essere possibile la navigazione sul Web; rimane possibile anche connettersi con Windows Live Messenger, poiché anche il suo user-agent contiene la parola Mozilla, per cui, se si vuole evitare questo tipo di connessione, bisogna creare una ulteriore ACL:

acl messenger browser Messenger

con la conseguente regola d’accesso che vieta la connessione alla rete Messenger, regola d’accesso che dev’essere posizionata prima della precedente regola d’accesso legata alla acl userAgent:

http_access deny messenger

In questo modo, anche l’accesso a Messenger è vietato, ed inoltre, si può gestire con una buona flessibilità l’accesso al Web di diverse altre applicazioni. Da notare comunque che Squid è esclusivamente un proxy HTTP ed FTP, e che quindi consente l’accesso ad Internet solamente a quei software in grado di usare i due protocolli HTTP ed FTP; tanto per fare un esempio, non sarà possibile utilizzare nella rete locale programmi come Outlook, Outlook Express o Thunderbird che cercano di scaricare o inviare posta tramite SMTP o POP3, ma ci dovrà essere un server di posta elettronica posto all’interno della rete locale.

No responses yet

Apr 11 2007

Disabilitare autoelezione a master browser

In una rete con un dominio Active Directory, è possibile che sul domain controller appaiano messaggi che notificano il tentativo di un client di autoeleggersi Master Browser ai danni del controllore di dominio; il master browser è quel computer che gestisce la lista degli host presenti sulla rete locale, e problemi col master browser si traducono in possibili problemi nello sfogliare le risorse di rete. Il messaggio che compare nel visualizzatore eventi ha id evento 8003 e origine "Mrxsmb", per altri dettagli su questo errore vedere sul sito eventid.net.

Una delle possibili soluzioni consiste nell’impedire che un client cerchi di autoeleggersi master browser, e ciò è possibile intervenendo sul registro di sistema, precisamente impostando il valore delle voce HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\Services\ Browser\ Parameters\ MaintainServerList a FALSE; per farlo, è naturalmente possibile modificare il registro a mano, ma trovandoci in una rete locale potremmo anche utilizzare un file batch, posizionato sul server in modo che sia utilizzabile da tutti i PC della rete locale che eventualmente presentano questo problema (tenere presente che il seguente batch è applicabile solo sui sistemi da Windows XP in avanti). Utilizzeremo quindi il comando REG per togliere ed aggiungere la voce di registro col valore modificato; sarebbe stato più logico modificare direttamente il valore nel registro, ma credo che non esista un modo di modificare in un solo passaggio il valore di una voce di registro. Inoltre, la prima istruzione del file batch servirà per fare un salvataggio della chiave di registro coinvolta, operazione molto utile per poter ripristinare la chiave di backup originaria in caso di problemi. Di seguito le poche righe del batch:

reg save HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser\Parameters c:\browserParameters.hiv
reg delete HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser\Parameters /v MaintainServerList /F
reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser\Parameters /v MaintainServerList /t REG_SZ /d FALSE

Esaminiamo il batch: la prima riga, come scritto, consente di salvare la chiave indicata nel file c:\browserParameters.hiv, ripristinabile col comando "reg restore"; la seconda riga, cancella la voce MaintainServerList (che è richiamata con l’opzione /v) nella chiave indicata, forzando la cancellazione con l’opzione /F; la terza riga aggiunge la voce MaintainServerList nella chiave indicata, specificando, oltre alla voce, il tipo di dati della voce stessa con l’opzione /t, ed il valore da assegnare alla voce con l’opzione /d, valore che deve essere racchiuso tra virgolette se composto da più parole.

Il batch è tutto qui, l’unica cosa da tenere presente è che il batch andrebbe eseguito con i privilegi di amministratore della macchina.

No responses yet

Apr 10 2007

Importare dati da file CSV ad un DB utilizzando ASP

Può capitare di dover importare dei dati in un database di un’applicazione partendo da un file Excel. In questi casi, può essere una buona soluzione convertire il file di Excel in un file di testo (ad esempio un file CSV) ed importare i dati presenti nel file di testo in una o più tabelle del nostro DB. In questo caso prendiamo in esame un’applicazione ASP che si poggia su un database MySQL, con il file di dati trasformato da Excel in CSV, coi campi delimitati dal ";". In MySQL esiste un comando, load data infile, che permette appunto di importare file di testo in una tabella a scelta, peccato che questa procedura non si adatti a tutte le situazioni, ad esempio, non funziona quando non si ha un accesso diretto al server Web, oppure se il file contiene dati che non vanno su un’unica tabella ma che, essendo un file di testo una tabella di un database "piatto", non ha un minimo di normalizzazione, da ricreare in fase di importazione.

Una situazione tipica può essere quella di un file di testo contenente una lista di dipendenti e delle relative aziende di appartenenza, infatti esistendo più dipendenti per ogni azienda, le informazioni relative ad ogni singola azienda vengono ripetute diverse volte, e quindi questi dati non possono essere importati in una singola tabella, ma dovranno essere posti in due tabelle, aziende e dipendenti, in relazione uno a molti; in questo caso, non può essere usata l’istruzione load data infile, poiché, a quanto ne so io, questo comando non supporta l’inserimento in due tabelle distinte. Intanto vediamo da quali campi è composto il file CSV e come questi campi verranno distribuiti nelle due tabelle "Dipendenti" e "Aziende":

File CSV

Cognome;Nome;Via;CAP;Localita;CodiceFiscale;NomeAzienda;
ViaAzienda;CAPAzienda;LocalitaAzienda;PartitaIVA

Tabella Dipendenti

idDipendente int not null auto_increment primary key
cognome varchar(30) not null
nome varchar(30) not null
via varchar(60)
CAP varchar(5)
localita varchar(60)
codiceFiscale varchar(16)
idAzienda int not null

Tabella Aziende

idAzienda int not null auto_increment primary key
nomeAzienda varchar(60) not null
viaAzienda varchar(60)
CAPAzienda varchar(5)
localitaAzienda varchar(60)
partitaIVA varchar(11)

A questo punto vediamo come impostare il codice vbscript della pagina ASP. Per prima cosa bisognerà aprire il file di testo che quindi dovrà essere posto in una cartella visibile del nostro server Web, utilizzando l’oggetto FileSystemObject per aprire il file e per scorrerlo; i primi dati a dover essere letti sono quelli relativi alle aziende, visto che poi dovrò associare i dipendenti all’azienda di appartenenza. Di seguito la prima parte del codice:

<%
Dim percorso, fileFSO, apriFile, rigaFile, arrRiga
‘dichiarazione delle variabili
Dim vNomeAzienda, vViaAzienda, vCAPAzienda, vLocalitaAzienda, vPartitaIVA
Dim conn, importTempAziende, importAziende, truncateTempAziende, queryAzienda, rsAzienda, importIscritti
Dim vidAzienda, vCognome, vNome, vVia, vCAP, vLocalita, vCodiceFiscale, vPartitaIVAAzienda
set conn = server.CreateObject("ADODB.Connection")
‘creazione dell’oggetto di connessione al database
conn.ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=localhost; DATABASE=prova; UID=prova; PWD=prova; OPTION=3" ‘opzioni di connessione al DB
conn.Open ‘apertura della connessione al DB
percorso = Server.MapPath("filecsv.csv") ’si specifica il percorso relativo del file da aprire. Server.MapPath serve per convertire un percorso virtuale in un percorso fisico
set fileFSO = server.CreateObject("Scripting.FileSystemObject") ‘crea una nuova istanza dell’oggetto FileSystemObject
if fileFSO.FileExists(percorso) then ‘utilizzo - all’interno di una struttura condizionale if… then… else - il metodo FileExists per verificare se il file esiste
set apriFile = fileFSO.openTextFile(percorso, 1) ‘utilizzo il metodo openTextFile per aprire il file csv in sola lettura (il numero 1 significa l’apertura del file in sola lettura)
do until apriFile.AtEndOfStream ‘uso un ciclo per leggere riga per riga il file fino ad arrivare alla fine tramite la proprietà AtEndOfStream
rigaFile = apriFile.ReadLine ‘uso il metodo ReadLine per leggere una riga del file di testo e trasformarla in stringa
arrRiga = split(rigaFile, ";") ‘tramite la funzione split trasformo la stringa ottenuta tramite il metodo ReadLine in un array
vNomeAzienda = arrRiga(6) ‘assegno alla variabile vNomeAzienda il valore relativo al nome dell’azienda pescato nell’array creato precedentemente
vNomeAzienda = replace(vNomeAzienda, "’", "”") ’sostituzione dell’apice con un doppio apice per permettere l’inserimento nella tabella senza problemi
vViaAzienda = arrRiga(7)
vViaAzienda = replace(vViaAzienda, "’", "”")
vCAPAzienda = arrRiga(8)
vLocalitaAzienda = arrRiga(9)
vLocalitaAzienda = replace(vLocalitaAzienda, "’", "”")
vPartitaIVA = arrRiga(10)
%>

Ora abbiamo tutti gli elementi che ci servono per inserire i dati relativi alle aziende in una tabella di transito, infatti non è possibile inserire direttamente i dati nella tabella Aziende, poiché i dati sarebbero duplicati e quindi il database di fatto inutile, quindi di seguito verrà fatto in modo di inserire questi dati nella tabella "transitoAziende", e da qui si prenderanno i dati filtrati in modo da non avere record duplicati per inserirli nella tabella "Aziende".

<%
ImportTempAziende = "INSERT INTO tempAziende (nomeAzienda, viaAzienda, capAzienda, localitaAzienda, partitaIVA) " & _
VALUES (’" & vNomeAzienda & "’, ‘" & vViaAzienda & "’, ‘" & vCAPAzienda & "’, ‘" & vLocalitaAzienda & "’, ‘" & vPartitaIVA & "’)"
‘istruzione di inserimento dei dati prelevati dall’array nella tabella tempAziende
conn.Execute ImportTempAziende ‘esecuzione dell’istruzione SQL precedente
loop ‘termine del ciclo
end if ‘termine struttura condizionale
importAziende = "INSERT INTO aziende (nomeAzienda, viaAzienda, capAzienda, localitaAzienda, partitaIVA) " & _
SELECT nomeAzienda, viaAzienda, capAzienda, localitaAzienda, partitaIVA FROM tempAziende GROUP BY partitaIVA
‘istruzione per filtrare i dati dalla tabella tempAziende ed inserirli nella tabella aziende
truncateTempAziende = "TRUNCATE TABLE tempAziende" ‘istruzione per cancellare i dati di transito presenti all’interno della tabella tempAziende
conn.Execute importAziende ‘esecuzione dell’istruzione SQL definita nella variabile importAziende
conn.Execute truncateTempAziende ‘esecuzione dell’istruzione SQL definita nella variabile truncateTempAziende
set fileFSO = nothing ‘libero la memoria occupata dall’istanza fileFSO
%>

Con le istruzioni precedenti la procedura inserisce, riga per riga, i dati relativi alle aziende presenti nel file CSV nella tabella tempAziende, quindi fa in modo di filtrare i dati dalla tabella tempAziende ed eliminare i record duplicati tramite l’istruzione GROUP BY (utilizzando DISTINCT, se i dati non sono "perfetti", si rischia di non eliminare completamente i duplicati), quindi questi dati filtrati sono inseriti nella tabella aziende tramite un’unica istruzione SQL, "INSERT INTO SELECT"; infine, vengono cancellati i dati dalla tabella tempAziende essendo questi dati di natura temporanea. A questo punto bisogna inserire i dipendenti nella tabella "dipendenti". In primo luogo, dovrò riaprire il file "filecsv.csv" tramite il solito ciclo, ricreare l’array per ogni riga del file csv, ed "estrarre" dall’array i dati relativi ai dipendenti, e la partita IVA dell’azienda corrispondente per poter associare il dipendente all’azienda; come si può vedere, la prima parte del codice è identica alla parte precedente:

<%
set fileFSO = server.CreateObject("Scripting.FileSystemObject") ‘crea una nuova istanza dell’oggetto FileSystemObject
if fileFSO.FileExists(percorso) then ‘utilizzo - all’interno di una struttura condizionale if… then… else - il metodo FileExists per verificare se il file esiste
set apriFile = fileFSO.openTextFile(percorso, 1) ‘utilizzo il metodo openTextFile per aprire il file csv in sola lettura (il numero 1 significa l’apertura del file in sola lettura)
do until apriFile.AtEndOfStream ‘uso un ciclo per leggere riga per riga il file fino ad arrivare alla fine tramite la proprietà AtEndOfStream
rigaFile = apriFile.ReadLine ‘uso il metodo ReadLine per leggere una riga del file di testo e trasformarla in stringa
arrRiga = split(rigaFile, ";") ‘tramite la funzione split trasformo la stringa ottenuta tramite il metodo ReadLine in un array
vCognome = arrRiga(0) ‘assegno alla variabile vCognome il valore relativo al nome dell’azienda pescato nell’array creato precedentemente
vCognome = replace(vCognome, "’", "”") ’sostituzione dell’apice con un doppio apice per permettere l’inserimento nella tabella senza problemi
vNome = arrRiga(1)
vNome = replace(vNome, "’", "”")
vVia = arrRiga(2)
vVia = replace(vVia, "’", "”")
vCAP = arrRiga(3)
vLocalita = arrRiga(4)
vLocalita = replace(vLocalita, "’", "”")
vCodiceFiscale = arrRiga(5)

vPartitaIVAAzienda = arrRiga(10)
%>

Ottenuti i dati che ci servono, per ogni dipendente bisogna ricavare l’azienda di appartenenza, nel dettaglio significa fare una query sulla tabella Aziende cercando l’idAzienda corrispondente alla Partita IVA ricavata in precedenza. Se si fosse impostata la partita IVA come chiave primaria non sarebbe stato necessario dover fare questa query, ma in alcuni casi i dati che vengono forniti non sono poi così ben bonificati… Una volta ottenuto l’ID dell’azienda, è possibile inserire il dipendente nella tabella Dipendenti completo di Foreign Key, indispensabile per poter mettere in relazione la tabella Aziende con la tabella Dipendenti.

<%
queryAzienda = "SELECT idAzienda FROM aziende WHERE PI = ‘" & vPartitaIVAAzienda & "’" ‘definizione della query per ottenere l’idAzienda in base alla Partita IVA
set rsAzienda = server.CreateObject("ADODB.Recordset") ‘istanziazione recordset
rsAzienda.Open queryAzienda, conn, 3, 3 ‘apertura recordset
vidAzienda = rsAzienda("idAzienda") ‘assegnazione dell’ID dell’azienda alla relativa variabile
importIscritti = "INSERT INTO iscritti (cognome, nome, via, CAP, localita, codiceFiscale, idAzienda)  VALUES " & _
(’" & vCognome & "’, ‘" & vNome & "’, ‘" & vVia & "’, ‘" & vCAP & "’, ‘" & vLocalita & "’, ‘" & vCodiceFiscale & "’, " & vidAzienda & ")"
‘definizione dell’istruzione di inserimento dipendente
conn.Execute importIscritti ‘esecuzione dell’inserimento dipendente
loop ‘termine del ciclo
end if ‘termine struttura condizionale
set fileFSO = nothing ‘libero la memoria occupata dall’istanza fileFSO
rsAzienda.close ‘chiusura del recordset
set rsAzienda = nothing ‘libero memoria
conn.close ‘chiusura connessione al database
set conn = nothing ‘libero memoria
%>

Ora sono inseriti anche i dipendenti con indicata anche la loro azienda d’appartenenza. Siccome non sono esattamente un esperto di questi argomenti, ho affrontato la questione a modo mio, quindi molto probabilmente esistono modi più brillanti di risolvere il problema, nel mio caso questa soluzione ha l’indubbio pregio di funzionare. Chi volesse segnalare metodi migliori per affrontare la situazione può farlo tramite la pagina dei contatti.

No responses yet

Apr 07 2007

Regole Site and Content Rules su ISA Server 2000

Published by Lorenzo under Firewall, Networking, Server, Sicurezza

Site and Content Rules in ISA Server 2000 consente di definire le applicazioni ed i siti che è possibile utilizzare durante la propria navigazione sul Web, ma soprattutto, è possibile applicare queste regole ad utenti e/o gruppi definiti in Active Directory, rendendo possibile una gestione delle autorizzazioni semplice ed al tempo stesso efficiente. Ad esempio, è possibile creare una regola che impedisca ad un determinato gruppo di utenti di scaricare file video o audio, così com’è possibile limitare un altro gruppo di utenti consentendo loro di visitare solamente siti con determinati URL.

Su ISA Server 2000 però, quando si crea una regola in Site and Content Rules, bisogna prestare attenzione alle regole già create, infatti, a differenza di ISA Server 2004, non si può indicare un ordine preciso di applicazione, ma è ISA Server 2000 ad applicare un suo ordine specifico, in particolare:

  1. regole di negazione (deny) applicate ad ogni richiesta (accesso anonimo)
  2. regole di approvazione (allow) applicate ad ogni richiesta (accesso anonimo)
  3. regole di negazione (deny) applicate ad utenti o gruppi
  4. regole di approvazione (allow) applicate ad utenti o gruppi

Da qui si può capire che, se ho una regola che consente di navigare sul Web a chiunque, e successivamente creo una regola che impedisce ad un gruppo di utenti di navigare su alcuni siti, quest’ultima regola non verrà applicata, in quanto in precedenza avevo già consentito la navigazione anonima a tutti gli utenti. Per ovviare al problema e consentire l’applicazione della regola di negazione, dovrò cambiare la regola in cui consento la navigazione indiscriminata consentendo l’accesso Web solamente agli utenti autenticati (ad esempio il gruppo Domain Users).

No responses yet