Initial revision
[freeside.git] / bin / svc_acct.import
1 #!/usr/bin/perl -Tw
2 #
3 # ivan@sisd.com 98-mar-9
4 #
5 # changed 'password' field to '_password' because PgSQL 6.3 reserves this word
6 #       bmccane@maxbaud.net  98-Apr-3
7 #
8 # generalized svcparts (still needs radius import) ivan@sisd.com 98-mar-23
9 #
10 # radius import, now an interactive script.  still needs erpcd import?
11 # ivan@sisd.com 98-jun-24
12 #
13 # arbitrary radius attributes ivan@sisd.com 98-aug-9
14 #
15 # don't import /var/spool/freeside/conf/shells!  ivan@sisd.com 98-aug-13
16
17 use strict;
18 use vars qw(%part_svc);
19 use Date::Parse;
20 use FS::SSH qw(iscp);
21 use FS::UID qw(adminsuidsetup);
22 use FS::Record qw(qsearch);
23 use FS::svc_acct;
24
25 adminsuidsetup;
26
27 #my($spooldir)="/var/spool/freeside/export";
28 my($spooldir)="unix/";
29
30 $FS::svc_acct::nossh_hack = 1;
31
32 ###
33
34 %part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'});
35
36 print "\n\n", &menu_svc, "\n", <<END;
37 Most accounts probably have entries in passwd and users (with Port-Limit
38 nonexistant or 1).
39 END
40 my($ppp_svcpart)=&getpart;
41
42 print "\n\n", &menu_svc, "\n", <<END;
43 Some accounts have entries in passwd and users, but with Port-Limit 2 (or
44 more).
45 END
46 my($isdn_svcpart)=&getpart;
47
48 print "\n\n", &menu_svc, "\n", <<END;
49 Some accounts might have entries in users only (Port-Limit 1)
50 END
51 my($oppp_svcpart)=&getpart;
52
53 print "\n\n", &menu_svc, "\n", <<END;
54 Some accounts might have entries in users only (Port-Limit >= 2)
55 END
56 my($oisdn_svcpart)=&getpart;
57
58 print "\n\n", &menu_svc, "\n", <<END;
59 POP mail accounts have entries in passwd only, and have a particular shell.
60 END
61 print "Enter that shell: ";
62 my($pop_shell)=&getvalue;
63 my($popmail_svcpart)=&getpart;
64
65 print "\n\n", &menu_svc, "\n", <<END;
66 Everything else in passwd is a shell account.
67 END
68 my($shell_svcpart)=&getpart;
69
70 print "\n\n", <<END;
71 Enter the location and name of your _user_ passwd file, for example
72 "mail.isp.com:/etc/passwd" or "nis.isp.com:/etc/global/passwd"
73 END
74 print ":";
75 my($loc_passwd)=&getvalue;
76 iscp("root\@$loc_passwd", "$spooldir/passwd.import");
77
78 print "\n\n", <<END;
79 Enter the location and name of your _user_ shadow file, for example
80 "mail.isp.com:/etc/shadow" or "bsd.isp.com:/etc/master.passwd"
81 END
82 print ":";
83 my($loc_shadow)=&getvalue;
84 iscp("root\@$loc_shadow", "$spooldir/shadow.import");
85
86 print "\n\n", <<END;
87 Enter the location and name of your radius "users" file, for example
88 "radius.isp.com:/etc/raddb/users"
89 END
90 print ":";
91 my($loc_users)=&getvalue;
92 iscp("root\@$loc_users", "$spooldir/users.import");
93
94 sub menu_svc {
95   ( join "\n", map "$_: ".$part_svc{$_}->svc, sort keys %part_svc ). "\n";
96 }
97 sub getpart {
98   print "Enter part number, or 0 for none: ";
99   &getvalue;
100 }
101 sub getvalue {
102   my($x)=scalar(<STDIN>);
103   chop $x;
104   $x;
105 }
106
107 print "\n\n";
108
109 ###
110
111 open(PASSWD,"<$spooldir/passwd.import");
112 open(SHADOW,"<$spooldir/shadow.import");
113 open(USERS,"<$spooldir/users.import");
114
115 my(%upassword,%ip,%allparam);
116 my(%param,$username);
117 while (<USERS>) {
118   chop;
119   next if /^$/;
120   if ( /^\S/ ) {
121     /^(\w+)\s+Password\s+=\s+"([^"]+)"(,\s+Expiration\s+=\s+"([^"]*")\s*)?$/
122       or die "1Unexpected line in users.import: $_";
123     my($password,$expiration);
124     ($username,$password,$expiration)=(lc($1),$2,$4);
125     $upassword{$username}=$password;
126     undef %param;
127   } else {
128     die "2Unexpected line in users.import: $_";
129   }
130   while (<USERS>) {
131     chop;
132     if ( /^\s*$/ ) {
133       $ip{$username}=$param{'radius_Framed_IP_Address'}||'0e0';
134       delete $param{'radius_Framed_IP_Address'};
135       $allparam{$username}={ %param };
136       last;
137     } elsif ( /^\s+([\w\-]+)\s=\s"?([\w\.\-\s]+)"?,?\s*$/ ) {
138       my($attribute,$value)=($1,$2);
139       $attribute =~ s/\-/_/g;
140       $param{'radius_'.$attribute}=$value;
141     } else {
142       die "3Unexpected line in users.import: $_";
143     }
144   }
145 }
146 #? incase there isn't a terminating blank line ?
147 $ip{$username}=$param{'radius_Framed_IP_Address'}||'0e0';
148 delete $param{'radius_Framed_IP_Address'};
149 $allparam{$username}={ %param };
150
151 my(%password);
152 while (<SHADOW>) {
153   chop;
154   my($username,$password)=split(/:/);
155   $password{$username}=$password;
156 }
157
158 while (<PASSWD>) {
159   chop;
160   my($username,$x,$uid,$gid,$finger,$dir,$shell)=split(/:/);
161   my($password)=$upassword{$username} || $password{$username};
162
163   my($maxb)=${$allparam{$username}}{'radius_Port_Limit'};
164   my($svcpart);
165   if ( exists $upassword{$username} ) {
166     if ( $maxb >= 2 ) {
167       $svcpart = $isdn_svcpart
168     } elsif ( ! $maxb || $maxb == 1 ) {
169       $svcpart = $ppp_svcpart
170     } else {
171       die "Illegal Port-Limit in users ($username)!\n";
172     }
173   } elsif ( $shell eq $pop_shell ) {
174     $svcpart = $popmail_svcpart;
175   } else {
176     $svcpart = $shell_svcpart;
177   }
178
179   my($svc_acct) = create FS::svc_acct ({
180     'svcpart'  => $svcpart,
181     'username' => $username,
182     'password' => $password,
183     'uid'      => $uid,
184     'gid'      => $gid,
185     'finger'   => $finger,
186     'dir'      => $dir,
187     'shell'    => $shell,
188     'slipip'   => $ip{$username},
189     %{$allparam{$username}},
190   });
191   my($error);
192   $error=$svc_acct->insert;
193   die $error if $error;
194
195   delete $allparam{$username};
196   delete $upassword{$username};
197 }
198
199 #my($username);
200 foreach $username ( keys %upassword ) {
201   my($password)=$upassword{$username};
202
203   my($maxb)=${$allparam{$username}}{'radius_Port_Limit'} || 0;
204   my($svcpart);
205   if ( $maxb == 2 ) {
206     $svcpart = $oisdn_svcpart
207   } elsif ( ! $maxb || $maxb == 1 ) {
208     $svcpart = $oppp_svcpart
209   } else {
210     die "Illegal Port-Limit in users!\n";
211   }
212
213   my($svc_acct) = create FS::svc_acct ({
214     'svcpart'  => $svcpart,
215     'username' => $username,
216     'password' => $password,
217     'slipip'   => $ip{$username},
218     %{$allparam{$username}},
219   });
220   my($error);
221   $error=$svc_acct->insert;
222   die $error, if $error;
223
224   delete $allparam{$username};
225   delete $upassword{$username};
226 }
227