Use shift for VSAs instead of OR
[freeradius.git] / scripts / users2mysql.pl
1 #!/usr/bin/perl -w
2 #
3 # users2mysql.pl -- a script to parse a RADIUS users file and fill
4 #                   a freeradius mysql database...
5 #
6 #
7 # Script developed by Rich Puhek, Znet Telecom
8 #
9 # last change: Aug 8th, 2002.
10 #
11
12
13
14 #Modify to suit your db.
15 $database="radius";
16 $hostname="localhost";
17 $user="radius";
18 $password="passwd";
19
20
21 #location of source users file:
22 $users_file="/etc/raddb_cistron_backup/users";
23
24
25 #The following are defaults from freeradius 0.7
26 #  ...shouldn't have to change.
27 $groups_table="usergroup";
28 $check_table="radcheck";
29 $reply_table="radreply";
30
31 $debug=3;
32
33 use DBD::mysql;
34
35 #open the users file, and the db.
36 open USERS, $users_file or die "ERROR: Unable to open $users_file $!\n";
37 $database = DBI->connect("DBI:mysql:$database:$hostname",$user, $password) or die "ERROR: Unable to connect to $database on $hostname $!\n";
38
39 sub check_attribs {
40
41         if (!defined($_[0]) or !defined($_[1])) {
42                 print "undefined parameter!\n";
43                 return undef;
44         };
45
46         $attr = $_[0];
47         $val  =  $_[1];
48
49         if ($attr !~ /Password|Framed-IP-Address|Framed-IP-Netmask|Framed-IP-Routing|Framed-Routing|Framed-IP-Route|Password|Simultaneous-Use|Idle-Timeout|Auth-Type|Service-Type|Netmask|Framed-Protocol/ ) {
50                 print "unrecognized attribute: $attr\n" if $debug>1;
51                 return undef;
52         };
53
54         return undef if (       (! defined($val) ) or
55                 ( ($attr =~ /Simultaneous\-Use/i) && ( $val !~ /^[0-9]*$/ ) )
56                 );
57         print "attribs ok!\n" if $debug>3;
58         return "TRUE";
59 };
60
61 sub cleanup {
62         #clean up variables: strip leading/trailing spaces and trailing commas...
63         my $myval;
64         $myval = $_[0];
65         $myval =~ s/^\s//g;
66         $myval =~ s/\s$//g;
67         $myval =~ s/,$//;
68         return $myval;
69 };
70
71
72 sub user_attribute {
73         #push values into db...
74         $dtable=$_[0];
75         $duser=$_[1];
76         $dattrib=$_[2];
77         $dval=$_[3];
78
79         print "inserting \"$dattrib\", \"$dval\" for \"$duser\" in rad$dtable\n" if ( $dtable !~ /group/ and $debug>2);
80         print "inserting \"$duser\" into usergroup table as member of \"$dattrib\"\n" if ( $dtable =~ /group/ and $debug>2);
81
82         if ( $dtable =~ /group/ ) {
83                 $table = "usergroup";
84         } elsif ( $dtable =~ /check/ ) {
85                 $table = "radcheck";
86         } elsif ( $dtable =~ /reply/ ) {
87                 $table = "radreply";
88         } else {
89                 die "argh! what table is $dtable?\n";
90         };
91
92
93         if ( $table =~ /usergroup/ ) {
94                 if ( $dattrib =~ /static/ ) {
95                         #Delete the "dynamic" entry...
96                         $return = $database->do ("DELETE FROM `$table` WHERE `UserName`='$duser' LIMIT 1");
97                 };
98                 $return = $database->do ("INSERT INTO `$table` SET `UserName`='$duser',`GroupName`='$dattrib'");
99
100         } else {
101                 $return = $database->do ("INSERT INTO `$table` SET `UserName`='$duser',`Attribute`='$dattrib',`Value`='$dval', `op`=':='");
102         };
103         return $return;
104 };
105
106
107 while (<USERS>) {
108
109         chop;
110         #Skip comment lines and blank lines...
111         next if ( /^\#/ );
112         next if ( /^$/ );
113         next if ( /^\s*$/ );
114
115         if ( /^[a-zA-Z0-9]+/ ) {
116                 print "located a user entry: $_\n" if $debug>6;
117                 ($user,$rest) = split /\s/, $_, 2;
118                 #Put user into usergroup as dynamic, if the user's attributes
119                 # include an IP address, the script will change that later...
120                 user_attribute("group",$user,"dynamic","");
121                 @attribs = split /,/, $rest;
122         } else {
123                 # Already found the user, now finding attributes...
124                 @attribs = $_;
125         };
126
127         foreach $attr (@attribs) {
128                 ($attrib,$value) = split /=/, $attr, 2;
129                 #TODO: insert sanity checks here!
130                 $value  = cleanup($value)  if (defined($value));
131                 $attrib = cleanup($attrib) if (defined($attrib));
132                 unless (check_attribs($attrib,$value)) {
133                         print "ERROR: something bad with line $.: \"$attrib\", \"$value\"\n";
134                         next;
135                 };
136                 print "attrib: $attrib has value: $value\n" if $debug>8;
137
138                 if ( $attrib =~ /Framed-IP-Address/ ) {
139                         #user is a static IP user...
140                         $static{$user} = 1;
141                         user_attribute("group",$user,"static","");
142                 };
143
144                 if ( $attrib =~ /Password|Simultaneous-Use/ ) {
145                         #This is an individual check attribute, so we'll pass it along...
146                         user_attribute("check",$user,$attrib,$value);
147                 };
148                 if ( $attrib =~ /Framed-IP-Address|Framed-IP-Routing|Framed-Routing/ ) {
149                         #This is an individual reply attribute, so we'll pass this along...
150                         user_attribute("reply",$user,$attrib,$value);
151                 };
152         };
153
154 };
155
156 close USERS;
157 exit($database->disconnect);