File Coverage

blib/lib/urpm/ldap.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package urpm::ldap;
2              
3              
4 1     1   1429 use strict;
  1         2  
  1         37  
5 1     1   5 use warnings;
  1         1  
  1         24  
6 1     1   27 use urpm;
  0            
  0            
7             use urpm::util qw(cat_ output_safe);
8             use urpm::msg 'N';
9             use urpm::media;
10              
11             our $LDAP_CONFIG_FILE = '/etc/ldap.conf';
12             my @per_media_opt = (@urpm::media::PER_MEDIA_OPT, qw(md5sum ftp-proxy http-proxy));
13              
14             # TODO
15             # use srv dns record ?
16             # complete the doc
17              
18             =head1 NAME
19              
20             urpm::ldap - routines to handle configuration with ldap
21              
22             =head1 SYNOPSIS
23              
24             =head1 DESCRIPTION
25              
26             =over
27              
28             =item write_ldap_cache($urpm,$medium)
29              
30             Writes the value fetched from ldap, in case of server failure. This should not
31             be used to reduce the load of the ldap server, as fetching is still needed, and
32             therefore, caching is useless if server is up.
33              
34             =cut
35              
36             sub write_ldap_cache($$) {
37             my ($urpm, $medium) = @_;
38             my $ldap_cache = "$urpm->{cachedir}/ldap";
39             # FIXME what perm for cache ?
40             -d $ldap_cache or mkdir $ldap_cache
41             or die N("Cannot create ldap cache directory");
42             output_safe("$ldap_cache/$medium->{name}",
43             join("\n",
44             "# internal cache file for disconnect ldap operation, do not edit",
45             map { "$_ = $medium->{$_}" } grep { $medium->{$_} } keys %$medium
46             )
47             ) or die N("Cannot write cache file for ldap\n");
48             return 1;
49             }
50              
51              
52             =item check_ldap_medium($medium)
53              
54             Checks if the ldap medium has all required attributes.
55              
56             =cut
57              
58             sub check_ldap_medium($) {
59             my ($medium) = @_;
60             return $medium->{name} && $medium->{url};
61             }
62              
63             sub get_vars_from_sh {
64             my ($filename) = @_;
65             my %l;
66             foreach (cat_($filename)) {
67             s/#.*//; s/^\s*//; s/\s*$//;
68             my ($key, $val) = /^(\w+)=(.*)/ or next;
69             $val =~ s/^(["'])(.*)\1$/$2/;
70             $l{$key} = $val;
71             }
72             %l;
73             }
74              
75             =item read_ldap_cache($urpm)
76              
77             Reads the cache created by the C function. Should be called
78             if the ldap server doesn't answer (upgrade, network problem, mobile user, etc.)
79              
80             =cut
81              
82             sub read_ldap_cache {
83             my ($urpm) = @_;
84             foreach (glob("$urpm->{cachedir}/ldap/*")) {
85             ! -f $_ and next;
86             my %medium = get_vars_from_sh($_);
87             next if !check_ldap_medium(\%medium);
88             urpm::media::add_existing_medium($urpm, \%medium, 'nocheck');
89             }
90             }
91              
92             =item clean_ldap_cache($urpm)
93              
94             Cleans the ldap cache, removes all files in the directory.
95              
96             =cut
97              
98             #- clean the cache, before writing a new one
99             sub clean_ldap_cache($) {
100             my ($urpm) = @_;
101             unlink glob("$urpm->{cachedir}/ldap/*");
102             }
103              
104              
105             =item get_ldap_config()
106              
107             parse the system LDAP configuration file and return its config values
108              
109             =cut
110              
111             sub get_ldap_config() {
112             return get_ldap_config_file($LDAP_CONFIG_FILE);
113             }
114              
115             =item get_ldap_config_file($file)
116              
117             parse a given LDAP configuration file and return its config values
118              
119             =cut
120              
121             sub get_ldap_config_file {
122             my ($file) = @_;
123             my %config;
124             foreach (cat_($file)) {
125             s/#.*//;
126             s/^\s*//;
127             s/\s*$//;
128             s/\s{2}/ /g;
129             /^$/ and next;
130             /^(\S*)\s*(\S*)/ && $2 or next;
131             $config{$1} = $2;
132             }
133             return %config && \%config;
134             }
135              
136              
137             =item get_ldap_config_dns()
138              
139             Not implemented yet.
140              
141             =cut
142              
143             sub get_ldap_config_dns() {
144             # TODO
145             die "not implemented yet\n";
146             }
147              
148             my %ldap_changed_attributes = (
149             'source-name' => 'name',
150             'with-hdlist' => 'with_hdlist',
151             'http-proxy' => 'http_proxy',
152             'ftp-proxy' => 'ftp_proxy',
153             'media-info-dir' => 'media_info_dir',
154             );
155              
156             =item load_ldap_media($urpm)
157              
158             Loads urpmi media configuration from ldap.
159              
160             =cut
161              
162             sub load_ldap_media {
163             my ($urpm) = @_;
164              
165             my $config = get_ldap_config() or return;
166              
167             $config->{ssl} = 'off';
168              
169             # try first urpmi_foo and then foo
170             foreach my $opt (qw(base uri filter host ssl port binddn passwd scope)) {
171             if (!defined $config->{$opt} && defined $config->{"urpmi_$opt"}) {
172             $config->{$opt} = $config->{"urpmi_$opt"};
173             }
174             }
175              
176             die N("No server defined, missing uri or host") if !(defined $config->{uri} || defined $config->{host});
177             die N("No base defined") if !defined $config->{base};
178              
179             if (! defined $config->{uri}) {
180             $config->{uri} = "ldap" . ($config->{ssl} eq 'on' ? "s" : "") . "://" .
181             $config->{host} . ($config->{port} ? ":" . $config->{port} : "") . "/";
182             }
183              
184             eval {
185             require Net::LDAP;
186             my $ldap = Net::LDAP->new($config->{uri})
187             or die N("Cannot connect to ldap uri:"), $config->{uri};
188              
189             $ldap->bind($config->{binddn}, $config->{password})
190             or die N("Cannot connect to ldap uri:"), $config->{uri};
191             #- base is mandatory
192             my $result = $ldap->search(
193             base => $config->{base},
194             filter => $config->{filter} || '(objectClass=urpmiRepository)',
195             scope => $config->{scope} || 'sub',
196             );
197              
198             $result->code and die $result->error;
199             # FIXME more than one server ?
200             clean_ldap_cache($urpm);
201              
202             foreach my $entry ($result->all_entries) {
203             my $medium = {};
204              
205             foreach my $opt (@per_media_opt, keys %ldap_changed_attributes) {
206             my $v = $entry->get_value($opt);
207             defined $v and $medium->{$opt} = $v;
208             }
209              
210             #- name is not valid for the schema ( already in top )
211             #- and _ are forbidden in attributes names
212              
213             foreach (keys %ldap_changed_attributes) {
214             $medium->{$ldap_changed_attributes{$_}} = $medium->{$_};
215             delete $medium->{$_};
216             }
217             #- add ldap_ to reduce collision
218             #- TODO check if name already defined ?
219             $medium->{name} = "ldap_" . $medium->{name};
220             $medium->{ldap} = 1;
221             next if !check_ldap_medium($medium);
222             urpm::media::add_existing_medium($urpm, $medium, 'nocheck');
223             write_ldap_cache($urpm,$medium);
224             }
225             };
226             if ($@) {
227             $urpm->{log}($@);
228             read_ldap_cache($urpm);
229             }
230              
231             }
232              
233             1;
234              
235              
236             =back
237              
238             =head1 COPYRIGHT
239              
240             Copyright (C) 2005 MandrakeSoft SA
241              
242             Copyright (C) 2005-2010 Mandriva SA
243              
244             Copyright (C) 2011-2017 Mageia
245              
246             =cut