line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Mail::vpopmail.pm |
2
|
|
|
|
|
|
|
# $Id: vpopmail.pm,v 0.60b3 2007/04/16 00:32:24 jkister Exp $ |
3
|
|
|
|
|
|
|
# Copyright (c) 2004-2007 Jeremy Kister. |
4
|
|
|
|
|
|
|
# Released under Perl's Artistic License. |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
$Mail::vpopmail::VERSION = "0.60b3"; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 NAME |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
Mail::vpopmail - Utility to get information about vpopmail managed email addresses |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 SYNOPSIS |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use Mail::vpopmail; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $vchkpw = Mail::vpopmail->new(); |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
my $vchkpw = Mail::vpopmail->new(cache => 1, |
19
|
|
|
|
|
|
|
debug => 0, |
20
|
|
|
|
|
|
|
auth_module => 'cdb', |
21
|
|
|
|
|
|
|
dsn => 'DBI:mysql:host=localhost;database=vpopmail', |
22
|
|
|
|
|
|
|
dbun => 'vpopmailuser', |
23
|
|
|
|
|
|
|
dbpw => 'vpoppasswd', |
24
|
|
|
|
|
|
|
); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 DESCRIPTION |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
C provides serveral functions for interacting with |
30
|
|
|
|
|
|
|
vpopmail. This module can be useful especially when hashing is turned |
31
|
|
|
|
|
|
|
on, as you can not predict the location of the domain's nor the |
32
|
|
|
|
|
|
|
mailbox's directories. |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=over 4 |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
=item new( [OPTIONS] ); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
C are passed in a hash like fashion, using key and value |
41
|
|
|
|
|
|
|
pairs. Possible options are: |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
B - Cache results of queries (0=Off, 1=On). Default=On. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
B - Print debugging info to STDERR (0=Off, 1=On). Default=On. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
B - cdb or sql. Default=cdb, but |
48
|
|
|
|
|
|
|
Default=sql if ~vpopmail/etc/vpopmail.mysql exists. |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
B - SQL DSN. Default='DBI:mysql:host=localhost;database=vpopmail' |
51
|
|
|
|
|
|
|
Autogenerated if ~vpopmail/etc/vpopmail.mysql exists. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
B - SQL Username. Default=vpopmailuser. |
54
|
|
|
|
|
|
|
Autogenerated if ~vpopmail/etc/vpopmail.mysql exists. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
B - SQL Password. Default=vpoppasswd. |
57
|
|
|
|
|
|
|
Autogenerated if ~vpopmail/etc/vpopmail.mysql exists. |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=item userinfo( email => $email, field => ); |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
B - the email address to get properties on |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
B - the field(s) to be returned (may be comma separated): |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
dir - return this domain's vpopmail domains directory |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
crypt - return the encrypted password |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
uid - return the uid |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
gid - return the gid |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
comment - return the comment, if available |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
maildir - return this user's maildir |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
quota - return the quota (you have to parse this yourself) |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
plain - return the plain text password, if available |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=item domaininfo( domain => $domain, field => ); |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
B - the domain to get properties on |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
B - the field to be returned: |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
dir - return the vpopmail domain directory |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
mailboxes - return an array reference containing all the mailboxes |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
all - return an array ref of hash refs of all data for the domain |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item alldomains( field => ); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
B - the field to be returned: |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
name - returns an array reference of the names of all domains |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
dir - returns an array refrence of all domain directories |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
map - returns a hash reference of domain name -> domain directory |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=head1 EXAMPLES |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
use strict; |
107
|
|
|
|
|
|
|
use Mail::vpopmail; |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
my $vchkpw = Mail::vpopmail->new(cache=>1, debug=>0); |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# find all domains |
113
|
|
|
|
|
|
|
my $domains_aref = $vchkpw->alldomains(field => 'name'); |
114
|
|
|
|
|
|
|
foreach my $domain (@${domains_aref}){ |
115
|
|
|
|
|
|
|
print "$domain\n"; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
# find all domains directories |
119
|
|
|
|
|
|
|
my $dirlist_aref = $vchkpw->alldomains(field => 'dir'); |
120
|
|
|
|
|
|
|
foreach my $dir (@${dirlist_aref}){ |
121
|
|
|
|
|
|
|
print "$dir\n"; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# find all domains and their directories |
125
|
|
|
|
|
|
|
my $alllist_aref = $vchkpw->alldomains(field => 'map'); |
126
|
|
|
|
|
|
|
foreach my $href (@${alllist_aref}){ |
127
|
|
|
|
|
|
|
print "$href->{name} => $href->{dir}\n"; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
my $domain = shift; |
131
|
|
|
|
|
|
|
unless(defined($domain)){ |
132
|
|
|
|
|
|
|
print "enter domain: "; |
133
|
|
|
|
|
|
|
chop($domain=); |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# find all mailboxes in a given domain |
138
|
|
|
|
|
|
|
my $mailboxes_aref = $vchkpw->domaininfo(domain => $domain, field => 'mailboxes'); |
139
|
|
|
|
|
|
|
foreach my $mailbox (@{$mailboxes_aref}){ |
140
|
|
|
|
|
|
|
print "found mailbox: $mailbox for domain: $domain\n"; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# find all properties for a given domain |
144
|
|
|
|
|
|
|
my $alldata_aref = $vchkpw->domaininfo(domain => $domain, field => 'all'); |
145
|
|
|
|
|
|
|
foreach my $href (@{$alldata_aref}){ |
146
|
|
|
|
|
|
|
print "found data for $domain:\n"; |
147
|
|
|
|
|
|
|
while(my($key,$value) = each %{$href}){ |
148
|
|
|
|
|
|
|
print " found $key => $value\n"; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# individual user stuff |
153
|
|
|
|
|
|
|
my $email = shift; |
154
|
|
|
|
|
|
|
unless(defined($email)){ |
155
|
|
|
|
|
|
|
print "email address: "; |
156
|
|
|
|
|
|
|
chop($email=); |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
my $dir = $vchkpw->userinfo(email => $email, field => 'dir'); |
160
|
|
|
|
|
|
|
print "dir: $dir\n"; |
161
|
|
|
|
|
|
|
my ($crypt,$uid,$gid) = $vchkpw->userinfo(email => $email, field => 'crypt,uid,gid'); |
162
|
|
|
|
|
|
|
print "crypt/uid/gid: $crypt/$uid/$gid\n"; |
163
|
|
|
|
|
|
|
my $comment = $vchkpw->userinfo(email => $email, field => 'comment'); |
164
|
|
|
|
|
|
|
print "comment: $comment\n"; |
165
|
|
|
|
|
|
|
my $maildir = $vchkpw->userinfo(email => $email, field => 'maildir'); |
166
|
|
|
|
|
|
|
print "maildir: $maildir\n"; |
167
|
|
|
|
|
|
|
my $quota = $vchkpw->userinfo(email => $email, field => 'quota'); |
168
|
|
|
|
|
|
|
print "quota: $quota\n"; |
169
|
|
|
|
|
|
|
my $plain = $vchkpw->userinfo(email => $email, field => 'plain'); |
170
|
|
|
|
|
|
|
print "plain: $plain\n"; |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head1 CAVEATS |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
This version is the first that supports SQL auth modules. It is not |
175
|
|
|
|
|
|
|
tested and should be used with caution. Feedback needed. |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head1 AUTHOR |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Jeremy Kister - http://jeremy.kister.net/ |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=cut |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
package Mail::vpopmail; |
185
|
|
|
|
|
|
|
|
186
|
1
|
|
|
1
|
|
605
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2391
|
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
my $HAVE_DBI; |
189
|
|
|
|
|
|
|
eval{ require DBI; $HAVE_DBI=1; }; |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
my (%_cache,%_arg); |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
sub new { |
194
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
195
|
0
|
|
|
|
|
|
%_arg = @_; |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
|
|
|
|
$_arg{cache} = 1 unless(defined($_arg{cache})); |
198
|
0
|
0
|
|
|
|
|
$_arg{debug} = 1 unless(defined($_arg{debug})); |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
|
my $vpopdir = (getpwnam('vpopmail'))[7]; |
201
|
0
|
0
|
|
|
|
|
die "vpopmail home directory ($vpopdir) not found.\n" unless(-d $vpopdir); |
202
|
|
|
|
|
|
|
|
203
|
0
|
0
|
|
|
|
|
if(open(MYSQL, "${vpopdir}/etc/vpopmail.mysql")){ |
|
|
0
|
|
|
|
|
|
204
|
0
|
|
|
|
|
|
chop(my $input=); |
205
|
0
|
|
|
|
|
|
my ($hostname,$dbport,$dbun,$dbpw,$dbname) = split(/\|/, $input); |
206
|
0
|
|
|
|
|
|
close MYSQL; |
207
|
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
my $dsn = "DBI:mysql:hostname=${hostname};database=${dbname}"; |
209
|
0
|
0
|
|
|
|
|
$dsn .= ";port=$dbport" if($dbport); |
210
|
0
|
|
|
|
|
|
$_arg{dsn} = $dsn; |
211
|
0
|
|
|
|
|
|
$_arg{dbname} = $dbname; |
212
|
0
|
|
|
|
|
|
$_arg{dbun} = $dbun; |
213
|
0
|
|
|
|
|
|
$_arg{dbpw} = $dbpw; |
214
|
0
|
|
|
|
|
|
$_arg{auth_module} = 'sql'; |
215
|
|
|
|
|
|
|
}elsif($_arg{auth_module} eq 'sql'){ |
216
|
0
|
0
|
|
|
|
|
$_arg{dsn} = 'DBI:ldap:host=localhost;database=vpopmail' unless(defined($_arg{dsn})); |
217
|
0
|
|
|
|
|
|
($_arg{dbname}) = $_arg{dsn} =~ /database=([^\=\;\:\s]+)/; |
218
|
0
|
0
|
|
|
|
|
$_arg{dbun} = 'vpopmailuser' unless(defined($_arg{dbun})); |
219
|
0
|
0
|
|
|
|
|
$_arg{dbpw} = 'vpoppasswd' unless(defined($_arg{dbpw})); |
220
|
|
|
|
|
|
|
}else{ |
221
|
0
|
|
|
|
|
|
$_arg{auth_module} = 'cdb'; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
0
|
0
|
|
|
|
|
if($_arg{auth_module} eq 'sql'){ |
225
|
0
|
0
|
|
|
|
|
unless($HAVE_DBI){ |
226
|
0
|
|
|
|
|
|
warn "You're trying to use SQL support, but do not have DBI in \@INC. (\@INC contains: )"; |
227
|
0
|
|
|
|
|
|
foreach(@INC){ |
228
|
0
|
|
|
|
|
|
print "$_ "; |
229
|
|
|
|
|
|
|
} |
230
|
0
|
|
|
|
|
|
die "\nnew() failed-- "; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
return(bless({},$class)); |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
0
|
|
|
0
|
0
|
|
sub Version { $Mail::vpopmail::VERSION } |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub _handle_dbh { |
240
|
0
|
0
|
|
0
|
|
|
my $dbh = ($_cache{dbh}) ? $_cache{dbh} : DBI->connect($_arg{dsn}, $_arg{dbun}, $_arg{dbpw}, {RaiseError => 1}); |
241
|
|
|
|
|
|
|
|
242
|
0
|
0
|
|
|
|
|
unless($dbh){ |
243
|
0
|
|
|
|
|
|
die "Connect to database failed: $DBI::errstr "; |
244
|
|
|
|
|
|
|
} |
245
|
0
|
0
|
|
|
|
|
if($_arg{cache}){ |
246
|
0
|
0
|
|
|
|
|
$_cache{dbh} = $dbh unless($_cache{dbh}); |
247
|
|
|
|
|
|
|
} |
248
|
0
|
|
|
|
|
|
return($dbh); |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub _dir { |
252
|
0
|
|
|
0
|
|
|
my $class = shift; |
253
|
0
|
0
|
|
|
|
|
if(my $domain = shift){ |
254
|
0
|
0
|
|
|
|
|
return($_cache{$domain}{dir}) if($_cache{$domain}{dir}); |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# assign is still authoritative when sql in use |
257
|
0
|
0
|
|
|
|
|
if(open(ASSIGN, '/var/qmail/users/assign')){ |
258
|
0
|
|
|
|
|
|
my $dir; |
259
|
0
|
|
|
|
|
|
while(){ |
260
|
0
|
0
|
|
|
|
|
if(/^\+${domain}\-:[^:]+:\d+:\d+:([^:]+):-:/){ |
261
|
0
|
|
|
|
|
|
$dir = $1; |
262
|
0
|
|
|
|
|
|
last; |
263
|
|
|
|
|
|
|
} |
264
|
|
|
|
|
|
|
} |
265
|
0
|
|
|
|
|
|
close ASSIGN; |
266
|
|
|
|
|
|
|
|
267
|
0
|
0
|
|
|
|
|
if(defined($dir)){ |
268
|
0
|
0
|
|
|
|
|
$_cache{$domain}{dir} = $dir if($_arg{cache}); |
269
|
0
|
|
|
|
|
|
return($dir); # this dir is not verified, it's just what vpopmail thinks |
270
|
|
|
|
|
|
|
}else{ |
271
|
0
|
0
|
|
|
|
|
warn "could not find directory for domain: $domain\n" if($_arg{debug}); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
}else{ |
274
|
0
|
0
|
|
|
|
|
warn "could not open /var/qmail/users/assign: $!\n" if($_arg{debug}); |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
}else{ |
277
|
0
|
0
|
|
|
|
|
warn "domain not supplied correctly\n" if($_arg{debug}); |
278
|
|
|
|
|
|
|
} |
279
|
0
|
|
|
|
|
|
return(); |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub userinfo { |
283
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
284
|
0
|
|
|
|
|
|
my %arg = @_; |
285
|
0
|
0
|
0
|
|
|
|
unless(exists($arg{email}) && exists($arg{field})){ |
286
|
0
|
0
|
|
|
|
|
if($_arg{debug}){ |
287
|
0
|
|
|
|
|
|
warn "syntax error: email: $arg{email} field: $arg{field}\n"; |
288
|
|
|
|
|
|
|
} |
289
|
0
|
|
|
|
|
|
return(); |
290
|
|
|
|
|
|
|
} |
291
|
0
|
|
|
|
|
|
my ($user,$domain) = split(/\@/, $arg{email}); # no routing data supported |
292
|
0
|
0
|
|
|
|
|
warn "arg{email}: $arg{email} - user: $user - domain: $domain\n" if($_arg{debug}); |
293
|
|
|
|
|
|
|
|
294
|
0
|
0
|
0
|
|
|
|
if(defined($user) && defined($domain)){ |
295
|
0
|
|
|
|
|
|
my @return; |
296
|
0
|
|
|
|
|
|
my $dir = Mail::vpopmail->_dir($domain); |
297
|
|
|
|
|
|
|
|
298
|
0
|
0
|
|
|
|
|
if($arg{field} eq 'dir'){ |
299
|
0
|
|
|
|
|
|
push @return, $dir; |
300
|
|
|
|
|
|
|
}else{ |
301
|
0
|
0
|
|
|
|
|
if(exists($_cache{$arg{email}}{crypt})){ |
302
|
0
|
0
|
|
|
|
|
warn "cache found for $arg{email}\n" if($_arg{debug}); |
303
|
0
|
|
|
|
|
|
foreach my $field (split(/,/, $arg{field})){ |
304
|
0
|
|
|
|
|
|
push @return, $_cache{$arg{email}}{$field}; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
}else{ |
307
|
0
|
|
|
|
|
|
my (%uhash,$found); |
308
|
0
|
0
|
|
|
|
|
if($_arg{auth_module} eq 'cdb'){ |
309
|
0
|
0
|
|
|
|
|
if(open(VPASSWD, "${dir}/vpasswd")){ |
310
|
0
|
|
|
|
|
|
while(){ |
311
|
0
|
|
|
|
|
|
chomp; |
312
|
0
|
0
|
|
|
|
|
if(/^${user}:([^:]+):(\d+):(\d+):([^:]*):([^:]+):([^:]+)(:([^:]+))?/){ |
313
|
0
|
|
|
|
|
|
%uhash = (crypt => $1, uid => $2, gid => $3, comment => $4, |
314
|
|
|
|
|
|
|
maildir => $5, quota => $6, plain => $8, dir => $dir); |
315
|
0
|
|
|
|
|
|
$found=1; |
316
|
0
|
|
|
|
|
|
last; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
0
|
|
|
|
|
|
close VPASSWD; |
320
|
|
|
|
|
|
|
}else{ |
321
|
0
|
0
|
|
|
|
|
warn "cannot open ${dir}/vpasswd: $!\n" if($_arg{debug}); |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
}else{ |
324
|
|
|
|
|
|
|
# sql |
325
|
0
|
|
|
|
|
|
my $dbh = _handle_dbh(); |
326
|
0
|
|
|
|
|
|
my $sql = "SELECT pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell,pw_clear_passwd FROM $_arg{dbname}"; |
327
|
0
|
|
|
|
|
|
$sql .= ' WHERE pw_name = ' . $dbh->quote($user) . ' AND pw_domain = ' . $dbh->quote($domain); |
328
|
0
|
|
|
|
|
|
my $sth = $dbh->prepare($sql); |
329
|
0
|
|
|
|
|
|
$sth->execute; |
330
|
0
|
|
|
|
|
|
my $row = $sth->fetchrow_arrayref; |
331
|
0
|
|
|
|
|
|
%uhash = (crypt => $row->[0], uid => $row->[1], gid => $row->[2], comment => $row->[3], |
332
|
|
|
|
|
|
|
maildir => $row->[4], quota => $row->[5], plain => $row->[6], dir => ${dir}); |
333
|
0
|
0
|
|
|
|
|
$found=1 if(exists($uhash{crypt})); |
334
|
|
|
|
|
|
|
} |
335
|
0
|
0
|
|
|
|
|
if($found){ |
336
|
0
|
0
|
|
|
|
|
if($_arg{cache}){ |
337
|
0
|
|
|
|
|
|
while(my($key,$value) = each %uhash){ |
338
|
0
|
|
|
|
|
|
$_cache{$arg{email}}{$key} = $value; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
foreach my $field (split(/,/, $arg{field})){ |
343
|
0
|
|
|
|
|
|
push @return, $uhash{$field}; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
}else{ |
346
|
0
|
0
|
|
|
|
|
warn "cannot find ${user} in ${domain}\n" if($_arg{debug}); |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
} |
350
|
0
|
0
|
|
|
|
|
return (@return == 1) ? $return[0] : @return; |
351
|
|
|
|
|
|
|
}else{ |
352
|
0
|
0
|
|
|
|
|
warn "email not supplied correctly\n" if($_arg{'debug'}); |
353
|
|
|
|
|
|
|
} |
354
|
0
|
|
|
|
|
|
return(); |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub alldomains { |
358
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
359
|
0
|
|
|
|
|
|
my %arg = @_; |
360
|
0
|
0
|
0
|
|
|
|
unless($arg{field} eq 'name' || $arg{field} eq 'dir' || $arg{field} eq 'map'){ |
|
|
|
0
|
|
|
|
|
361
|
0
|
0
|
|
|
|
|
if($_arg{debug}){ |
362
|
0
|
|
|
|
|
|
warn "syntax error: field: $arg{field}\n"; |
363
|
|
|
|
|
|
|
} |
364
|
0
|
|
|
|
|
|
return(); |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
# assign is still authoritative when sql in use |
368
|
0
|
0
|
|
|
|
|
if(open(ASSIGN, '/var/qmail/users/assign')){ |
369
|
0
|
|
|
|
|
|
my @array; |
370
|
0
|
|
|
|
|
|
while(){ |
371
|
0
|
0
|
|
|
|
|
if(/^\+([^:]+)\-:[^:]+:\d+:\d+:([^:]+):-:/){ |
372
|
0
|
0
|
|
|
|
|
if($arg{field} eq 'map'){ |
|
|
0
|
|
|
|
|
|
373
|
0
|
|
|
|
|
|
push @array, { name => $1, dir => $2 }; |
374
|
|
|
|
|
|
|
}elsif($arg{field} eq 'dir'){ |
375
|
0
|
|
|
|
|
|
push @array, $2; |
376
|
|
|
|
|
|
|
}else{ |
377
|
0
|
|
|
|
|
|
push @array, $1; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
} |
381
|
0
|
|
|
|
|
|
close ASSIGN; |
382
|
0
|
|
|
|
|
|
return(\@array); |
383
|
|
|
|
|
|
|
}else{ |
384
|
0
|
0
|
|
|
|
|
warn "could not open /var/qmail/users/assign: $!\n" if($_arg{debug}); |
385
|
|
|
|
|
|
|
} |
386
|
0
|
|
|
|
|
|
return(); |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub domaininfo { |
390
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
391
|
0
|
|
|
|
|
|
my %arg = @_; |
392
|
|
|
|
|
|
|
|
393
|
0
|
0
|
0
|
|
|
|
if(exists($arg{domain}) && exists($arg{field})){ |
394
|
0
|
0
|
0
|
|
|
|
unless($arg{field} eq 'mailboxes' || $arg{field} eq 'all' || $arg{field} eq 'dir'){ |
|
|
|
0
|
|
|
|
|
395
|
0
|
0
|
|
|
|
|
warn "syntax error: domain field type may be 'mailboxes' or 'all'\n" if($_arg{debug}); |
396
|
0
|
|
|
|
|
|
return(); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
}else{ |
399
|
0
|
0
|
|
|
|
|
if($_arg{debug}){ |
400
|
0
|
|
|
|
|
|
warn "syntax error: domain: $arg{domain} - field: $arg{field}\n"; |
401
|
|
|
|
|
|
|
} |
402
|
0
|
|
|
|
|
|
return(); |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
|
405
|
0
|
0
|
|
|
|
|
my %hash = ( dir => (exists($_cache{$arg{domain}}{dir})) ? $_cache{$arg{domain}}{dir} : Mail::vpopmail->_dir($arg{domain}) ); |
406
|
0
|
0
|
|
|
|
|
warn "hash{dir}: $hash{dir}\n" if($_arg{debug}); |
407
|
|
|
|
|
|
|
|
408
|
0
|
0
|
|
|
|
|
if($arg{field} eq 'dir'){ |
409
|
0
|
|
|
|
|
|
return($hash{dir}); |
410
|
|
|
|
|
|
|
} |
411
|
|
|
|
|
|
|
|
412
|
0
|
|
|
|
|
|
my @return; |
413
|
0
|
0
|
|
|
|
|
if($_arg{auth_module} eq 'cdb'){ |
414
|
0
|
0
|
|
|
|
|
if(open(VPASSWD, "$hash{dir}/vpasswd")){ |
415
|
0
|
|
|
|
|
|
while(){ |
416
|
0
|
|
|
|
|
|
chomp; |
417
|
0
|
0
|
|
|
|
|
if(/^([^:]+):([^:]+):(\d+):(\d+):([^:]*):([^:]+):([^:]+)(:([^:]+))?/){ |
418
|
0
|
|
|
|
|
|
%hash = (mailbox => $1, crypt => $2, uid => $3, gid => $4, |
419
|
|
|
|
|
|
|
comment => $5, maildir => $6, quota => $7, plain => $9, dir => $hash{dir}); |
420
|
|
|
|
|
|
|
|
421
|
0
|
0
|
|
|
|
|
if($arg{field} eq 'mailboxes'){ |
422
|
0
|
|
|
|
|
|
push @return, $hash{mailbox}; |
423
|
|
|
|
|
|
|
}else{ |
424
|
0
|
|
|
|
|
|
push @return, \%hash; |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
0
|
0
|
|
|
|
|
if($_arg{cache}){ |
428
|
0
|
|
|
|
|
|
while(my($key,$value) = each %hash){ |
429
|
0
|
|
|
|
|
|
$_cache{$hash{mailbox}}{$key} = $value; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
} |
433
|
|
|
|
|
|
|
} |
434
|
0
|
|
|
|
|
|
close VPASSWD; |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
}else{ |
437
|
0
|
0
|
|
|
|
|
warn "cannot open $hash{dir}/vpasswd: $!\n" if($_arg{debug}); |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
}else{ |
440
|
|
|
|
|
|
|
#sql; |
441
|
0
|
|
|
|
|
|
my $dbh = _handle_dbh(); |
442
|
0
|
|
|
|
|
|
my $sql = 'SELECT pw_name'; |
443
|
0
|
0
|
|
|
|
|
$sql .= ',pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell,pw_clear_passwd' if($arg{field} eq 'all'); |
444
|
0
|
|
|
|
|
|
$sql .= " FROM $_arg{dbname} WHERE pw_domain = " . $dbh->quote($arg{domain}); |
445
|
0
|
|
|
|
|
|
my $sth = $dbh->prepare($sql); |
446
|
0
|
|
|
|
|
|
$sth->execute; |
447
|
0
|
|
|
|
|
|
while(my $row = $sth->fetchrow_arrayref){ |
448
|
0
|
0
|
|
|
|
|
if($arg{field} eq 'mailboxes'){ |
449
|
0
|
|
|
|
|
|
push @return, $row->[0]; |
450
|
|
|
|
|
|
|
}else{ |
451
|
0
|
|
|
|
|
|
push @return, { mailbox => $row->[0], crypt => $row->[1], uid => $row->[2], gid => $row->[3], |
452
|
|
|
|
|
|
|
comment => $row->[4], maildir => $row->[5], quota => $row->[6], |
453
|
|
|
|
|
|
|
plain => $row->[7], dir => $hash{dir} }; |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
} |
457
|
0
|
|
|
|
|
|
return(\@return); |
458
|
|
|
|
|
|
|
} |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
1; |