001 #!/usr/bin/perl 002 #It's already too late to do that check here, but at least try to print a 003 #warning 004 if ($> != $<) 005 { 006 print "Must not run with Set-UID bit set\n"; 007 exit; 008 } 033 #We need to be root at startup so we can bind to the ident port. 034 if ($< != 0) 035 { 036 print "Need to be root to bind to the ident port\n"; 037 exit; 038 } 039 chdir("/") or die "Can not change working directory"; 057 if ($file =~ /^[^-'][^']*\.hash$/) 058 { 059 $usefile=$file; 060 } 066 open(STR1,"/usr/bin/strings /usr/lib/ispell/'$usefile'|")||die "Can't start strings"; 152 ($pnam,$dummy,$myuid,$mygid)=getpwnam("nobody"); 158 #Just in case O_NOFOLLOW is not supported we double check. 159 if (-l "/tmp/rident.pid") { 161 exit; 162 } elsif (sysopen(PID,"/tmp/rident.pid",O_RDONLY | O_NOFOLLOW)) { 163 $oldpid = 0; 164 ($pfuid,$pfgid) = (stat(PID))[4,5] or die "PANIC: Can not stat open pidfile"; 165 unless ($pfuid == $myuid || $pfgid == $mygid) 166 { 168 exit; 169 } else { 170 #See if the file was already written. 171 seek(PID,0,SEEK_END); 172 $size=tell(PID); 173 seek(PID,0,SEEK_SET); 175 if ($size > 0 && $size < 100) { 177 sysread(PID,$oldpid,$size,0); 178 chomp $oldpid; 179 unless ($oldpid =~ /^\d+$/) 180 { 182 exit; 183 } 184 $oldpid +=0; 185 } else { 186 &dprint("* PID file is corrupt\n"); 187 exit; 188 } 189 } 190 close(PID); 191 #Now let's test if the found pid is really our old instance. 192 $killit=0; 193 if ($oldpid) 194 { 196 open(PS,"/bin/ps -p '$oldpid'|"); 197 $killit=0; 198 while () 199 { 200 if (/\bridentd\.pl\b/) 201 { 202 $killit=$oldpid; 203 } 204 } 205 unless ($killit) 206 { 207 &dprint("* pid file apears to be old\n"); 208 } else { 209 #We need to kill the old process, but we are root and thus to powerfull. 210 $tpid=fork(); 211 unless (defined($tpid)) { 212 print "ERR: Forking error\n"; 213 exit; 214 } 215 if ($tpid) { 216 #The parent remains root and must wait for the child process. 217 &dprint("* Started background process to kill old instance safely\n"); 218 waitpid($tpid,0); 219 &dprint("* Background process finished.\n"); 220 sleep(1); 221 } else { 222 unless ($)=$mygid) {print "Cleanup Unable to set group ID to $mygid\n";exit;} 223 unless ($>=$myuid) {print "Cleanup Unable to set user ID to $myuid\n";exit;} 224 kill(9,$killit); 225 exit; 226 } 227 } 228 } 229 } 237 unlink("/tmp/rident.pid"); 241 unless (sysopen(PID,"/tmp/rident.pid",O_RDWR | O_CREAT | O_EXCL, 0600)) { 242 print "PANIC: Could not create the pid file /tmp/rident.pid $! $?\n"; 243 exit; 244 } 246 $pid=fork(); 252 if ($pid) 253 { 254 # parent 255 unless (syswrite(PID,"$pid\n",length("$pid\n"))) { 257 close(PID); 258 kill(9,$pid); 259 } 260 exit; 261 }