access(2)

الاسم
access, faccessat, faccessat2 - التحقق من أذونات المستخدم لملف

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <unistd.h>

int access(const char *path, int mode);

#include <fcntl.h>            /* Definition of AT_* constants */
#include <unistd.h>

int faccessat(int dirfd, const char *path, int mode, int flags);
                /* But see C library/kernel differences, below */

#include <fcntl.h>            /* Definition of AT_* constants */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(SYS_faccessat2,
            int dirfd, const char *path, int mode, int flags);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

faccessat():
    منذ glibc 2.10:
        _POSIX_C_SOURCE >= 200809L
    قبل glibc 2.10:
        _ATFILE_SOURCE

الوصف
access() يتحقق مما إذا كانت العملية المستدعية يمكنها الوصول إلى الملف path. إذا كان path رابطًا رمزيًا، فسيتم متابعته.

يحدد mode فحص (فحوصات) الوصول التي سيتم تنفيذها، وهو إما القيمة F_OK، أو قناع يتكون من OR على مستوى البت لواحد أو أكثر من R_OK و W_OK و X_OK. يختبر F_OK وجود الملف. يختبر R_OK و W_OK و X_OK ما إذا كان الملف موجودًا ويمنح أذونات القراءة والكتابة والتنفيذ، على التوالي.

يتم الفحص باستخدام UID و GID الحقيقيين للعملية المستدعية، بدلاً من المعرفات الفعالة كما يحدث عند محاولة تنفيذ عملية (مثل open(2)) على الملف. وبالمثل، بالنسبة للمستخدم الجذر، يستخدم الفحص مجموعة الصلاحيات المسموح بها بدلاً من مجموعة الصلاحيات الفعالة؛ وبالنسبة للمستخدمين غير الجذر، يستخدم الفحص مجموعة فارغة من الصلاحيات.

يسمح هذا للبرامج ذات set-user-ID والبرامج المزودة بالصلاحيات بتحديد سلطة المستخدم المستدعي بسهولة. بعبارة أخرى، لا يجيب access() على سؤال "هل يمكنني قراءة/كتابة/تنفيذ هذا الملف؟". إنه يجيب على سؤال مختلف قليلاً: "(بافتراض أنني ثنائي setuid) هل يمكن لـ المستخدم الذي استدعاني قراءة/كتابة/تنفيذ هذا الملف؟"، مما يعطي برامج set-user-ID إمكانية منع المستخدمين الخبيثين من جعلها تقرأ ملفات لا ينبغي للمستخدمين قراءتها.

إذا كانت العملية المستدعية مميزة (أي أن UID الحقيقي لها هو صفر)، فإن فحص X_OK يكون ناجحًا لملف عادي إذا كان إذن التنفيذ مفعلًا لأي من مالك الملف أو المجموعة أو الآخرين.

  faccessat()
يعمل faccessat() بنفس طريقة access() تمامًا، باستثناء الاختلافات الموصوفة هنا.

إذا كان path نسبيًا، فسيتم تفسيره بالنسبة إلى الدليل المشار إليه بواسطة واصف الملف dirfd (بدلاً من دليل العمل الحالي للعملية المستدعية، كما يفعل access() لاسم مسار نسبي).

إذا كان path نسبيًا وكان dirfd هو القيمة الخاصة AT_FDCWD، فسيتم تفسير path بالنسبة إلى دليل العمل الحالي للعملية المستدعية (مثل access()).

إذا كان المسار path مطلقاً، فُيتجاهل dirfd.

يتم إنشاء flags بواسطة OR معًا لصفر أو أكثر من القيم التالية:

AT_EACCESS
    قم بإجراء فحوصات الوصول باستخدام معرفات المستخدم والمجموعة الفعالة. بشكل مبدئي، يستخدم faccessat() المعرفات الحقيقية (مثل access()).

AT_EMPTY_PATH (منذ لينكس 5.8)
    إذا كان path سلسلة فارغة، فسيُعمل على الملف الذي يشير إليه dirfd (والذي ربما تم الحصول عليه باستخدام الراية O_PATH في open(2)). في هذه الحالة، يمكن لـ dirfd أن يشير إلى أي نوع من الملفات، وليس فقط المجلدات. وإذا كان dirfd هو AT_FDCWD، فسيُنادى على مجلد العمل الحالي. هذه الراية خاصة بلينكس؛ عرّف _GNU_SOURCE للحصول على تعريفها.

