← Index
NYTProf Performance Profile   « line view »
For /usr/local/bin/sa-learn
  Run on Sun Nov 5 03:09:29 2017
Reported on Mon Nov 6 13:20:46 2017

Filename/usr/local/lib/perl5/site_perl/Mail/SpamAssassin/Conf/LDAP.pm
StatementsExecuted 14 statements in 1.71ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11141µs180µsMail::SpamAssassin::Conf::LDAP::::BEGIN@44Mail::SpamAssassin::Conf::LDAP::BEGIN@44
11125µs30µsMail::SpamAssassin::Conf::LDAP::::BEGIN@48Mail::SpamAssassin::Conf::LDAP::BEGIN@48
11122µs45µsMail::SpamAssassin::Conf::LDAP::::BEGIN@47Mail::SpamAssassin::Conf::LDAP::BEGIN@47
11120µs84µsMail::SpamAssassin::Conf::LDAP::::BEGIN@51Mail::SpamAssassin::Conf::LDAP::BEGIN@51
11119µs27µsMail::SpamAssassin::Conf::LDAP::::BEGIN@46Mail::SpamAssassin::Conf::LDAP::BEGIN@46
11118µs74µsMail::SpamAssassin::Conf::LDAP::::BEGIN@49Mail::SpamAssassin::Conf::LDAP::BEGIN@49
0000s0sMail::SpamAssassin::Conf::LDAP::::__ANON__[:107]Mail::SpamAssassin::Conf::LDAP::__ANON__[:107]
0000s0sMail::SpamAssassin::Conf::LDAP::::loadMail::SpamAssassin::Conf::LDAP::load
0000s0sMail::SpamAssassin::Conf::LDAP::::load_modulesMail::SpamAssassin::Conf::LDAP::load_modules
0000s0sMail::SpamAssassin::Conf::LDAP::::load_with_ldapMail::SpamAssassin::Conf::LDAP::load_with_ldap
0000s0sMail::SpamAssassin::Conf::LDAP::::newMail::SpamAssassin::Conf::LDAP::new
0000s0sMail::SpamAssassin::Conf::LDAP::::sa_dieMail::SpamAssassin::Conf::LDAP::sa_die
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# <@LICENSE>
2# Licensed to the Apache Software Foundation (ASF) under one or more
3# contributor license agreements. See the NOTICE file distributed with
4# this work for additional information regarding copyright ownership.
5# The ASF licenses this file to you under the Apache License, Version 2.0
6# (the "License"); you may not use this file except in compliance with
7# the License. You may obtain a copy of the License at:
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# </@LICENSE>
17
18=head1 NAME
19
20Mail::SpamAssassin::Conf::LDAP - load SpamAssassin scores from LDAP database
21
22=head1 SYNOPSIS
23
24 (see Mail::SpamAssassin)
25
26
27=head1 DESCRIPTION
28
29Mail::SpamAssassin is a module to identify spam using text analysis and
30several internet-based realtime blacklists.
31
32This class is used internally by SpamAssassin to load scores from an LDAP
33database. Please refer to the C<Mail::SpamAssassin> documentation for public
34interfaces.
35
36=head1 METHODS
37
38=over 4
39
40=cut
41
42package Mail::SpamAssassin::Conf::LDAP;
43
44257µs2319µs
# spent 180µs (41+139) within Mail::SpamAssassin::Conf::LDAP::BEGIN@44 which was called: # once (41µs+139µs) by Mail::SpamAssassin::BEGIN@73 at line 44
use Mail::SpamAssassin::Logger;
# spent 180µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@44 # spent 139µs making 1 call to Exporter::import
45
46263µs235µs
# spent 27µs (19+8) within Mail::SpamAssassin::Conf::LDAP::BEGIN@46 which was called: # once (19µs+8µs) by Mail::SpamAssassin::BEGIN@73 at line 46
use strict;
# spent 27µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@46 # spent 8µs making 1 call to strict::import
47251µs268µs
# spent 45µs (22+23) within Mail::SpamAssassin::Conf::LDAP::BEGIN@47 which was called: # once (22µs+23µs) by Mail::SpamAssassin::BEGIN@73 at line 47
use warnings;
# spent 45µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@47 # spent 23µs making 1 call to warnings::import
48254µs235µs
# spent 30µs (25+5) within Mail::SpamAssassin::Conf::LDAP::BEGIN@48 which was called: # once (25µs+5µs) by Mail::SpamAssassin::BEGIN@73 at line 48
use bytes;
# spent 30µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@48 # spent 5µs making 1 call to bytes::import
49266µs2130µs
# spent 74µs (18+56) within Mail::SpamAssassin::Conf::LDAP::BEGIN@49 which was called: # once (18µs+56µs) by Mail::SpamAssassin::BEGIN@73 at line 49
use re 'taint';
# spent 74µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@49 # spent 56µs making 1 call to re::import
50
5112µs
# spent 84µs (20+64) within Mail::SpamAssassin::Conf::LDAP::BEGIN@51 which was called: # once (20µs+64µs) by Mail::SpamAssassin::BEGIN@73 at line 53
use vars qw{
52 @ISA
5311.40ms2148µs};
# spent 84µs making 1 call to Mail::SpamAssassin::Conf::LDAP::BEGIN@51 # spent 64µs making 1 call to vars::import
54
5518µs@ISA = qw();
56
57###########################################################################
58
59sub new {
60 my $class = shift;
61 $class = ref($class) || $class;
62 my ($main) = @_;
63
64 my $self = {
65 'main' => $main
66 };
67
68 bless ($self, $class);
69 $self;
70}
71
72###########################################################################
73
74sub load_modules { # static
75 dbg("ldap: loading Net::LDAP and URI");
76 eval {
77 require Net::LDAP; # actual server connection
78 require URI; # parse server connection dsn
79 };
80
81 # do any other preloading that will speed up operation
82}
83
84###########################################################################
85
86=item $f->load ($username)
87
88Read configuration paramaters from LDAP server and parse scores from it.
89
90=back
91
92=cut
93
94sub load {
95 my ($self, $username) = @_;
96
97 my $conf = $self->{main}->{conf};
98 my $url = $conf->{user_scores_dsn}; # an ldap URI
99 dbg("ldap: URL is $url");
100 if(!defined($url) || $url eq '') {
101 dbg("ldap: No URL defined; skipping LDAP");
102 return;
103 }
104
105 eval {
106 # make sure we can see croak messages from DBI
107 local $SIG{'__DIE__'} = sub { warn "$_[0]"; };
108 require Net::LDAP;
109 require URI;
110 load_with_ldap($self, $username, $url);
111 1;
112 } or do {
113 my $eval_stat = $@ ne '' ? $@ : "errno=$!"; chomp $eval_stat;
114 if ($conf->{user_scores_fail_to_global}) {
115 info("ldap: failed to load user (%s) scores from LDAP server, ".
116 "using a global default: %s", $username, $eval_stat);
117 return 1;
118 } else {
119 warn sprintf(
120 "ldap: failed to load user (%s) scores from LDAP server: %s\n",
121 $username, $eval_stat);
122 return 0;
123 }
124 };
125}
126
127sub load_with_ldap {
128 my ($self, $username, $url) = @_;
129
130# ldapurl = scheme "://" [hostport] ["/"
131# [dn ["?" [attributes] ["?" [scope]
132# ["?" [filter] ["?" extensions]]]]]]
133
134 my $uri = URI->new("$url");
135
136 my $host = $uri->host;
137 if (!defined($host) || $host eq '') {
138 dbg("ldap: No server specified, assuming localhost");
139 $host = "localhost";
140 }
141 my $port = $uri->port;
142 my $base = $uri->dn;
143 my @attr = $uri->attributes;
144 my $scope = $uri->scope;
145 my $filter = $uri->filter;
146 my $scheme = $uri->scheme;
147 my %extn = $uri->extensions; # unused
148
149 $filter =~ s/__USERNAME__/$username/g;
150 dbg("ldap: host=$host, port=$port, base='$base', attr=${attr[0]}, scope=$scope, filter='$filter'");
151
152 my $main = $self->{main};
153 my $conf = $main->{conf};
154 my $ldapuser = $conf->{user_scores_ldap_username};
155 my $ldappass = $conf->{user_scores_ldap_password};
156
157 if(!$ldapuser) {
158 undef($ldapuser);
159 } else {
160 dbg("ldap: user='$ldapuser'");
161 }
162
163 if(!$ldappass) {
164 undef($ldappass);
165 } else {
166 # don't log this to avoid leaking sensitive info
167 # dbg("ldap: pass='$ldappass'");
168 }
169
170 my $f_attribute = $attr[0];
171
172 my $ldap = Net::LDAP->new ("$host:$port",
173 onerror => "warn",
174 scheme => $scheme);
175
176 if (!defined($ldapuser) && !defined($ldappass)) {
177 $ldap->bind;
178 } else {
179 $ldap->bind($ldapuser, password => $ldappass);
180 }
181
182 my $result = $ldap->search( base => $base,
183 filter => $filter,
184 scope => $scope,
185 attrs => \@attr
186 );
187
188 my $config_text = '';
189 foreach my $entry ($result->all_entries) {
190 my @v = $entry->get_value($f_attribute);
191 foreach my $v (@v) {
192 dbg("ldap: retrieving prefs for $username: $v");
193 $config_text .= $v."\n";
194 }
195 }
196 if ($config_text ne '') {
197 $conf->{main} = $main;
198 $conf->parse_scores_only($config_text);
199 delete $conf->{main};
200 }
201 return;
202}
203
204###########################################################################
205
206sub sa_die { Mail::SpamAssassin::sa_die(@_); }
207
208###########################################################################
209
21018µs1;