Skip to main content

Ralsina.Me — Roberto Alsina's website

Qmail Address Lister

What it does:

What does this prog­gie do? Well, it lists qmail's user­s, that's what!

Some­times, for some rea­son, you will want a list of all valid ad­dress­es on a qmail sys­tem. This is not that. It stops too soon (see be­low), but it is close.

I wrote this to use with some squir­rel­mail plug­in, so the out­put may not be what you ex­pec­t, but it's easy to change.

It does, how­ev­er, give you all first-lev­el mail ad­dress­es (no sub­-ad­dress­es like joe-s­pam@s­pamjoe.­com), be­cause there are po­ten­tial­ly an in­fi­nite num­ber of those. Al­so, it ig­nores alias­es.

It tries to fig­ure out if some­thing is re­al­ly wrong with your user­s, and warn you.

How this works:

As­sum­ing you are us­ing a "clas­si­cal" mul­ti­-us­er qmail sys­tem, ev­ery do­main list­ed in /var/q­mail/­con­trol/lo­cals is valid for all user­s. So, I get the list of users and cross it with that list, to get a bunch of ad­dress­es.

For each do­main in /var/q­mail/­con­trol/vir­tu­al­do­main­s, there is a pre­fix. Usu­al­ly (I as­sume this), that pre­fix will match a user's name, and all sub­-ad­dress­es of that user, as de­fined in his .q­mail-* files, are valid ad­dress­es for this do­main.

So, I fetch that. For each do­main (say, vir­tu­al­do­main) I get the pre­fix (say pre­f), I read all .q­mail files in /home­/pref (say .q­mail-ex­t) and add an ad­dress of the form p-ex­t@vir­tu­al­do­main .

Keep in mind that .q­mail files feed­ing pro­grams or what­ev­er will con­fuse the be­jeezus out of this scrip­t. How­ev­er, the net ef­fect should sim­ply be some weird ad­dress in the out­put, noth­ing else.

The code:

It is not meant to be fast, or short, but it is meant to be writ­ten clear­ly!

The vari­able names are in span­ish for rea­son of lazy­ness ;-)

#!/us­r/bin/python

im­port   os
im­port   sys
im­port   time

re­sul­ta­dos=[]


#First, read­ al­l user­s of the sys­tem

users={}

for   lin­ea   in   open('/etc/­pass­wd','r'):
        
da­ta=lin­ea.split(':')
        
lo­gin=da­ta[0]
        
nom­bre=da­ta[4]
        
home=da­ta[5]
        
users[lo­gin]=(nom­bre,home)

# Now, read­ the list of vir­tu­al ­do­mains

vir­tuales={}
for   lin­ea   in   open('/­var/q­mail/­con­trol/vir­tu­al­do­main­s','r'):
        
(do­minio,usuario)=lin­ea[:-1].split(':')
        
vir­tuales[do­minio]=usuario

# Read­ the list of lo­cal ­do­mains

lo­cals=[]
for   lin­ea   in   open('/­var/q­mail/­con­trol/lo­cal­s','r'):
        
#Dis­car ­do­main­s that are al­so in vir­tu­al­do­main­s,
        
#Those, we han­dle d­if­fer­ent

        
do­minio=lin­ea[:-1]
        
lo­cals.ap­pend(do­minio)


# Now pro­cess the vir­tu­al ­do­main­s.

for   do­minio   in   vir­tuales.keys():
        
usuario=vir­tuales[do­minio]
        
try:
                
home=users[usuario][1]
        
ex­cept    Key­Er­ror:
                
sys.stderr.write("WARN­ING: Usuer %s ­Does­n't ex­ist, but he's the ­main user of a ­do­main!\n"%usuario)
                
con­tin­ue

        
#Open the user's home­ di­rec­to­ry

        
try:
                
archivos=os.list­dir(home)
        
ex­cept   OS­Er­ror:
                
sys.stderr.write("-----------------------------------------------------------------------------\n")
                
sys.stderr.write("ER­ROR: User %s ex­ist­s, but has no home­! (should be %s)\n"%(usuario,home))
                
sys.stderr.write("-----------------------------------------------------------------------------\n")
                
time.sleep(5)
                
con­tin­ue

        
#Now ­take al­l .q­mail-­some­thing on the user's home
        
#And ­for each, cre­ate the ­match­ing en­try

        
for   archi­vo   in   archivos:
                
if   archi­vo[0:7]=='.q­mail-':
                        
for   lin­ea   in   open(home+'/'+archi­vo):
                                
if   lin­ea[0]=='&':
                                        
user­name=lin­ea[1:-1]
                                        
try:
                                                
re­sul­ta­dos.ap­pend('%s,%s,%s@%s'%(user­name,users[user­name][0],user­name,do­minio))
                                        
ex­cept   Key­Er­ror:
                                                
sys.stderr.write("WARN­ING: user %s has an ad­dress on ­do­main %s, but he ­does­n't ex­ist!\n"
%(user­name,do­minio))
                                                
con­tin­ue


#Al­l user­s have ad­dress­es on the lo­cal­s ­do­main­s (y­ou should­n't have ­many of the­se!)

for   user­name   in   users.keys():
        
for   lo­cal   in   lo­cals:
                
re­sul­ta­dos.ap­pend(   '%s,%s,%s@%s'%(user­name,users[user­name][0],user­name,lo­cal)   )

for   item   in   re­sul­ta­dos:
        
print   item
employment background check / 2011-12-27 23:24:


Hi very nice article


Contents © 2000-2023 Roberto Alsina