AT_SYMLINK_NOFOLLOW
    إذا كان path رابطًا رمزيًا، فلا تتبعه: بدلاً من ذلك، أعد معلومات حول الرابط نفسه.

انظر openat(2) لشرح الحاجة إلى faccessat().

  faccessat2()
يتوافق وصف faccessat() المذكور أعلاه مع POSIX.1 ومع التنفيذ المقدم من glibc. ومع ذلك، كان تنفيذ glibc محاكاة غير كاملة (انظر الأخطاء) التي أخفت حقيقة أن استدعاء النظام الخام faccessat() في Linux لا يحتوي على وسيطة flags. للسماح بتنفيذ صحيح، أضاف Linux 5.8 استدعاء النظام faccessat2() الذي يدعم وسيطة flags ويسمح بتنفيذ صحيح لدالة الغلاف faccessat().

قيمة الإرجاع
عند النجاح (تم منح جميع الأذونات المطلوبة، أو mode هو F_OK والملف موجود)، يتم إرجاع صفر. عند الخطأ (طلب بت واحد على الأقل في mode إذنًا مرفوضًا، أو mode هو F_OK والملف غير موجود، أو حدث خطأ آخر)، يتم إرجاع -1، ويتم تعيين errno للإشارة إلى الخطأ.

الأخطاء

EACCES
    سيتم رفض الوصول المطلوب إلى الملف، أو يتم رفض إذن البحث لأحد الدلائل في بادئة المسار لـ path. (انظر أيضًا path_resolution(7).)

EBADF
    (faccessat()) path نسبي ولكن dirfd ليس AT_FDCWD (faccessat()) ولا واصف ملف صالح.

EFAULT
    المسار path يشير إلى خارج مساحة العناوين التي يمكن الوصول إليها.

EINVAL
    تم تحديد mode بشكل غير صحيح.

EINVAL
    (faccessat()) تم تحديد علامة غير صالحة في flags.

EIO حدث خطأ إدخال/إخراج.

ELOOP
    وُجد عدد كبير جدًا من الوصلات الرمزية أثناء تحليل path.

ENAMETOOLONG
    المسار path طويل جداً.

ENOENT
    أحد مكونات path غير موجود أو أنه وصلة رمزية معلقة.

ENOMEM
    ذاكرة النواة المتوفرة غير كافية.

ENOTDIR
    المكون المستخدم كدليل في path ليس دليلاً في الواقع.

ENOTDIR
    (faccessat()) path نسبي و dirfd هو واصف ملف يشير إلى ملف غير دليل.

EPERM
    طلب إذن الكتابة إلى ملف مضبوط بعلم غير قابل للتغيير. انظر أيضًا FS_IOC_SETFLAGS(2const).

EROFS
    طلب إذن الكتابة لملف على نظام ملفات للقراءة فقط.

ETXTBSY
    طلب وصول للكتابة إلى ملف تنفيذي يجري تنفيذه.

الإصدارات
إذا كانت العملية المستدعية تملك صلاحيات مناسبة (أي، هي مستخدم فائق)، يسمح POSIX.1-2001 للتنفيذ بالإشارة إلى نجاح فحص X_OK حتى لو لم تكن أي من بتات إذن تنفيذ الملف مضبوطة. لا يفعل لينكس هذا.

  الاختلافات بين مكتبة C والنواة
استدعاء النظام الخام faccessat() يأخذ فقط الوسائط الثلاث الأولى. العلامتان AT_EACCESS و AT_SYMLINK_NOFOLLOW منفذتان فعليًا داخل دالة الغلاف glibc لـ faccessat(). إذا تم تحديد أي من هاتين العلامتين، تستخدم دالة الغلاف fstatat(2) لتحديد أذونات الوصول، لكن انظر الأخطاء.

  ملاحظات glibc
على النوى القديمة حيث faccessat() غير متوفر (وعندما لا يتم تحديد العلامتين AT_EACCESS و AT_SYMLINK_NOFOLLOW)، تعود دالة الغلاف glibc لاستخدام access(). عندما يكون path نسبيًا، تبني glibc اسم مسار بناءً على الرابط الرمزي في /proc/self/fd الذي يتوافق مع وسيطة dirfd.

