מידע משתמש וקבוצה

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 אלמנטים