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

getpwuid#

מאתר את רשומת ה־passwd של משתמש לפי UID מספרי.

getpwuid עוטף את קריאת getpwuid(3) של ספריית ה־C של המערכת. העבירו מזהה משתמש מספרי כמו 0 או $<; תקבלו בחזרה את רשומת ה־passwd של אותו משתמש, או רשימה ריקה / undef אם UID כזה לא קיים. צורת ההחזרה תלויה בהקשר: הקשר רשימה נותן את כל שדות הרשומה; הקשר סקלרי נותן ערך שימושי אחד - עבור getpwuid ספציפית, שם ההתחברות.

תקציר#

getpwuid UID

מה מקבלים בחזרה#

הקשר רשימה מחזיר רשימה בת 10 אלמנטים המשקפת struct passwd מורחבת ב־BSD extras - אותה צורה ש־getpwnam מחזיר:

my ($name,    $passwd, $uid,  $gid,   $quota,
    $comment, $gcos,   $dir,  $shell, $expire) = getpwuid($uid);
  • $name - שם התחברות

  • $passwd - סיסמה מוצפנת, או "x" / "*" במערכות shadow-password. מוכתם תחת -T.

  • $uid - מזהה משתמש מספרי (אותו מספר שהעברתם)

  • $gid - מזהה קבוצה ראשי מספרי

  • $quota - מכסת דיסק, או $change / $age במערכות מסוימות. מחרוזת ריקה כשלא נתמך.

  • $comment - הערה אדמיניסטרטיבית, לפעמים $class. מחרוזת ריקה כשלא נתמך.

  • $gcos - שדה GECOS (בדרך כלל השם האמיתי בתוספת מידע משתמש אחר). מוכתם תחת -T כי משתמשים יכולים לערוך אותו.

  • $dir - ספריית הבית

  • $shell - login shell. מוכתם תחת -T.

  • $expire - תפוגת חשבון / סיסמה, כשנתמך.

הקשר סקלרי מחזיר רק את $name (שם ההתחברות). עבור getpwuid - איתור לפי UID - הקשר סקלרי נותן לכם ״את הדבר האחר״, תואם את הכלל שהמקור מתעד עבור כל הפונקציות getpw* / getgr* / gethost* / getnet* / getproto* / getserv*.

בכשל איתור שני ההקשרים מחזירים רשימה ריקה / undef. תמיד בדקו את ערך ההחזרה לפני פירוק.

מצב גלובלי שהוא נוגע בו#

  • קובע את $! בכשל קריאת מערכת (נדיר - ״UID לא נמצא״ אינו כשל, זו החזרה ריקה).

  • קורא את $< ו־$> באופן מובלע רק כשמעבירים אותם, אך הניב הנפוץ getpwuid($<) הוא מה שהופך את משתנה ה־real-UID המיוחד לרשומה שימושית.

  • תחת -T (מצב taint), $passwd, $gcos, ו־$shell חוזרים מוכתמים. ראו perlsec כיצד לכבסם.

  • חולק את אותו מצב איטרטור בסיסי עם getpwent, setpwent, ו־endpwent. קריאת getpwuid אינה מפריעה ללולאת getpwent בעיצומה ב־glibc, אבל קוד נייד לא צריך להניח זאת.

דוגמאות#

איתור בסיסי UID־לשם בהקשר סקלרי:

my $name = getpwuid(0);             # "root"

״תחת איזה משתמש אני רץ״ - הניב הקנוני של getpwuid, הפותר את ה־UID האמיתי לשם התחברות:

my $me = getpwuid($<);              # e.g. "alice"

שלבו עם getlogin לקבלת שרשרת fallback אמינה השורדת תהליכים מנותקים ו־sessions של su:

my $login = getlogin() || getpwuid($<) || "unknown";

getlogin קורא את רשומת ה־tty השולטת ויכול לשקר (או להחזיר ריק) כשאין tty; getpwuid($<) עונה מה־UID הרשום של הקרנל ותמיד עובד.

רשומה מלאה בהקשר רשימה, עם בדיקה הגנתית:

my @pw = getpwuid($uid)
    or die "uid $uid: not in passwd database";
my ($name, undef, undef, $gid, undef, undef, $gcos, $home, $shell) = @pw;
print "$name ($uid) -> $home, shell $shell\n";

מעבר UID → שם קבוצה דרך השדה $gid:

my $gid      = (getpwuid($<))[3];
my $groupnam = getgrgid($gid);

גישה בסגנון עצם דרך הדריסה של User::pwent, שימושי כשרוצים accessors בעלי שם במקום לספור מיקומי רשימה:

use User::pwent;
my $pw = getpwuid($<);
printf "%s lives in %s, runs %s\n", $pw->name, $pw->dir, $pw->shell;