المعايير

access()
faccessat()
    POSIX.1-2024.

faccessat2()
    لينكس.

التاريخ

access()
    4.3BSD، SVr4، POSIX.1-1988.

faccessat()
    لينكس 2.6.16، glibc 2.4، POSIX.1-2008.

faccessat2()
    لينكس 5.8.

ملاحظات
تحذير: استخدام هذه الاستدعاءات للتحقق مما إذا كان المستخدم مخولًا، على سبيل المثال، لفتح ملف قبل القيام بذلك فعليًا باستخدام open(2) يخلق ثغرة أمنية، لأن المستخدم قد يستغل الفاصل الزمني القصير بين التحقق وفتح الملف للتلاعب به. لهذا السبب، يجب تجنب استخدام استدعاء النظام هذا. (في المثال الموصوف للتو، البديل الأكثر أمانًا سيكون التبديل المؤقت لمعرف المستخدم الفعال للعملية إلى المعرف الحقيقي ثم استدعاء open(2).)

access() دائمًا يفك مرجعية الروابط الرمزية. إذا كنت بحاجة للتحقق من الأذونات على رابط رمزي، استخدم faccessat() مع العلامة AT_SYMLINK_NOFOLLOW.

ترجع هذه الاستدعاءات خطأ إذا تم رفض أي من أنواع الوصول في mode، حتى لو كانت بعض أنواع الوصول الأخرى في mode مسموحة.

الملف يمكن الوصول إليه فقط إذا كانت الأذونات على كل دليل في بادئة المسار لـ path تمنح وصول البحث (أي، التنفيذ). إذا كان أي دليل غير قابل للوصول، يفشل استدعاء access()، بغض النظر عن الأذونات على الملف نفسه.

يتم فحص بتات الوصول فقط، وليس نوع الملف أو محتوياته. لذلك، إذا تم العثور على دليل قابل للكتابة، فهذا يعني غالبًا أنه يمكن إنشاء ملفات في الدليل، وليس أن الدليل يمكن كتابته كملف. بالمثل، قد يتم الإبلاغ عن ملف DOS كملف تنفيذي، لكن استدعاء execve(2) سيفشل مع ذلك.

قد لا تعمل هذه الاستدعاءات بشكل صحيح على أنظمة ملفات NFSv2 مع تمكين تعيين UID، لأن تعيين UID يتم على الخادم ويكون مخفيًا عن العميل، الذي يتحقق من الأذونات. (إصدارات NFS 3 وما فوق تقوم بالفحص على الخادم.) يمكن أن تحدث مشاكل مماثلة لوصلات FUSE.

العلل
لأن استدعاء النظام faccessat() في نواة لينكس لا يدعم وسيطة flags، تقوم دالة الغلاف glibc faccessat() المقدمة في glibc 2.32 وما قبله بمحاكاة الوظيفة المطلوبة باستخدام مزيج من استدعاء النظام faccessat() و fstatat(2). لكن هذه المحاكاة لا تأخذ في الاعتبار قوائم التحكم بالوصول (ACLs). بدءًا من glibc 2.33، تتجنب دالة الغلاف هذا الخطأ باستخدام استدعاء النظام faccessat2() حيثما كان متوفرًا من النواة الأساسية.

في لينكس 2.4 (وما قبله) هناك بعض الغرابة في معالجة اختبارات X_OK للمستخدم الفائق. إذا تم تعطيل جميع فئات إذن التنفيذ لملف غير دليل، فإن اختبار access() الوحيد الذي يرجع -1 هو عندما يتم تحديد mode كـ X_OK فقط؛ إذا تم تحديد R_OK أو W_OK أيضًا في mode، فإن access() يرجع 0 لمثل هذه الملفات. لينكس المبكر 2.6 (حتى لينكس 2.6.3) تصرف أيضًا بنفس طريقة لينكس 2.4.

قبل لينكس 2.6.20، تجاهلت هذه الاستدعاءات تأثير العلامة MS_NOEXEC إذا تم استخدامها لـ mount(2) نظام الملفات الأساسي. منذ لينكس 2.6.20، يتم احترام العلامة MS_NOEXEC.

انظر أيضًا
chmod(2), chown(2), open(2), setgid(2), setuid(2), stat(2), euidaccess(3), credentials(7), path_resolution(7), symlink(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.