2 # fixscript will replace this line with require innshellvars.pl
5 ## Sample code for the nnrpd Perl access hooks.
7 ## This file is loaded when a perl_access: parameter is reached in
8 ## readers.conf. If it defines a sub named access, which will be
9 ## called during processing of a perl_access: parameter. Attributes
10 ## about the connection are passed to the program in the %attributes
11 ## global variable. It should return a hash containing
12 ## parameter-value pairs for the access group. If there is a problem,
13 ## nnrpd will die and syslog the exact error.
15 ## The default behavior of the following code is to look for nnrp.access
16 ## in INN's configuration file directory and to attempt to implement about
17 ## the same host-based access control as the previous nnrp.access code in
18 ## earlier versions of INN. This may be useful for backward compatibility.
20 ## This file cannot be run as a standalone script, although it would be
21 ## worthwhile to add some code so that it could so that one could test the
22 ## results of various authentication and connection queries from the
23 ## command line. The #! line at the top is just so that fixscript will
26 # This function is called when perl_access: is reached in readers.conf.
27 # For details on all the information passed to it, see
28 # ~news/doc/hook-perl.
30 &loadnnrp($inn::newsetc . '/nnrp.access');
31 return &checkhost($attributes{hostname}, $attributes{ipaddress});
34 # Called at startup, this loads the nnrp.access file and converts it into a
35 # convenient internal format for later queries.
38 my ($block, $perm, $user, $pass);
40 open (ACCESS, $file) or die "Could not open $file: $!\n";
47 ($block, $perm, $user, $pass, $tmp{groups}) = split /:/;
48 next unless (defined $tmp{groups});
50 # We don't support username/password entries, so be safe.
51 next if ($user || $pass);
53 # Change the wildmat pattern to a regex (this isn't thorough, as
54 # some ranges won't be converted properly, but it should be good
55 # enough for this purpose).
56 if ($block !~ m%^(?:\d+\.){3}\d+/\d+$%) {
63 $tmp{canread} = ($perm =~ /r/i);
64 $tmp{canpost} = ($perm =~ /p/i);
66 unshift(@hosts, { %tmp });
71 # Given the hostname and IP address of a connecting host, use our @hosts
72 # array constructed from nnrp.access and see what permissions that host has.
78 my ($read, $post) = ($key->{canread}, $key->{canpost});
80 # First check for CIDR-style blocks.
81 if ($key->{block} =~ m%^(\d+\.\d+\.\d+\.\d+)/(\d+)$%) {
82 my $block = unpack('N', pack('C4', split(/\./, $1)));
83 my $mask = (0xffffffff << (32 - $2)) & 0xffffffff;
84 $block = $block & $mask;
85 my $packedip = unpack('N', pack('C4', split(/\./, $ip)));
86 if (($packedip & $mask) == $block) {
88 $return_hash{"read"} = $key->{groups};
91 $return_hash{"post"} = $key->{groups};
97 if ($ip =~ /^$key->{block}$/) {
99 $return_hash{"read"} = $key->{groups};
102 $return_hash{"post"} = $key->{groups};
107 if ($host =~ /^$key->{block}$/) {
109 $return_hash{"read"} = $key->{groups};
112 $return_hash{"post"} = $key->{groups};
118 # If we fell through to here, nothing matched, so we should deny