Linux
Inviato da Matteo Mattei / 17th maggio 2012
Se avete bisogno di configurare un server svn su Linux con autenticazione tramite LDAP, webdav ed inserire specifiche restrizioni su determinate cartelle, potete seguire le seguenti istruzioni.
- Uno: dovete installare subversion e apache sul vostro server Linux (ometterò questa parte).
- Two: dovete configurare webdav per accedere ad svn tramite http e configurare l’accesso tramite LDAP.
Assicuratevi di avere i seguenti moduli di apache installati e configurati:
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so
LoadModule authn_alias_module modules/mod_authn_alias.so
Assunzioni:
- Sono solito configurare subversion sotto la directory /srv/svn.
- Gli utenti a cui è permesso di accedere a subversion devono appartenere al gruppo LDAP CN=SVN-AUTHORIZATION,OU=Groups GSO,DC=test,DC=example,DC=com
Modificate il file /etc/apache2/mods-enabled/dav_svn.conf (su Ubuntu, su altre distribuzioni potrebbe essere posizionato altrove) ed assicuratevi di avere le seguenti configurazioni:
<Location /svn/>
# Abilitare svn su webdav
DAV svn
# Impostare il parent path per repositori multipli
SVNParentPath /srv/svn/
# Impostare il tipo di autenticazione
AuthType Basic
# Impostare il nome dell'autenticazione
AuthName "FLR Subversion Repository"
# Impostare il file che conterrà le autorizzazioni (permessi)
AuthzSVNAccessFile /etc/apache2/dav_svn.authz
# Consentire di listare il parent path
SVNListParentPath On
# Utilizzare LDAP per l'autenticazione
AuthBasicProvider ldap
# Il server LDAP è autoritativo (cioè l'autenticazione finale è delegata a LDAP)
AuthzLDAPAuthoritative On
# Utente di bin per LDAP
AuthLDAPBindDN "CN=svnbind,OU=Users OS,DC=test,DC=example,DC=com"
# Password dell'utente di bind per LDAP
AuthLDAPBindPassword mypassword
# LDAP URL
AuthLDAPUrl "ldap://ldap_ip_address:389/DC=test,DC=example,DC=com?sAMAccountName?sub?(&(&(objectClass=user)(objectCategory=person))(memberof=CN=SVN-AUTHORIZATION,OU=Groups GSO,DC=test,DC=example,DC=com))"
# E' necessario un utente valido
Require valid-user
</Location>
Three Create il file dei permessi /etc/apache2/dav_svn.authz
Dovrà avere il seguente contenuto in base alle vostre esigenze:
[groups]
admin = matteo
group1 = user1, user2, user3
group2 = user2
group3 = user4
###################################
[/]
* = r
@admin = rw
###################################
[repository1:/]
* = rw
###################################
[repository2:/]
* =
@admin = rw
@group1 = rw
###################################
[repository3:/]
* =
@admin = rw
@group2 = rw
@group1 = r
###################################
[repository4:/]
* = r
@admin = rw
[repository4:/trunk/sources]
* = r
@admin = rw
@group3 = rw
###################################
Adesso riavviate apache con /etc/init.d/apache2 restart
Quattro: create finalmente i repositori.
Da root impartite i seguenti comandi:
cd /srv/svn
svnadmin create repository1
chown www-data.www-data -R repository1
svnadmin create repository2
chown www-data.www-data -R repository2
svnadmin create repository3
chown www-data.www-data -R repository3
svnadmin create repository4
chown www-data.www-data -R repository4
Siete adesso pronti per utilizzare subversion con account LDAP, webdav e restrizioni su directory personalizzate.
Inviato da Matteo Mattei / 26th novembre 2011
Se state utilizzando PhpMyAdmin insieme ad APC può capitare che abbiate degli errori come questi:
PHP Fatal error: Call to undefined function PMA_log_user() in /usr/share/webapps/phpMyAdmin/libraries/common.inc.php on line 914
PHP Fatal error: Call to undefined function PMA_select_language() in /usr/share/webapps/phpMyAdmin/libraries/auth/cookie.auth.lib.php on line 220
PHP Fatal error: Call to undefined function pma_generate_common_url() in /usr/share/webapps/phpMyAdmin/libraries/header_meta_style.inc.php on line 48
PHP Fatal error: Call to undefined function PMA_DBI_connect() in /srv/http/librolandia.it/test/phpmyadmin/libraries/common.inc.php on line 916
PHP Fatal error: Class 'PMA_Error_Handler' not found in /path/to/phpMyAdmin/libraries/common.inc.php on line 58
PHP Fatal error: Call to undefined function PMA_getenv() in /path/to/phpMyAdmin/libraries/common.inc.php on line 143
Se questo è il vostro caso avrete bisogno di disabilitare APC nella configurazione del virtualhost di PhpMyAdmin:
Alias /phpmyadmin "/usr/share/webapps/phpMyAdmin"
<Directory "/usr/share/webapps/phpMyAdmin">
AllowOverride All
Options FollowSymlinks
Order allow,deny
Allow from all
php_admin_value open_basedir "/srv/:/tmp/:/usr/share/webapps/:/etc/webapps:/usr/share/pear/"
php_admin_value apc.enabled 0
</Directory>
Inoltre modificate il filtro di APC nella sezione [APC] di php.ini:
[APC]
apc.filter="-/usr/share/webapps/phpMyAdmin/.*"
Riavviate Apache e phpMyAdmin dovrebbe a questo punto funzionare regolarmente.
Inviato da Matteo Mattei / 25th ottobre 2011
Questo semplice pezzo di codice mostra come estrarre/decomprimere un’immagine u-boot multi-file creata con il comando mkimage, utilizzando Python. Il formato dell’immagine del file u-boot è abbastanza semplice:
64 byte per l'image header.
4 byte per la dimensione della prima immagine.
4 byte per la dimensione della seconda immagine.
...
4 byte a zero per la terminazione.
immagine1.
immagine2.
...
Dovete anche ricordarvi che ogni immagine deve essere paddata a 4 byte.
#!/usr/bin/env python
import sys
def toNumber(buf):
""" Convert string in number """
size = 0
for b in buf: size=size*256+ord(b)
return size
if len(sys.argv)!=2:
sys.stdout.write('Usage %s uboot_image_file\n' % sys.argv[0])
sys.exit(1)
f = open(sys.argv[1],'rb')
f.seek(64) # skip image header
parts = []
# get file size of all images
while True:
buf = f.read(4)
size = toNumber(buf)
if size==0: break
parts.append(size)
i = 0
for size in parts:
pattern = 'file%d.img' % i
p = open(pattern, 'wb')
buf = f.read(size)
p.write(buf)
p.close()
if size%4 != 0:
# 4 byte padding
f.read(4-(size%4))
i+=1
f.close()
Inviato da Matteo Mattei / 28th agosto 2011
In questi giorni ho iniziato a studiare PySide. Dopo alcuni giorni spesi a leggere un bel po’ di materiale online, ho pensato che un esempio reale potesse essere utile per chi come come me intende cimentarsi con PySide. In questo esempio vi vieme mostrato come potete implementare un segnale custom (MySignal) insieme all’uso dei thread con QThread.
Il codice seguente crea una finestra con due pulsanti: il primo avvia e ferma un thread (MyThread) che lancia un processo il quale stampa sullo standard output della console un punto ogni secondo continuamente. Il secondo bottone vi permette solo di avviare un altro thread (MyLongThread) che stampa un asterisco sullo standard output ogni secondo per 10 secondi e poi esce.
Questo esempio utilizza la versione delle API 2 (introdotta con PyQt 4.5) per connettere i segnali agli slot.
#!/usr/bin/env python2
import sys, time
from PySide.QtGui import *
from PySide.QtCore import *
class MySignal(QObject):
sig = Signal(str)
class MyLongThread(QThread):
def __init__(self, parent = None):
QThread.__init__(self, parent)
self.exiting = False
self.signal = MySignal()
def run(self):
end = time.time()+10
while self.exiting==False:
sys.stdout.write('*')
sys.stdout.flush()
time.sleep(1)
now = time.time()
if now>=end:
self.exiting=True
self.signal.sig.emit('OK')
class MyThread(QThread):
def __init__(self, parent = None):
QThread.__init__(self, parent)
self.exiting = False
def run(self):
while self.exiting==False:
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(1)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self,parent)
self.centralwidget = QWidget(self)
self.batchbutton = QPushButton('Start batch',self)
self.longbutton = QPushButton('Start long (10 seconds) operation',self)
self.label1 = QLabel('Continuos batch')
self.label2 = QLabel('Long batch')
self.vbox = QVBoxLayout()
self.vbox.addWidget(self.batchbutton)
self.vbox.addWidget(self.longbutton)
self.vbox.addWidget(self.label1)
self.vbox.addWidget(self.label2)
self.setCentralWidget(self.centralwidget)
self.centralwidget.setLayout(self.vbox)
self.thread = MyThread()
self.longthread = MyLongThread()
self.batchbutton.clicked.connect(self.handletoggle)
self.longbutton.clicked.connect(self.longoperation)
self.thread.started.connect(self.started)
self.thread.finished.connect(self.finished)
self.thread.terminated.connect(self.terminated)
self.longthread.signal.sig.connect(self.longoperationcomplete)
def started(self):
self.label1.setText('Continuous batch started')
def finished(self):
self.label1.setText('Continuous batch stopped')
def terminated(self):
self.label1.setText('Continuous batch terminated')
def handletoggle(self):
if self.thread.isRunning():
self.thread.exiting=True
self.batchbutton.setEnabled(False)
while self.thread.isRunning():
time.sleep(0.01)
continue
self.batchbutton.setText('Start batch')
self.batchbutton.setEnabled(True)
else:
self.thread.exiting=False
self.thread.start()
self.batchbutton.setEnabled(False)
while not self.thread.isRunning():
time.sleep(0.01)
continue
self.batchbutton.setText('Stop batch')
self.batchbutton.setEnabled(True)
def longoperation(self):
if not self.longthread.isRunning():
self.longthread.exiting=False
self.longthread.start()
self.label2.setText('Long operation started')
self.longbutton.setEnabled(False)
def longoperationcomplete(self,data):
self.label2.setText('Long operation completed with: '+data)
self.longbutton.setEnabled(True)
if __name__=='__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Per ulteriori informazioni potete dare un’occhiata ai seguenti link:
Documentazione sul modulo QThread: http://doc.qt.nokia.com/latest/qthread.html
Segnali e Slot di PySide: http://developer.qt.nokia.com/wiki/Signals_and_Slots_in_PySide
PyQt Api 2 con PySide: http://www.pyside.org/docs/pseps/psep-0101.html
Inviato da Matteo Mattei / 30th luglio 2011
Il seguente codice PHP può essere utilizzato per exportare una tabella MySQL in formato CSV e quindi facilmente modificabile con MS Excel.
$link = mysql_connect($mysql_host,$mysql_user,$mysql_pass) or die('Could not connect: '.mysql_error());
mysql_select_db($mysql_db,$link) or die('Could not select database: '.$mysql_db);
$query = "SELECT * FROM $tablename ORDER BY id";
$result = mysql_query($query) or die("Error executing query: ".mysql_error());
$row = mysql_fetch_assoc($result);
$line = "";
$comma = "";
foreach($row as $name => $value)
{
$line .= $comma . '"' . str_replace('"', '""', $name) . '"';
$comma = ";";
}
$line .= "\n";
$out = $line;
mysql_data_seek($result, 0);
while($row = mysql_fetch_assoc($result))
{
$line = "";
$comma = "";
foreach($row as $value)
{
$line .= $comma . '"' . str_replace('"', '""', $value) . '"';
$comma = ";";
}
$line .= "\n";
$out.=$line;
}
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=listino.csv");
echo $out;
exit;
Inviato da Matteo Mattei / 27th luglio 2011
Se avete accesso da root ma avete bisogno di eseguire alcuni applicazioni o script con credenziali di altri utenti potete semplicemente farlo direttamente dalla shell con:
su - username -c "command to execute"
Ma se invece avete bisogno di eseguire tale programma dalla vostra applicazione C/C++ avete bisogno di seguire questa procedura:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
int main(int argc, char* argv[])
{
if(argc != 3)
{
printf("Usage: %s [USERNAME] [COMMAND]\n",argv[0]);
return 1;
}
char *env[16];
char envc[16][64];
struct passwd *pw = getpwnam(argv[1]);
if(pw==NULL)
{
printf("User %s does not exists!\n",argv[1]);
return 1;
}
sprintf(env[0]=envc[0],"TERM=xterm");
sprintf(env[1]=envc[1],"USER=%s",pw->pw_name);
sprintf(env[2]=envc[2],"HOME=%s",pw->pw_dir);
sprintf(env[3]=envc[3],"SHELL=%s",pw->pw_shell);
sprintf(env[4]=envc[4],"LOGNAME=%s",pw->pw_name);
sprintf(env[5]=envc[5],"PATH=/usr/bin:/bin:/opt/bin");
env[6]=0;
initgroups(argv[1],pw->pw_gid);
setgid(pw->pw_gid);
setuid(pw->pw_uid);
execve(argv[2],NULL,env);
return 0;
}
Potete compilare ed eseguire il codice in questo modo:
[root@barracuda ~]# gcc mysu.c -o mysu
[root@barracuda ~]# id
uid=0(root) gid=0(root) gruppi=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),19(log)
[root@barracuda ~]# ./mysu matteo /bin/bash
[matteo@barracuda /root]$ id
uid=1000(matteo) gid=100(users) groups=100(users),3(sys),10(wheel),14(uucp),91(video),92(audio),93(optical),95(storage),96(scanner),97(camera),98(power),108(vboxusers)
Lo stesso risultato si puo’ ottenere anche in Python con pochissimo sforzo:
#!/usr/bin/env python
import sys,pwd,os
pw = pwd.getpwnam(sys.argv[1])
os.initgroups(sys.argv[1],pw.pw_gid)
env={"TERM":"xterm","USER":pw.pw_name,"HOME":pw.pw_dir,"SHELL":pw.pw_shell,"LOGNAME":pw.pw_name,"PATH":"/usr/bin:/bin:/opt/bin"};
os.setgid(pw.pw_gid);
os.setuid(pw.pw_uid);
os.execve(sys.argv[2],[],env);
Inviato da Matteo Mattei / 10th giugno 2011
Qualche giorno fa ho speso un pò di tempo per provare a ridimensionare una macchina virtuale con sopra Ubuntu 11.04 con la partizione di root formattata con il filesystem EXT4.
Il problema principale è che la versione attuale di VMware tools (8.4.6, build-385536) non supporta lo shrink su filesystem ext4. se infatti digitate sudo vmware-toolbox, la vostra partizione di root è formattata in ext4 e provate ad eseguire uno shrink, otterrete un messaggio di errore di questo tipo.