use User::pwent מחליף את getpwuid בגרסה המחזירה עצם ש־blessed עליו עם accessors ->name, ->uid, ->gid, ->dir, ->shell. שתי הצורות אינן מתערבבות: בתוך תחום אחד השתמשו או בדריסה או בפנימי, לא בשניהם.

מקרי קצה#

  • UID כזה לא קיים מחזיר רשימה ריקה בהקשר רשימה ו־undef בהקשר סקלרי. זו אינה שגיאה - $! אינו נקבע. הבחינו בין ״UID חסר״ ל־״האיתור נכשל״ על־ידי בדיקת $! רק כשרוצים לדווח על כשל בלתי־צפוי, לא כשמחליטים האם ה־UID קיים.

  • $passwd רק לעיתים רחוקות שימושי. במערכות Linux ו־BSD מודרניות ההאש האמיתי חי ב־/etc/shadow, קריא רק לשורש. תקבלו "x" או "*" כאן. השתמשו ב־PAM או במודול Authen::PAM לאימות במקום להשוות מול שדה זה.

  • ניידות $quota, $comment, $expire. שדות אלה ריקים או חסרי משמעות ב־Linux. ה־POD של המקור מפרט ערכי Config (d_pwquota, d_pwage, d_pwchange, d_pwcomment, d_pwexpire) שניתן לבדוק אם יש צורך לדעת בזמן ריצה האם הפלטפורמה מאכלסת אותם.

  • שדות מוכתמים תחת -T. $passwd, $gcos, $shell מוכתמים כי משתמשים יכולים לשנותם (דרך chsh, chfn, או עריכות ישירות של /etc/passwd בהקשרים מורשים). העבירו אותם דרך לכידת regex כדי לכבסם לפני שימוש בקריאת מערכת.

  • החזרה סקלרית עבור UID 0 לעולם אינה שקר. בניגוד ל־getpwnam, שהחזרתו הסקלרית עבור root היא ה־UID 0 (ערך שקר), ההחזרה הסקלרית של getpwuid היא השם "root" - תמיד מחרוזת אמת עבור משתמשים קיימים. if (getpwuid($uid)) { ... } לכן עובד כמצופה, אבל פנו ל־defined בכל זאת אם אכפת לכם מההבחנה בין ״חסר״ ל־״שם ריק״:

    if (defined getpwuid($uid))       { ... }   # unambiguous
    if (my @pw = getpwuid($uid))      { ... }   # also correct
    
  • UID הוא מספר, לא שם. getpwuid("root") ממיר את "root" ל־0 (עם אזהרה תחת use warnings) ומאתר UID 0. השתמשו ב־getpwnam לאיתורים לפי שם.

  • UIDs שליליים / חורגים בגודל. קריאת המערכת מקבלת כל מה ש־uid_t מקבל על הפלטפורמה (בדרך כלל 32-bit unsigned). Perl ממיר ערכים שליליים דרך two’s-complement בכניסה; התוצאה ספציפית לפלטפורמה וכמעט לעולם לא מה שרוצים.

  • ספריות גדולות (LDAP / NIS / SSSD). getpwuid עובר דרך NSS, ולכן העלות מתאמת לאופן שבו ה־resolver המקומי עונה. החמצה מול שרת LDAP שמוגדר לא נכון יכולה לחסום למשך שניות. שמרו תוצאות ב־cache בהאש אם אתם פותרים UIDs רבים בלולאה צפופה (למשל בעת הוספת הערות לפלט בסגנון ls -l).

  • Threads. המקור מציין ש־getpwuid_r משמש אוטומטית במקום שבו הפלטפורמה מספקת אותו; איטרציית getpwent, לעומת זאת, נשארת לכל־תהליך. לא מהווה דאגה תחת pperl (אין ithreads), אבל כדאי לדעת אם משתפים קוד עם perl5.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • getpwnam - אותה רשומה, מאותרת לפי שם התחברות; שלבו עם getpwuid כשצריך לעבור שם → UID

  • getpwent - איטרציה על מסד ה־passwd כולו; השתמשו כשצריך כל משתמש, לא ספציפי

  • endpwent - סוגר את איטרטור ה־passwd לאחר getpwent

  • getgrgid - מקבילה במסד הקבוצות; נדרש כדי לפתור את שדה ה־$gid מרשומה זו חזרה לשם קבוצה

  • getlogin - איתור זול של ״מי על ה־tty הזה״; חזרו אל getpwuid($<) כשהוא מחזיר ריק

  • User::pwent - עוטף עצם עם accessors בעלי שם; פנו אליו כשרוצים ->name במקום לספור מיקומי רשימה