getpwent#
להחזיר את הרשומה הבאה ממסד נתוני הסיסמאות של המערכת.
getpwent עובר על מסד נתוני הסיסמאות רשומה אחת בכל פעם. הקריאה הראשונה פותחת את מסד הנתונים (בדרך כלל /etc/passwd, אולי מועשר על־ידי NSS עם LDAP, SSSD, או דומה); כל קריאה עוקבת מחזירה את הרשומה הבאה. כאשר האיטרציה מותשת הקריאה מחזירה רשימה ריקה בהקשר רשימה או undef בהקשר סקלרי. יש לשייך עם setpwent להחזרת המצביע ועם endpwent לשחרור משאבים שספריית מסד הנתונים מחזיקה.
תקציר#
my @fields = getpwent;
my $name = getpwent; # scalar context: login name only
מה מקבלים בחזרה#
בהקשר רשימה, רשימה של 10 אלמנטים שמתארת חשבון אחד:
my ( $name, $passwd, $uid, $gid, $quota,
$comment, $gcos, $dir, $shell, $expire ) = getpwent;
# 0 1 2 3 4
# 5 6 7 8 9
$name- שם כניסה.$passwd- שדה הסיסמה המוצפן. במערכות עם shadow passwords זה בדרך כלל"x"או"*"אלא אם התהליך מורשה; ה־hash האמיתי מצוי ב־/etc/shadow. tainted תחת-T.$uid,$gid- מזהים מספריים של משתמש וקבוצה ראשית.$quota- מכסת דיסק במערכות שתומכות בכך, אחרת מחרוזת ריקה. בחלק מהמערכות חריץ זה נושא$changeאו$age(נתוני התיישנות סיסמה).$comment- הערה אדמיניסטרטיבית במערכות שתומכות בכך, אחרת ריק. בחלק מהמערכות חריץ זה נושא$class.$gcos- שדה GECOS, לפי המוסכמה שם אמיתי של המשתמש. ניתן לכתיבה על־ידי המשתמש במערכות רבות, ולכן tainted תחת-T.$dir- ספריית הבית.$shell- shell הכניסה. tainted תחת-T.$expire- תפוגת חשבון או סיסמה במערכות שתומכות בכך, אחרת נעדר.
בהקשר סקלרי, מוחזר רק שם הכניסה. כאשר האיטרציה מותשת הערך הסקלרי הוא undef וערך הרשימה ריק.
האם $quota, $comment, ו־$expire נושאים נתונים בעלי משמעות בבניה הנוכחית תלוי באופן בו Perl הוגדר; יש לבחון את הערכים Config d_pwquota, d_pwage, d_pwchange, d_pwcomment, ו־d_pwexpire כדי לגלות.
מצב גלובלי שהוא נוגע בו#
getpwent שומר את הסמן שלו בבלוק מצב רוחב־תהליך, בבעלות הספריה בתוך השגרות pwd של ספריית C. השלכות:
שתי לולאות עצמאיות על מסד הנתונים באותו תהליך מפריעות זו לזו. כל
getpwentמקדם את הסמן המשותף היחיד.setpwentמחזיר את הסמן הזה להתחלה.endpwentסוגר את מסד הנתונים ומשליך כל משאבים (descriptor של קבצים פתוחים, מצב מודול NSS) שהספריה החזיקה.Threads משתפים את הסמן גם הם.
getpwentאינו בטוח לקריאה במקביל ממספר threads; אם שני threads עוברים במקביל, אף אחד מהם לא רואה את כל הרשומות.
getpwent אינו קורא או כותב משתנים מיוחדים כלשהם של Perl.
דוגמאות#
לפלוט כל שם חשבון וספריית בית:
while ( my @pw = getpwent ) {
print "$pw[0]\t$pw[7]\n";
}
endpwent;
פירוק לשדות נקובי־שם נקרא בבירור רב יותר מאינדוקס מספרי:
while ( my ($name, undef, $uid, $gid, undef, undef, $gcos, $dir) = getpwent ) {
next if $uid < 1000; # skip system accounts
print "$name ($gcos) uid=$uid home=$dir\n";
}
endpwent;
הקשר סקלרי מניב את שם הכניסה, שימושי למניית משתמשים מבלי לפרוק את השאר:
my @users;
while ( defined( my $name = getpwent ) ) {
push @users, $name;
}
endpwent;
להחזיר את המצביע באמצע מעבר עם setpwent:
my @first_pass = (getpwent)[0];
setpwent; # back to the top
while ( my @pw = getpwent ) { ... }
endpwent;
לאסוף את כל הרשומות לתוך האש שמומפתח לפי uid, ואז לשחרר את מסד הנתונים:
my %by_uid;
while ( my @pw = getpwent ) {
$by_uid{ $pw[2] } = \@pw;
}
endpwent;
מקרי קצה#
סוף איטרציה: מחזיר רשימה ריקה בהקשר רשימה ו־
undefבהקשר סקלרי.while (my @pw = getpwent)ו־while (defined(my $name = getpwent))הן צורות הלולאה המקובלות.שכחת
endpwent: מדליפה descriptor של קבצים או מצב NSS שהספריה פתחה עד שהתהליך יוצא. לא באג של נכונות, אך מורגש בתוכניות ארוכות־חיים וברתמות בדיקה.איטרציה מקוננת שבורה: שתי לולאות באותו תהליך חולקות את הסמן היחיד של הספריה. יש לאסוף מעבר אחד למבנה נתונים לפני התחלת הבא.
Shadow passwords: ב־Linux וב־Solaris ה־hash האמיתי של הסיסמה נמצא ב־
/etc/shadow, ניתן לקריאה רק על־ידי root. תהליכים לא־מורשים רואים"x"או"*"ב־$passwdוחייבים לקרוא לשגרות shadow-aware (מחוץ ל־core Perl) כדי לקבל את ה־hash.הפתעות NSS: מסד הנתונים הוא מה ש־
/etc/nsswitch.confאומר שהוא. על מארח שקשור ל־LDAP או SSSD,getpwentעשוי להחזיר אלפי חשבונות directory, לקחת זמן מורגש, ולהיכשל לסירוגין אם הרשת לא־יציבה. כדאי לשקול חיפוש חשבונות לפי שם עםgetpwnamכאשר ידוע איזה רוצים.Tainting תחת
-T:$passwd,$gcos, ו־$shellחוזרים tainted מכיוון שמשתמשים יכולים להשפיע עליהם. יש לבצע untaint עם התאמת regex מכוונת אם נדרש להשתמש בהם בפעולות רגישות.בטיחות thread: שלא כמו
getpwnamו־getpwuid, איןgetpwent_rב־POSIX ש־Perl יכול להחליף בשקיפות. איטרציה במקביל ממספר threads אינה בטוחה.ממשק לפי־שם:
User::pwentעוקף אתgetpwentבגרסה שמחזירה עצם שחושף שדות כמתודות ($pw->name,$pw->uid, …). יש להשתמש בו כאשר פירוק החריצים המספריים הופך למסורבל.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
getpwnam- לחפש חשבון אחד לפי שם כניסה; הקריאה הנכונה כאשר ידוע איזה משתמש רוציםgetpwuid- לחפש חשבון אחד לפי uid מספריsetpwent- להחזיר את הסמן שלgetpwentלרשומה הראשונהendpwent- לסגור את מסד נתוני הסיסמאות ולשחרר משאבי ספריה; יש לקרוא לו כאשר המעבר הסתייםgetgrent- המקבילה של מסד נתוני הקבוצות, אותו מודל איטרציהUser::pwent- ממשק לפי־שם שמחזיר עצם עם accessors נקובי־שם במקום רשימה של 10 אלמנטים