Tuttavia c’è un trucco per snellire l’immagine vmdk finale.
Eseguite questo comando da dentro la shell del sistema guest:
sudo dd if=/dev/zero of=/zero.raw bs=20480
rm -f /zero.raw
Poi, spengete la macchina virtuale e scaricate il tool vdiskmanager da VMware website.
A questo punto eseguite vmware-vdiskmanager con il parametro -k:
vmware-diskmanager.exe -k /path/to/image.vmdk
Questa operazione prenderà un pò di tempo ma alla fine otterrete un’immagine vmdk considerevolmente più piccola.
Inviato da Matteo Mattei / 22nd marzo 2011
Oggi insieme al mio amico Nicola stavo cercando in rete l’implementazione dell’algoritmo X9.19 in python. Purtroppo non l’abbiamo trovato da nessuna parte per cui ce lo siamo fatti da soli:
#!/usr/bin/env python2
import Crypto.Cipher.DES as des
import Crypto.Cipher.DES3 as des3
def mac_x919(key,data):
while len(data) % 8 != 0:
data += '\x00'
des_key1 = des.new(key[0:8],des.MODE_CBC)
des_key2 = des.new(key[0:8],des.MODE_ECB)
buf = des_key1.encrypt(data)
buf = buf[len(buf)-8:]
buf = des_key2.decrypt(buf)
des3_key = des3.new(key,des3.MODE_ECB)
buf = des3_key.encrypt(buf)
return buf[0:4]
mac = mac_x919('0123456789abcdef','test data to be encrypted')
Inviato da Matteo Mattei / 6th febbraio 2011
Per un mio cliente ho avuto bisogno di creare uno script in PHP che fosse in grado di esportare lo schema di un database MySQL su un altro database. Questo script supporta anche la gestione dei constraints.
Avrete solamente bisogno di configurare le variabili $DB_SRC_* and $DB_DST_* secondo le vostre necessità.
Qui di seguito trovate il codice che ho creato per questo scopo:
<?php
/********************* START CONFIGURATION *********************/
$DB_SRC_HOST='localhost';
$DB_SRC_USER='root';
$DB_SRC_PASS='password';
$DB_SRC_NAME='database1';
$DB_DST_HOST='localhost';
$DB_DST_USER='root';
$DB_DST__PASS='password';
$DB_DST_NAME='database2';
/*********************** GRAB OLD SCHEMA ***********************/
$db1 = mysql_connect($DB_SRC_HOST,$DB_SRC_USER,$DB_SRC_PASS) or die(mysql_error());
mysql_select_db($DB_SRC_NAME, $db1) or die(mysql_error());
$result = mysql_query("SHOW TABLES;",$db1) or die(mysql_error());
$buf="set foreign_key_checks = 0;\n";
$constraints='';
while($row = mysql_fetch_array($result))
{
$result2 = mysql_query("SHOW CREATE TABLE ".$row[0].";",$db1) or die(mysql_error());
$res = mysql_fetch_array($result2);
if(preg_match("/[ ]*CONSTRAINT[ ]+.*\n/",$res[1],$matches))
{
$res[1] = preg_replace("/,\n[ ]*CONSTRAINT[ ]+.*\n/","\n",$res[1]);
$constraints.="ALTER TABLE ".$row[0]." ADD ".trim($matches[0]).";\n";
}
$buf.=$res[1].";\n";
}
$buf.=$constraints;
$buf.="set foreign_key_checks = 1";
/**************** CREATE NEW DB WITH OLD SCHEMA ****************/
$db2 = mysql_connect($DB_DST_HOST,$DB_DST_USER,$DB_DST_PASS) or die(mysql_error());
$sql = 'CREATE DATABASE '.$DB_DST_NAME;
if(!mysql_query($sql, $db2)) die(mysql_error());
mysql_select_db($DB_DST_NAME, $db2) or die(mysql_error());
$queries = explode(';',$buf);
foreach($queries as $query)
if(!mysql_query($query, $db2)) die(mysql_error());
?>
Inviato da Matteo Mattei / 4th febbraio 2011
Sono solito configurare vsftp come FTP server sui web server per permettere un accesso FTP sulla base del nome a dominio. Qualche giorno fa un mio cliente mi ha chiesto di creare multipli utenti ftp per un singolo dominio, ognuno con una root differente all’interno dello stesso dominio.
Questa è sempre stata la configurazione base di vsftpd (/etc/vsftpd.conf) che utilizzo:
listen=YES
anonymous_enable=NO
local_enable=YES
virtual_use_local_privs=YES
write_enable=YES
connect_from_port_20=YES
xferlog_enable=YES
pam_service_name=vsftpd
guest_enable=YES
guest_username=www-data
user_sub_token=$USER
local_root=/var/www/$USER
chroot_local_user=YES
hide_ids=YES
force_dot_files=YES
ftpd_banner=Welcome to my private FTP service.
local_umask=022
e questo è il mio /etc/pam.d/vsftpd
auth required pam_pwdfile.so pwdfile /etc/ftpd.passwd
account required pam_permit.so
La prima volta ho creato il file /etc/ftpd.passwd in questo modo:
htpasswd -c -d -b /etc/ftpd.passwd domain1.com <password>
Per gli utenti futuri, semplicemente va evitato il parametro ‘-c’:
htpasswd -d -b /etc/ftpd.passwd domain2.com <password>
Con questa configurazione tutti gli utenti hanno le seguenti credenziali:
- host: domain1.com
- username: domain1.com
- password: password
- port: 21
- Root folder: /var/www/domain1/
Adesso il punto è: come possiamo creare utenti multipli per un singolo dominio e ognuno con una cartella root diversa?
La risposta è abbastanza semplice, seguitemi!
Create la directory /var/www/users e aggiungete la seguente linea alla fine di /etc/vsftpd.conf:
user_config_dir=/var/www/users
All’interno della directory /var/www/users create un file per ogni utente virtuale (per esempio per l’utente user1.domain1.com) contenente una linea con la directory base per quell’utente:
echo "local_root=/var/www/domain1.com/pub/user1" > /var/www/users/user1.domain1.com
Adesso aggiungete il nuovo nome utente e password al file /etc/ftpd.passwd come al solito:
htpasswd -d -b /etc/ftpd.passwd user1.domain1.com <password>
Riavviate il demone vsftpd e testate la vostra nuova configurazione!