|
|||||||||||||||||||||||||||
Ole Tange <sslug@sslug> writes:
> På min gamle Redhat 5 kan jeg gøre:
>
> strace -ff perl -e 'while(@a=getpwent()){}'
>
> Dette viser, at perl læser /etc/passwd een gang. På Mandrake 8 og på
> Gentoo 1.4 viser oventstående, at den læser /etc/shadow n gange (n =
> antallet af brugere). Dette er mildest talt ikke effektivt, hvis man gerne
> lige vil løbe alle brugere igennem.
>
> Hvordan får jeg getpwent til at opføre sig som i gamle dage?
>
> (Jeg kan kopiere den gamle binære /usr/bin/perl og opnå den gamle effekt -
> men der må være en pænere måde at gøre det på.)
Den er nødt til at virke på den måde for at fungere korrekt[1] med
shadow passwords. Nedenstående C program illustrerer hvordan jeg tror
perl gør.
#include <stdio.h>
#include <string.h>
#include <pwd.h>
int main(int argc, char * argv[])
{
struct passwd * pass;
while(pass = getpwent()){
char * passwd = NULL;
struct passwd * shadow_pass;
FILE * shadow = NULL;
if(strcmp(pass->pw_passwd,"x") == 0)
shadow = fopen("/etc/shadow", "r");
if(shadow){
while(shadow_pass = fgetpwent(shadow)){
if(strcmp(shadow_pass->pw_name, pass->pw_name) == 0){
passwd = shadow_pass->pw_passwd;
break;
}
}
fclose(shadow);
}
printf("%s:%s:%d:%d:%s:%s:%s\n", pass->pw_name,
passwd ? passwd : pass->pw_passwd,
pass->pw_uid, pass->pw_gid, pass->pw_gecos, pass->pw_dir,
pass->pw_shell);
}
endpwent();
return 0;
}
At man skal åbne /etc/shadow (hvis man må), søge den igennem og lukke
den bagefter, er et nødvendigt onde for ikke at efterlade åbne
filehandles. Det er der to grunde til, fendpwent() findes ikke og man
kan nok ikke garantere at indgangene i /etc/shadow er i samme
rækkefølge som i /etc/passwd.
At perl så gør det arbejde for en, som man er nødt til at gøre selv i
C, kan man så mene er godt eller skidt...jeg kan godt se det kan blive
et problem hvis der er mange brugere og man er root.
[1] Dvs. som hvis der IKKE var shadow passwords, altså på den gamle
måde med de hashede passwords direkte /etc/passwd
--
Christian Hemmingsen
|
||||||||||||||
|
||||||||||||||