6d90651a |
1 | #!/usr/bin/perl |
2 | |
3 | $etcdir= '/etc/userv/ipif'; |
4 | chdir($etcdir) or die "$0: chdir $etcdir: $!\n"; |
5 | |
6 | $descallowd= '-][()+_\'":=;,./|'; |
7 | |
8 | sub usage () { |
9 | die <<END; |
10 | Allocates an RFC1918 address and records it |
11 | usage: userv ipif-alloc <group|gid> [<prefix>]/<size> <description> |
12 | <description> may contain alphanums, spaces and $descallowed |
13 | END |
14 | } |
15 | |
16 | @ARGV==3 or usage(); |
17 | ($group, $pfxsize, $desc) = @ARGV; |
18 | |
19 | $super= 0; |
20 | |
21 | open X, "config" or die "$0: open config: $!\n"; |
22 | while (<X>) { |
23 | next if m/^\#/; |
24 | next if !m/\S/; |
25 | chomp; s/\s+$//; |
26 | if (m/^supergroup\s+(\w+)$/) { |
27 | $super= am_gid($1); |
28 | } elsif (m/^maxpergid\s+(\d+)$/) { |
29 | $maxpergid= $1; |
30 | } elsif (m,^range\s+([.0-9]+)/(\d+)$,) { |
31 | ($allow_p, $allow_m, $allow_l) = parse_range($1,$2); |
32 | } else { |
33 | die "$0: config:$.: unknown directive: $_\n"; |
34 | } |
35 | } |
36 | close X or die "$0: read config: $!\n"; |
37 | |
38 | if ($pfxsize =~ m,^([.0-9]+)/(\d+)$,) { |
39 | ($want_p, $want_m, $want_l) = parse_range($1,$2); |
40 | if (!$super && !overlap($want_p,$want_m, $allow_p,$allow_m)) { |
41 | die "$0: permission denied (out of required range)\n"; |
42 | } |
43 | } elsif ($pfxsize =~ m,^/(\d+)$,) { |
44 | undef $want_p; |
45 | undef $want_m; |
46 | $want_l= $1; |
47 | } else { |
48 | die "$0: bad request: $pfxsize\n"; |
49 | } |
50 | |
51 | $gid= get_gid($group); |
52 | if (!am_gid($gid)) { |
53 | die "$0: you are not gid $gid\n"; |
54 | } |
55 | |
56 | $op.= ''; |
57 | $max_p= 0; $max_m= 0; |
58 | |
59 | open Y, "auto-nets" or die "$0: open auto-nets: $!\n"; |
60 | for (;;) { |
61 | $!= 0; chomp($_= <Y>); |
62 | length or die "$0: read auto-nets: $!\n"; |
63 | last if m/^\#end/; |
64 | next if m/^\#/; |
65 | $op.= $_."\n"; |
66 | m:^(\d+),([.0-9]+)/(\d+),.*: or die "$0: auto-nets:$.: syntax error: $_\n"; |
67 | $this_gid= $1; |
68 | ($this_p, $this_m, $this_l) = parse_range($2,$3); |
69 | if (defined($want_p)) { |
70 | if (overlap($want_p,$want_m, $this_p,$this_m)) { |
71 | die "$0: overlaps with existing allocation (auto-nets:$.)\n"; |
72 | } |
73 | } else { |
74 | if ($this_p > $max_p) { |
75 | ($this_p,$this_m) = ($max_p,$max_m); |
76 | } |
77 | } |
78 | |
79 | |
80 | next if $1 ne $gid; |
81 | |