pwd - Database Password di Unix

Scopo: Legge dati utente dal database delle password di Unix

Il modulo pwd può essere utilizzato per leggere informazioni utente dal database delle password di Unix (in genere /etc/passwd). L'interfaccia a sola lettura ritorna oggetti tipo tupla con attributi nominali per i campi standard di un record di password.

INDICE ATTRIBUTO SIGNIFICATO
0 pw_name Il nome di accesso dell'utente
1 pw_passwd La password criptata (opzionale)
2 pw_uid Id Utente (intero)
3 pw_gid Id Gruppo (intero)
4 pw_gecos Commento / Nome completo
5 pw_dir La directory home
6 pw_shell L'applicazione lanciata all'accesso, generalmente un interprete di comandi

Interrogare Tutti gli Utenti

Questo esempio stampa un elenco di tutti gli utenti "reali" su di un sistema, comprese le loro directory home (laddove "reale" è inteso con chi ha un nome che non inizia per "_"). Per caricare il database delle password completo, si usa getpwall(). Il valore restituito è una lista in ordine indefinito, quindi deve essere ordinata prima della stampa.

# pwd_getpwall.py

import pwd
import operator

# Carica tutti i dati degli utenti, ordinati per nome utente
all_user_data = pwd.getpwall()
interesting_users = sorted(
    (u for u in all_user_data
     if not u.pw_name.startswith('_')),
    key=operator.attrgetter('pw_name')
)

# Cerca la lunghezza massima per alcuni campi
username_length = max(len(u.pw_name)
                      for u in interesting_users) + 1
home_length = max(len(u.pw_dir)
                  for u in interesting_users) + 1
uid_length = max(len(str(u.pw_uid))
                 for u in interesting_users) + 1

# Stampa le intestazioni del report
fmt = ' '.join(['{:<{username_length}}',
                '{:>{uid_length}}',
                '{:<{home_length}}',
                '{}'])
print(fmt.format('User',
                 'UID',
                 'Directory Home',
                 'Descrizione',
                 username_length=username_length,
                 uid_length=uid_length,
                 home_length=home_length))
print('-' * username_length,
      '-' * uid_length,
      '-' * home_length,
      '-' * 20)

# Stampa i dati
for u in interesting_users:
    print(fmt.format(u.pw_name,
                     u.pw_uid,
                     u.pw_dir,
                     u.pw_gecos,
                     username_length=username_length,
                     uid_length=uid_length,
                     home_length=home_length))

La maggior parte del codice qui sopra gestisce adeguatamente la formattazione dei risultati. Il ciclo for alla fine mostra come accedere ai campi dei record per nome; (viene indicato solo parte del risultato eseguendo lo script sul mio pc - n.d.t.).

$ python3 pwd_getpwall.py

User                    UID Directory Home              Descrizione
-------------------- ------ --------------------------- --------------------
backup                   34 /var/backups                backup
bin                       2 /bin                        bin
daemon                    1 /usr/sbin                   daemon
irc                      39 /var/run/ircd               ircd
kernoops                116 /                           Kernel Oops Tracking Daemon,,,
lightdm                 108 /var/lib/lightdm            Light Display Manager
man                       6 /var/cache/man              man
nobody                65534 /nonexistent                nobody
robby                  1000 /home/robby                 robby
root                      0 /root                       root

Interrogare l'Utente per Nome

Per leggere le informazioni circa un utente non è necessario leggere l'intero database delle password. Si usa getpwnam() per recuperare le informazioni di un utente dato il nome.

# pwd_getpwnam.py

import pwd
import sys

username = sys.argv[1]
user_info = pwd.getpwnam(username)

print('Nome Utente:', user_info.pw_name)
print('Password   :', user_info.pw_passwd)
print('Commento   :', user_info.pw_gecos)
print('UID/GID    :', user_info.pw_uid, '/', user_info.pw_gid)
print('Dir. Home  :', user_info.pw_dir)
print('Shell      :', user_info.pw_shell)

Le password nel sistema dove questo script viene eseguito sono conservate al di fuori del database utenti principale in un file ombra, quindi il campo della password è riportato come x.

$ python3 pwd_getpwnam.py robby

Nome Utente: robby
Password   : x
Commento   : robby,,,
UID/GID    : 1000 / 1000
Dir. Home  : /home/robby
Shell      : /bin/bash
$ python3 pwd_getpwnam.py nobody

Nome Utente: nobody
Password   : x
Commento   : nobody
UID/GID    : 65534 / 65534
Dir. Home  : /nonexistent
Shell      : /usr/sbin/nologin

Interrogare l'Utente per UID

E' anche possibile la ricerca di un utente tramite il suo i utente numerico. Questo è utile per trovare il proprietario di un file.

# pwd_getpwuid_fileowner.py

import pwd
import os

filename = 'pwd_getpwuid_fileowner.py'
stat_info = os.stat(filename)
owner = pwd.getpwuid(stat_info.st_uid).pw_name

print('Il proprietario di {} è {} ({})'.format(
    filename, owner, stat_info.st_uid))

L'id numerico dell'utente può anche essere usato per trovare informazioni circa l'utente che ha attualmente un processo in esecuzione.

# pwd_getpwuid_process.py

import pwd
import os

uid = os.getuid()
user_info = pwd.getpwuid(uid)
print('Attualmente in esecuzione con UID={} nome utente={}'.format(
    uid, user_info.pw_name))
$ python3 pwd_getpwuid_process.py

Attualmente in esecuzione con UID=1000 nome utente=robby

Vedere anche:

pwd
La documentazione della libreria standard per questo modulo.
spwd
Accesso al database delle password sicuro per sistemi che utilizzano il password shadowing.
grp
Il modulo grp legge informazioni sui gruppi Unix