Scroll to navigation

keyctl(2) System Calls Manual keyctl(2)

الاسم

keyctl - التلاعب بمرفق إدارة المفاتيح في النواة

المكتبة

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

بدلاً من ذلك، أدوات إدارة مفاتيح لينكس (libkeyutils، -lkeyutils)؛ انظر VERSIONS.

موجز

#include <linux/keyctl.h>     /* تعريف ثوابت KEY* */
#include <sys/syscall.h>      /* تعريف ثوابت SYS_* */
#include <unistd.h>
long syscall(SYS_keyctl, int operation, unsigned long arg2,
             unsigned long arg3, unsigned long arg4,
             unsigned long arg5);

ملاحظة: لا توفر glibc غلافاً لـ keyctl()، مما يستلزم استخدام syscall(2).

الوصف

تسمح keyctl() لبرامج فضاء المستخدم بإجراء تلاعب بالمفاتيح.

تُحدد العملية التي تجريها keyctl() بواسطة قيمة المعامل operation. تُغلف كل عملية من هذه العمليات بواسطة مكتبة libkeyutils (التي توفرها حزمة keyutils) في دوال منفردة (مذكورة أدناه) للسماح للمصرف بالتحقق من الأنواع.

القيم المسموح بها لـ operation هي:

ربط معرف مفتاح خاص بمعرف مفتاح حقيقي لهذه العملية.
تبحث هذه العملية عن المفتاح الخاص الذي يُوفّر معرفه في arg2 (مُحوّل إلى key_serial_t). إذا عُثر على المفتاح الخاص، يُعاد معرف المفتاح الحقيقي المقابل كـ نتيجة للدالة. القيم التالية يمكن تحديدها في arg2:
يحدد هذا حلقة مفاتيح خاصة بخيط التنفيذ للمستدعِي. انظر thread-keyring(7).
يحدد هذا حلقة مفاتيح خاصة بالعملية للمستدعِي. انظر process-keyring(7).
يحدد هذا حلقة مفاتيح خاصة بالجلسة للمستدعِي. انظر session-keyring(7).
يحدد هذا حلقة مفاتيح خاصة بمعرف المستخدم (UID) للمستدعِي. انظر user-keyring(7).
يحدد هذا حلقة مفاتيح جلسة معرف المستخدم للمستدعِي. انظر user-session-keyring(7).
يحدد هذا مفتاح الترخيص المنشأ بواسطة request_key(2) والممرر إلى العملية التي أطلقها لتوليد مفتاح. يتوفر هذا المفتاح فقط في برنامج بنمط request-key(8) مُرّر إليه مفتاح ترخيص بواسطة النواة، ويتوقف عن التوفر بمجرد تجسيد المفتاح المطلوب؛ انظر request_key(2).
يحدد هذا معرف المفتاح لحلقة مفاتيح وجهة request_key(2). تتوفر حلقة المفاتيح هذه فقط في برنامج بنمط request-key(8) مُرّر إليه مفتاح ترخيص بواسطة النواة، وتتوقف عن التوفر بمجرد تجسيد المفتاح المطلوب؛ انظر request_key(2).
يعتمد السلوك إذا كان المفتاح المحدد في arg2 غير موجود على قيمة arg3 (المُحوّلة إلى int). إذا احتوت arg3 على قيمة غير صفرية، فحينئذٍ—إذا كان ذلك مناسباً (مثلاً، عند البحث عن مفتاح المستخدم، أو جلسة المستخدم، أو الجلسة)—يُنشأ مفتاح جديد ويُعاد معرفه الحقيقي نتيجةً للدالة. خلاف ذلك، تفشل العملية مع الخطأ ENOKEY.
إذا حُدد معرف مفتاح صالح في arg2، وكان المفتاح موجوداً، فإن هذه العملية تعيد ببساطة معرف المفتاح. وإذا لم يكن المفتاح موجوداً، يفشل الاستدعاء مع الخطأ ENOKEY.
يجب أن يملك المستدعِي إذن search (بحث) على حلقة المفاتيح لكي يُعثر عليها.
تُتجاهل المعاملات arg4 و arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_get_keyring_ID(3).
استبدال حلقة مفاتيح الجلسة التي تشترك فيها هذه العملية بحلقة مفاتيح جلسة جديدة.
إذا كانت arg2 هي NULL، تُنشأ حلقة مفاتيح مجهولة بالوصف "_ses" وتُشترك العملية في حلقة المفاتيح تلك بصفتها حلقة مفاتيح الجلسة الخاصة بها، لتحل محل حلقة مفاتيح الجلسة السابقة.
خلاف ذلك، تُعامل arg2 (المُحوّلة إلى char *) على أنها وصف (اسم) حلقة مفاتيح، ويكون السلوك كما يلي:
إذا وجدت حلقة مفاتيح بوصف مطابق، فستحاول العملية الاشتراك في تلك الحلقة بصفتها حلقة مفاتيح الجلسة الخاصة بها إن أمكن؛ وإذا لم يكن ذلك ممكناً، يُعاد خطأ. لكي يشترك المستدعِي في حلقة المفاتيح، يجب أن يملك إذن search (بحث) عليها.
إذا لم توجد حلقة مفاتيح بوصف مطابق، تُنشأ حلقة مفاتيح جديدة بالوصف المحدد، وتُشترك العملية في تلك الحلقة بصفتها حلقة مفاتيح الجلسة الخاصة بها.
تُتجاهل المعاملات arg3 و arg4 و arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_join_session_keyring(3).
تحديث حمولة بيانات المفتاح.
يحدد المعامل arg2 (المُحوّل إلى key_serial_t) معرف المفتاح المراد تحديثه. يشير المعامل arg3 (المُحوّل إلى void *) إلى الحمولة الجديدة ويحتوي arg4 (المُحوّل إلى size_t) على حجم الحمولة الجديد بالبايت.
يجب أن يملك المستدعِي إذن write (كتابة) على المفتاح المحدد، ويجب أن يدعم نوع المفتاح التحديث.
يمكن تجسيد مفتاح مُجسّد سلبياً (انظر وصف KEYCTL_REJECT) إيجابياً بهذه العملية.
يُتجاهل المعامل arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_update(3).
إبطال المفتاح ذي المعرف المقدم في arg2 (المُحوّل إلى key_serial_t). يُجدول المفتاح لجمع المهملات؛ ولن يعود بالإمكان العثور عليه، وسيكون غير متاح لمزيد من العمليات. ستفشل أي محاولات أخرى لاستخدام المفتاح مع الخطأ EKEYREVOKED.
يجب أن يملك المستدعِي إذن write (كتابة) أو setattr (ضبط السمات) على المفتاح.
تُتجاهل المعاملات arg3 و arg4 و arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_revoke(3).
تغيير ملكية (معرف المستخدم والمجموعة) مفتاح ما.
يحتوي المعامل arg2 (المُحوّل إلى key_serial_t) على معرف المفتاح. يحتوي المعامل arg3 (المُحوّل إلى uid_t) على معرف المستخدم الجديد (أو -1 إذا كان لا ينبغي تغيير معرف المستخدم). يحتوي المعامل arg4 (المُحوّل إلى gid_t) على معرف المجموعة الجديد (أو -1 إذا كان لا ينبغي تغيير معرف المجموعة).
يجب أن يمنح المفتاح إذن setattr للمستدعِي.
لتغيير معرف المستخدم (UID)، أو لتغيير معرف المجموعة (GID) إلى مجموعة ليس المستدعِي عضواً فيها، يجب أن يملك المستدعِي قدرة CAP_SYS_ADMIN (انظر capabilities(7)).
إذا كان سيُغيّر معرف المستخدم (UID)، فيجب أن يملك المستخدم الجديد حصة كافية لقبول المفتاح. وسيُنقل خصم الحصة من المستخدم القديم إلى المستخدم الجديد في حال تغيير معرف المستخدم.
يُتجاهل المعامل arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_chown(3).
تغيير أذونات المفتاح ذي المعرف المقدم في المعامل arg2 (المُحوّل إلى key_serial_t) إلى الأذونات المقدمة في المعامل arg3 (المُحوّل إلى key_perm_t).
إذا لم يملك المستدعِي قدرة CAP_SYS_ADMIN، فلا يمكنه تغيير الأذونات إلا للمفاتيح التي يملكها. (بشكل أدق: يجب أن يطابق معرف المستخدم (UID) لنظام ملفات المستدعِي معرف المستخدم الخاص بالمفتاح).
يجب أن يمنح المفتاح إذن setattr للمستدعِي بغض النظر عن قدرات المستدعِي.
تحدد الأذونات في arg3 أقنعة للعمليات المتاحة لكل فئة من فئات المستخدمين التالية:
الحائز (منذ لينكس 2.6.14)
هذا هو الإذن الممنوح لعملية تحوز المفتاح (أي أنه متصل بشكل قابل للبحث بواحدة من حلقات مفاتيح العملية)؛ انظر keyrings(7).
هذا هو الإذن الممنوح لعملية يطابق معرف المستخدم (UID) الخاص بنظام ملفاتها معرف المستخدم الخاص بالمفتاح.
هذا هو الإذن الممنوح لعملية يطابق معرف المجموعة (GID) الخاص بنظام ملفاتها أو أي من معرفات مجموعاتها الإضافية معرف المجموعة الخاص بالمفتاح.
هذا هو الإذن الممنوح للعمليات الأخرى التي لا تندرج تحت فئتي user و group.
فئات user و group و other هي فئات استبعادية: إذا كانت العملية تطابق فئة user، فلن تحصل على الأذونات الممنوحة في فئة group؛ وإذا كانت العملية تطابق فئة user أو group، فلن تحصل على الأذونات الممنوحة في فئة other.
تمنح فئة possessor (الحائز) أذونات تراكمية مع الأذونات الممنوحة من فئات user أو group أو other.
كل قناع إذن حجمه ثمانية بتات، وتُستخدم منها ستة بتات فقط حالياً. الأذونات المتاحة هي:
يسمح هذا الإذن بقراءة سمات المفتاح.
هذا الإذن مطلوب لعملية KEYCTL_DESCRIBE.
بتات الإذن لكل فئة هي KEY_POS_VIEW و KEY_USR_VIEW و KEY_GRP_VIEW و KEY_OTH_VIEW.
يسمح هذا الإذن بقراءة حمولة المفتاح.
هذا الإذن مطلوب لعملية KEYCTL_READ.
بتات الإذن لكل فئة هي KEY_POS_READ و KEY_USR_READ و KEY_GRP_READ و KEY_OTH_READ.
يسمح هذا الإذن بتحديث أو تجسيد حمولة المفتاح. بالنسبة لحلقة المفاتيح، فإنه يسمح بربط المفاتيح بها أو فصلها عنها.
هذا الإذن مطلوب لعمليات KEYCTL_UPDATE و KEYCTL_REVOKE و KEYCTL_CLEAR و KEYCTL_LINK و KEYCTL_UNLINK.
بتات الإذن لكل فئة هي KEY_POS_WRITE و KEY_USR_WRITE و KEY_GRP_WRITE و KEY_OTH_WRITE.
يسمح هذا الإذن بالبحث في حلقات المفاتيح والعثور على المفاتيح. لا يمكن للبحث أن يتوغل تكرارياً إلا في حلقات المفاتيح المتداخلة التي ضُبط فيها إذن search (بحث).
هذا الإذن مطلوب لعمليات KEYCTL_GET_KEYRING_ID و KEYCTL_JOIN_SESSION_KEYRING و KEYCTL_SEARCH و KEYCTL_INVALIDATE.
بتات الإذن لكل فئة هي KEY_POS_SEARCH و KEY_USR_SEARCH و KEY_GRP_SEARCH و KEY_OTH_SEARCH.
يسمح هذا الإذن بربط مفتاح أو حلقة مفاتيح.
هذا الإذن مطلوب لعمليتي KEYCTL_LINK و KEYCTL_SESSION_TO_PARENT.
بتات الإذن لكل فئة هي KEY_POS_LINK و KEY_USR_LINK و KEY_GRP_LINK و KEY_OTH_LINK.
يسمح هذا الإذن بتغيير معرف المستخدم (UID)، ومعرف المجموعة (GID)، وقناع الأذونات الخاص بالمفتاح.
هذا الإذن مطلوب لعمليات KEYCTL_REVOKE و KEYCTL_CHOWN و KEYCTL_SETPERM.
بتات الإذن لكل فئة هي KEY_POS_SETATTR و KEY_USR_SETATTR و KEY_GRP_SETATTR و KEY_OTH_SETATTR.
من باب التيسير، عُرّفت وحدات الماكرو التالية كأقنعة لجميع بتات الأذونات في كل فئة من فئات المستخدمين: KEY_POS_ALL و KEY_USR_ALL و KEY_GRP_ALL و KEY_OTH_ALL.
تُتجاهل المعاملات arg4 و arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_setperm(3).
الحصول على سلسلة نصية تصف سمات مفتاح محدد.
يُحدد معرف المفتاح المراد وصفه في arg2 (المُحوّل إلى key_serial_t). وتُعاد سلسلة الوصف في الذاكرة الوسيطة التي يشير إليها arg3 (المُحوّل إلى char * )؛ ويحدد arg4 (المُحوّل إلى size_t) حجم تلك الذاكرة الوسيطة بالبايت.
يجب أن يمنح المفتاح إذن view (عرض) للمستدعِي.
السلسلة المعادة تنتهي بترميز صفري (null-terminated) وتحتوي على المعلومات التالية حول المفتاح:

type;uid;gid;perm;description
فيما سبق، type (النوع) و description (الوصف) هما سلسلتان نصيتان، و uid و gid هما سلسلتان عشريتان، و perm هو قناع أذونات سداسي عشري. وتُكتب سلسلة الوصف بالتنسيق التالي:

%s;%d;%d;%08x;%s
    

ملاحظة: النية هي أن تكون سلسلة الوصف قابلة للتوسعة في إصدارات النواة المستقبلية. وبوجه خاص، لن يحتوي حقل description (الوصف) على فواصل منقوطة؛ ويجب تحليله بالعمل عكسياً من نهاية السلسلة للعثور على آخر فاصلة منقوطة. يسمح هذا بإدراج حقول مستقبلية مفصولة بفواصل منقوطة في سلسلة الوصف مستقبلاً.
تجري محاولة الكتابة في الذاكرة الوسيطة فقط عندما لا تكون arg3 هي NULL ويكون حجم الذاكرة الوسيطة المحدد كبيراً بما يكفي لاستيعاب سلسلة الوصف (بما في ذلك البايت الصفري الختامي). ولتحديد ما إذا كان حجم الذاكرة الوسيطة صغيراً جداً، تحقق مما إذا كانت قيمة الإعادة للعملية أكبر من arg4.
يُتجاهل المعامل arg5.
تُوفّر هذه العملية بواسطة libkeyutils عبر الدالة keyctl_describe(3).
مسح محتويات حلقة مفاتيح (أي فصل جميع المفاتيح عنها).
يُوفّر معرف المفتاح (الذي يجب أن يكون من نوع حلقة مفاتيح) في arg2 (مُحوّل إلى key_serial_t).
يجب أن يمتلك المستدعِي إذن كتابة على حلقة المفاتيح.
تُتجاهل المعاملات arg3 و arg4 و arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_clear(3).
إنشاء رابط من حلقة مفاتيح إلى مفتاح.
يُحدّد المفتاح المراد ربطه في arg2 (مُحوّل إلى key_serial_t)؛ وتُحدّد حلقة المفاتيح في arg3 (مُحوّل إلى key_serial_t).
إذا كان هناك مفتاح بنفس النوع والوصف مربوطًا بالفعل في حلقة المفاتيح، فإن هذا المفتاح يُزاح من حلقة المفاتيح.
قبل إنشاء الرابط، تفحص النواة تداخل حلقات المفاتيح وتُعيد الأخطاء المناسبة إذا كان الرابط سينتج دورة أو إذا كان تداخل حلقات المفاتيح عميقًا جدًا (يُحدّد حد تداخل حلقات المفاتيح بواسطة ثابت النواة KEYRING_SEARCH_MAX_DEPTH، المُعرّف بالقيمة 6، وهو ضروري لمنع طفح مكدس النواة عند البحث التكراري في حلقات المفاتيح).
يجب أن يمتلك المستدعِي إذن ربط على المفتاح المضاف وإذن كتابة على حلقة المفاتيح.
تُتجاهل المعاملات arg4 و arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_link(3).
فصل مفتاح عن حلقة مفاتيح.
يُحدّد معرف المفتاح المراد فصله في arg2 (مُحوّل إلى key_serial_t)؛ ويُحدّد معرف حلقة المفاتيح المراد الفصل منها في arg3 (مُحوّل إلى key_serial_t).
إذا لم يكن المفتاح مربوطًا حاليًا في حلقة المفاتيح، فسينتج خطأ.
يجب أن يمتلك المستدعِي إذن كتابة على حلقة المفاتيح التي يُزال المفتاح منها.
إذا أُزيل الرابط الأخير لمفتاح، فسيُجدول هذا المفتاح للتدمير.
تُتجاهل المعاملات arg4 و arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_unlink(3).
البحث عن مفتاح في شجرة حلقة مفاتيح، وإرجاع معرفه وربطه اختياريًا بحلقة مفاتيح محددة.
تُحدّد الشجرة المراد البحث فيها بتمرير معرف حلقة المفاتيح الـ رئيسة في arg2 (مُحوّل إلى key_serial_t). يُجرى البحث بالاتساع أولاً وتكراريًا.
تُحدّد وسائط arg3 و arg4 المفتاح المراد البحث عنه: arg3 (مُحوّل كـ char *) يحتوي على نوع المفتاح (سلسلة محارف تنتهي بـ null يصل حجمها إلى 32 بايت، بما في ذلك بايت الإنهاء null)، و arg4 (مُحوّل كـ char *) يحتوي على وصف المفتاح (سلسلة محارف تنتهي بـ null يصل حجمها إلى 4096 بايت، بما في ذلك بايت الإنهاء null).
يجب أن تمنح حلقة مفاتيح المصدر إذن بحث لـ المستدعِي. عند إجراء البحث التكراري، ستُفحص فقط حلقات المفاتيح التي تمنح المستدعِي إذن بحث. يمكن فقط العثور على المفاتيح التي يمتلك المستدعِي إذن بحث عليها.
إذا وُجد المفتاح، يُرجع معرفه كنتيجة للدالة.
إذا وُجد المفتاح وكان arg5 (مُحوّل إلى key_serial_t) غير صفري، فبناءً على نفس القيود والقواعد مثل KEYCTL_LINK، يُربط المفتاح في حلقة المفاتيح التي حُدّد معرفها في arg5. إذا كانت حلقة مفاتيح الوجهة المحددة في arg5 تحتوي بالفعل على رابط لمفتاح له نفس النوع والوصف، فسيُزاح ذلك الرابط برابط للمفتاح الذي عثرت عليه هذه العملية.
بدلاً من معرفات حلقات المفاتيح الموجودة الصالحة، يمكن أن تكون حلقات مفاتيح المصدر (arg2) والوجهة (arg5) واحدة من معرفات حلقات المفاتيح الخاصة المدرجة تحت KEYCTL_GET_KEYRING_ID.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_search(3).
قراءة بيانات الحمولة لمفتاح.
يُحدّد معرف المفتاح المراد قراءة حمولته في arg2 (مُحوّل إلى key_serial_t). يمكن أن يكون هذا معرف مفتاح موجود، أو أيًا من معرفات المفاتيح الخاصة المدرجة لـ KEYCTL_GET_KEYRING_ID.
توضع الحمولة في المخزن المؤقت الذي يشير إليه arg3 (مُحوّل إلى char *)؛ ويجب تحديد حجم ذلك المخزن المؤقت في arg4 (مُحوّل إلى size_t).
ستُعالج البيانات المُرجعة للعرض وفقًا لنوع المفتاح. على سبيل المثال، ستُعيد حلقة المفاتيح مصفوفة من مدخلات key_serial_t تمثل معرفات جميع المفاتيح المربوطة بها. سيُعيد نوع مفتاح user بياناته كما هي. إذا كان نوع المفتاح لا ينفذ هذه الدالة، فستفشل العملية بالخطأ EOPNOTSUPP.
إذا لم يكن arg3 فارغًا (NULL)، فسيُنسخ من بيانات الحمولة قدر ما يتسع في المخزن المؤقت. عند الإرجاع الناجح، تكون القيمة المرجعة دائمًا هي الحجم الإجمالي لبيانات الحمولة. لتحديد ما إذا كان المخزن المؤقت ذا حجم كافٍ، تحقق مما إذا كانت القيمة المرجعة أقل من أو تساوي القيمة المزودة في arg4.
يجب أن يمنح المفتاح المستدعِي إذن قراءة، أو يمنحه إذن بحث عند البحث عنه من حلقات مفاتيح العملية (أي أن المفتاح ممتلك).
يُتجاهل المعامل arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_read(3).
تجسيد (إيجابي) لمفتاح غير مُجسّد بحمولة محددة.
يُوفّر معرف المفتاح المراد تجسيده في arg2 (مُحوّل إلى key_serial_t).
تُحدّد حمولة المفتاح في المخزن المؤقت الذي يشير إليه arg3 (مُحوّل إلى void *)؛ ويُحدّد حجم ذلك المخزن المؤقت في arg4 (مُحوّل إلى size_t).
قد تكون الحمولة مؤشرًا فارغًا (null) وقد يكون حجم المخزن المؤقت 0 إذا كان ذلك مدعومًا من نوع المفتاح (على سبيل المثال، إذا كان حلقة مفاتيح).
قد تفشل العملية إذا كانت بيانات الحمولة بتنسيق خاطئ أو غير صالحة لسبب آخر.
إذا كان arg5 (مُحوّل إلى key_serial_t) غير صفري، فبناءً على نفس القيود والقواعد مثل KEYCTL_LINK، يُربط المفتاح المُجسّد في حلقة المفاتيح التي حُدّد معرفها في arg5.
يجب أن يمتلك المستدعِي مفتاح الاستيثاق المناسب، وبمجرد تجسيد المفتاح غير المُجسّد، يُلغى مفتاح الاستيثاق. بعبارة أخرى، تتوفر هذه العملية فقط من برنامج بنمط request-key(8). انظر request_key(2) لشرح حول المفاتيح غير المُجسّدة وتجسيد المفاتيح.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_instantiate(3).
تجسيد سلبي لمفتاح غير مُجسّد.
هذه العملية مكافئة للاستدعاء:

keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4);
    

يُتجاهل المعامل arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_negate(3).
ضبط حلقة المفاتيح الـ مبدئية التي ستُربط بها المفاتيح المطلوبة ضمنيًا لهذا الخيط، وإرجاع الإعداد السابق. طلبات المفاتيح الضمنية هي تلك التي تُجريها مكونات النواة الداخلية، مثلما يحدث عند فتح ملفات على نظام ملفات AFS أو NFS مثلاً. يؤثر ضبط حلقة المفاتيح الـ مبدئية أيضًا عند طلب مفتاح من مساحة المستخدم؛ انظر request_key(2) للتفاصيل.
يجب أن تحتوي وسيطة arg2 (مُحوّلة إلى int) على واحدة من القيم التالية، لتحديد حلقة المفاتيح الـ مبدئية الجديدة:
عدم تغيير حلقة المفاتيح الـ مبدئية. يمكن استخدام هذا لاكتشاف حلقة المفاتيح الـ مبدئية الحالية (دون تغييرها).
يختار هذا السلوك الـ مبدئي، وهو استخدام حلقة المفاتيح الخاصة بالخيط إذا وجدت، وإلا فحلقة المفاتيح الخاصة بالعملية إذا وجدت، وإلا فحلقة مفاتيح الجلسة إذا وجدت، وإلا فحلقة مفاتيح الجلسة الخاصة بـ UID، وإلا فحلقة المفاتيح الخاصة بالمستخدم.
استخدام حلقة المفاتيح الخاصة بالخيط (thread-keyring(7)) كحلقة مفاتيح مبدئية جديدة.
استخدام حلقة المفاتيح الخاصة بالعملية (process-keyring(7)) كحلقة مفاتيح مبدئية جديدة.
استخدام حلقة مفاتيح الجلسة (session-keyring(7)) كحلقة مفاتيح مبدئية جديدة.
استخدام حلقة المفاتيح الخاصة بـ UID (user-keyring(7)) كحلقة مفاتيح مبدئية جديدة.
استخدام حلقة مفاتيح الجلسة الخاصة بـ UID (user-session-keyring(7)) كحلقة مفاتيح مبدئية جديدة.
استخدام حلقة مفاتيح طالب الطلب.
جميع القيم الأخرى غير صالحة.
تُتجاهل المعاملات arg3 و arg4 و arg5.
يَرث ابن fork(2) الإعداد الذي تتحكم فيه هذه العملية ويُحافظ عليه عبر execve(2).
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_set_reqkey_keyring(3).
ضبط مهلة زمنية لمفتاح.
يُحدّد معرف المفتاح في arg2 (مُحوّل إلى key_serial_t). تُحدّد قيمة المهلة، بالثواني من الوقت الحالي، في arg3 (مُحوّل إلى unsigned int). تُقاس المهلة مقابل ساعة الوقت الحقيقي.
تحديد قيمة المهلة بـ 0 يمسح أي مهلة موجودة على المفتاح.
يعرض ملف /proc/keys الوقت المتبقي حتى انتهاء صلاحية كل مفتاح. (هذه هي الطريقة الوحيدة لاكتشاف المهلة على المفتاح).
يجب أن يمتلك المستدعِي إما إذن setattr على المفتاح أو يحمل رمز استيثاق تجسيد للمفتاح (انظر request_key(2)).
سيُجمع المفتاح وأي روابط للمفتاح آليًا (garbage collected) بعد انتهاء المهلة. ستفشل المحاولات اللاحقة للوصول إلى المفتاح بالخطأ EKEYEXPIRED.
لا يمكن استخدام هذه العملية لضبط المهل على المفاتيح الملغاة، أو منتهية الصلاحية، أو المُجسّدة سلبيًا.
تُتجاهل المعاملات arg4 و arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_set_timeout(3).
تولي (أو تجريد) سلطة تجسيد مفتاح لخيط الاستدعاء.
تُحدّد وسيطة arg2 (مُحوّلة إلى key_serial_t) إما معرف مفتاح غير صفري لتولي السلطة، أو القيمة 0 لتجريد السلطة.
إذا كان arg2 غير صفري، فإنه يحدد معرف مفتاح غير مُجسّد يُراد تولي سلطته. يمكن بعد ذلك تجسيد ذلك المفتاح باستخدام أحد KEYCTL_INSTANTIATE، أو KEYCTL_INSTANTIATE_IOV، أو KEYCTL_REJECT، أو KEYCTL_NEGATE. بمجرد تجسيد المفتاح، يُجرّد الخيط آليًا من سلطة تجسيد المفتاح.
لا يمكن تولي السلطة على مفتاح إلا إذا كان خيط الاستدعاء يمتلك في حلقات مفاتيحه مفتاح الاستيثاق المرتبط بالمفتاح المحدد. (بعبارة أخرى، تتوفر عملية KEYCTL_ASSUME_AUTHORITY فقط من برنامج بنمط request-key(8)؛ انظر request_key(2) لشرح كيفية استخدام هذه العملية). يجب أن يمتلك المستدعِي إذن بحث على مفتاح الاستيثاق.
إذا كان للمفتاح المحدد مفتاح استيثاق مطابق، فيُرجع معرف ذلك المفتاح. يمكن قراءة مفتاح الاستيثاق (KEYCTL_READ) للحصول على معلومات الاتصال الممررة إلى request_key(2).
إذا كان المعرف المعطى في arg2 هو 0، فتُمسح (تُجرّد) السلطة المتولاة حاليًا، وتُرجع القيمة 0.
تسمح آلية KEYCTL_ASSUME_AUTHORITY لبرنامج مثل request-key(8) بتولي السلطة اللازمة لتجسيد مفتاح جديد غير مُجسّد أُنشئ نتيجة لاستدعاء request_key(2). لمزيد من المعلومات، انظر request_key(2) وملف مصدر النواة Documentation/security/keys-request-key.txt.
تُتجاهل المعاملات arg3 و arg4 و arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالة keyctl_assume_authority(3).
الحصول على لصيقة أمان LSM (وحدة أمان لينكس) للمفتاح المحدد.
يُحدّد معرف المفتاح المراد جلب لصيقة أمانه في arg2 (مُحوّل إلى key_serial_t). توضع لصيقة الأمان (التي تنتهي ببايت null) في المخزن المؤقت الذي تشير إليه وسيطة arg3 (مُحوّلة إلى char *)؛ ويجب تقديم حجم المخزن المؤقت في arg4 (مُحوّل إلى size_t).
إذا حُدّد arg3 كـ NULL أو كان حجم المخزن المؤقت المحدد في arg4 صغيرًا جدًا، فيُرجع الحجم الكامل لسلسلة لصيقة الأمان (بما في ذلك بايت الإنهاء null) كـ نتيجة للدالة، ولا يُنسخ أي شيء إلى المخزن المؤقت.
يجب أن يمتلك المستدعِي إذن عرض على المفتاح المحدد.
ستُعرض سلسلة لصيقة الأمان المُرجعة بصيغة مناسبة لـ LSM المعمول به. على سبيل المثال، مع SELinux، قد تبدو كالتالي:

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    

إذا لم يكن هناك LSM معمول به حاليًا، فتوضع سلسلة فارغة في المخزن المؤقت.
يُتجاهل المعامل arg5.
تُعرّض هذه العملية بواسطة libkeyutils عبر الدالتين keyctl_get_security(3) و keyctl_get_security_alloc(3).
استبدال حلقة مفاتيح الجلسة التي يشترك فيها والد عملية الاستدعاء بحلقة مفاتيح الجلسة لعملية الاستدعاء.
ستُستبدل حلقة المفاتيح في العملية الأب عند النقطة التي تنتقل فيها العملية الأب المرة القادمة من مساحة النواة إلى مساحة المستخدم.
يجب أن تكون حلقة المفاتيح موجودة ويجب أن تمنح المستدعِي link إذن الربط. يجب أن تكون العملية الأب أحادية الخيوط ولها نفس الملكية الفعلية لهذه العملية، ويجب ألا تكون مضبوطة بمعرف مستخدم (set-user-ID) أو معرف مجموعة (set-group-ID). ويجب أن يتطابق معرف المستخدم (UID) لحلقة مفاتيح الجلسة الحالية للعملية الأب (إن وُجدت)، وكذلك معرف المستخدم لحلقة مفاتيح جلسة المستدعِي مع معرف المستخدم الفعلي للمستدعِي.
حقيقة أن العملية الأب هي التي تتأثر بهذه العملية تسمح لبرنامج مثل الصدفة ببدء عملية ابن تستخدم هذه العملية لتغيير حلقة مفاتيح جلسة الصدفة. (هذا هو ما يفعله أمر new_session في keyctl(1).)
تُتجاهل المعاملات arg2 و arg3 و arg4 و arg5.
تُوفر هذه العملية عبر libkeyutils من خلال الدالة keyctl_session_to_parent(3).
وسم مفتاح بأنه مُنشأ سلبًا وضبط مؤقت انتهاء صلاحية للمفتاح. توفر هذه العملية مجموعة موسعة من وظائف عملية KEYCTL_NEGATE السابقة.
يُحدد معرف المفتاح المراد إنشاؤه سلبًا في arg2 (بتحويله إلى key_serial_t). ويحدد المعامل arg3 (بتحويله إلى unsigned int) عمر المفتاح بالثواني. ويحدد المعامل arg4 (بتحويله إلى unsigned int) الخطأ الذي سيُرجع عندما يصادف البحث هذا المفتاح؛ وعادة ما يكون أحد الأخطاء EKEYREJECTED أو EKEYREVOKED أو EKEYEXPIRED.
إذا كانت قيمة arg5 (بتحويلها إلى key_serial_t) غير صفرية، فوفقًا لنفس القيود والقواعد الخاصة بـ KEYCTL_LINK، يُربط المفتاح المنشأ سلبًا في حلقة المفاتيح التي حُدد معرفها في arg5.
يجب أن يمتلك المستدعِي مفتاح الاستيثاق المناسب. بعبارة أخرى، تتوفر هذه العملية فقط من برنامج بأسلوب request-key(8). انظر request_key(2).
يجب أن يمتلك المستدعِي مفتاح الاستيثاق المناسب، وبمجرد تجسيد المفتاح غير المُجسّد، يُلغى مفتاح الاستيثاق. بعبارة أخرى، تتوفر هذه العملية فقط من برنامج بنمط request-key(8). انظر request_key(2) لشرح حول المفاتيح غير المُجسّدة وتجسيد المفاتيح.
تُوفر هذه العملية عبر libkeyutils من خلال الدالة keyctl_reject(3).
إنشاء مفتاح غير مُنشأ بحمولة محددة عبر متجه من المخازن المؤقتة.
هذه العملية هي نفسها KEYCTL_INSTANTIATE، ولكن تُحدد بيانات الحمولة كمصفوفة من هياكل iovec (انظر iovec(3type)).
يُحدد المؤشر إلى متجه الحمولة في arg3 (بتحويله إلى const struct iovec *). ويُحدد عدد العناصر في المتجه في arg4 (بتحويله إلى unsigned int).
يُفسر arg2 (معرف المفتاح) و arg5 (معرف حلقة المفاتيح) كما في KEYCTL_INSTANTIATE.
تُوفر هذه العملية عبر libkeyutils من خلال الدالة keyctl_instantiate_iov(3).
وسم مفتاح بأنه غير صالح.
يُحدد معرف المفتاح المراد إبطاله في arg2 (بتحويله إلى key_serial_t).
لإبطال مفتاح، يجب أن يمتلك المستدعِي إذن البحث search على المفتاح.
تسم هذه العملية المفتاح بأنه غير صالح وتجدول الجمع الفوري للمهملات. يزيل جامع المهملات المفتاح المبطل من جميع حلقات المفاتيح ويحذفه عندما يصل عداد مرجعه إلى صفر. بعد هذه العملية، سيُتجاهل المفتاح في جميع عمليات البحث، حتى لو لم يُحذف بعد.
تصبح المفاتيح الموسومة بأنها غير صالحة غير مرئية لعمليات المفاتيح العادية فورًا، على الرغم من أنها تظل مرئية في /proc/keys (موسومة بالعلامة 'i') حتى تُزال فعليًا.
تُتجاهل المعاملات arg3 و arg4 و arg5.
تُوفر هذه العملية عبر libkeyutils من خلال الدالة keyctl_invalidate(3).
الحصول على حلقة المفاتيح المستمرة (persistent-keyring(7)) لمستخدم محدد وربطها بحلقة مفاتيح محددة.
يُحدد معرف المستخدم في arg2 (بتحويله إلى uid_t). إذا حُددت القيمة -1، سيُستخدم معرف المستخدم الحقيقي للمستدعِي. ويُحدد معرف حلقة المفاتيح الوجهة في arg3 (بتحويله إلى key_serial_t).
يجب أن يمتلك المستدعِي قدرة CAP_SETUID في مساحة اسم المستخدم الخاصة به من أجل جلب حلقة المفاتيح المستمرة لمعرف مستخدم لا يتطابق مع معرف المستخدم الحقيقي أو الفعلي للمستدعِي.
إذا كان الاستدعاء ناجحًا، يُضاف رابط لحلقة المفاتيح المستمرة إلى حلقة المفاتيح التي حُدد معرفها في arg3.
يجب أن يمتلك المستدعِي إذن كتابة على حلقة المفاتيح.
ستُنشئ النواة حلقة المفاتيح المستمرة إذا لم تكن موجودة بعد.
في كل مرة تُجرى فيها عملية KEYCTL_GET_PERSISTENT، ستُصفر مهلة انتهاء صلاحية حلقة المفاتيح المستمرة إلى القيمة الموجودة في:

/proc/sys/kernel/keys/persistent_keyring_expiry
    

في حال الوصول إلى المهلة، ستُزال حلقة المفاتيح المستمرة ويمكن حينها جمع كل ما ثبّتته كمهملات.
أضيفت حلقات المفاتيح المستمرة في لينكس 3.13.
تُتجاهل المعاملات arg4 و arg5.
تُوفر هذه العملية عبر libkeyutils من خلال الدالة keyctl_get_persistent(3).
حساب سر مشترك أو مفتاح عام بطريقة ديفي-هيلمان (Diffie-Hellman)، مع إمكانية تطبيق دالة اشتقاق مفاتيح (KDF) على النتيجة اختياريا.
المعامل arg2 هو مؤشر إلى مجموعة من المعلمات تحتوي على الأرقام التسلسلية لثلاثة مفاتيح "مستخدم" تُستخدم في حساب ديفي-هيلمان، ومُعبأة في هيكل بالصيغة التالية:

struct keyctl_dh_params {

int32_t private; /* المفتاح الخاص المحلي */
int32_t prime; /* العدد الأولي، المعروف لكلا الطرفين */
int32_t base; /* العدد الأساسي: إما المولد المشترك
أو المفتاح العام للطرف الآخر */ };

يجب أن يمنح كل مفتاح من المفاتيح الثلاثة المحددة في هذا الهيكل إذن القراءة read للمستدعِي. تُستخدم حمولات هذه المفاتيح لحساب نتيجة ديفي-هيلمان كالتالي:

base ^ private mod prime
    

إذا كان الأساس هو المولد المشترك، فالنتيجة هي المفتاح العام المحلي. وإذا كان الأساس هو المفتاح العام للطرف الآخر، فالنتيجة هي السر المشترك.
يشير المعامل arg3 (بتحويله إلى char *) إلى مخزن مؤقت حيث توضع نتيجة الحساب. ويُحدد حجم ذلك المخزن في arg4 (بتحويله إلى size_t).
يجب أن يكون المخزن المؤقت كبيرًا بما يكفي لاستيعاب بيانات المخرجات، وإلا سيُرجع خطأ. إذا حُدد arg4 بصفر، فلا يُستخدم المخزن المؤقت وتُرجع العملية أقل حجم مخزن مطلوب (أي طول العدد الأولي).
يمكن إجراء حسابات ديفي-هيلمان في مساحة المستخدم، ولكنها تتطلب مكتبة أعداد صحيحة متعددة الدقة (MPI). يوفر نقل التنفيذ إلى النواة وصولاً إلى تنفيذ MPI الخاص بالنواة، ويسمح بالوصول إلى أجهزة آمنة أو مسرعة.
اعتبرت إضافة دعم حساب DH إلى استدعاء النظام keyctl() مناسبة بسبب استخدام خوارزمية DH لاشتقاق المفاتيح المشتركة؛ كما أنها تسمح لنوع المفتاح بتحديد تنفيذ DH المناسب (سواء كان برمجياً أو مادياً).
إذا كان المعامل arg5 هو NULL، فستُرجع نتيجة DH نفسها. وإلا (منذ لينكس 4.12)، فإنه يكون مؤشراً إلى هيكل يحدد معلمات عملية KDF المراد تطبيقها:

struct keyctl_kdf_params {

char *hashname; /* اسم خوارزمية التلبيد */
char *otherinfo; /* معلومات أخرى SP800-56A */
__u32 otherinfolen; /* طول بيانات otherinfo */
__u32 __spare[8]; /* محجوز */ };

حقل hashname هو سلسلة منتهية بصفر تحدد اسم التلبيد (المتوفر في واجهة برمجة تطبيقات التعمية للنواة؛ من الصعب ملاحظة قائمة التلبيدات المتوفرة؛ يرجى الرجوع إلى وثائق "هيكلية واجهة برمجة تطبيقات التعمية للنواة" للحصول على معلومات حول كيفية بناء أسماء التلبيد ومصدر النواة والضبط الخاص بك فيما يتعلق بالشيفرات والقوالب المتوفرة من نوع CRYPTO_ALG_TYPE_SHASH) ليُطبق على نتيجة DH في عملية KDF.
حقل otherinfo هو بيانات OtherInfo كما هو موضح في SP800-56A القسم 5.8.1.2 وهو خاص بالخوارزمية. تُدمج هذه البيانات مع نتيجة عملية DH وتُقدم كمدخل لعملية KDF. ويُحدد حجمها في حقل otherinfolen وهو محدود بالثابت KEYCTL_KDF_MAX_OI_LEN المعرف في security/keys/internal.h بقيمة 64.
حقل __spare غير مستخدم حالياً. كان يُتجاهل حتى لينكس 4.13 (ولكن يجب أن يظل قابلاً للعنونة من قبل المستخدم لأنه يُنسخ إلى النواة)، ويجب أن يحتوي على أصفار منذ لينكس 4.13.
يتوافق تنفيذ KDF مع SP800-56A وكذلك مع SP800-108 (KDF العداد).
تُوفر هذه العملية عبر libkeyutils (من الإصدار 1.5.10 وما بعده) من خلال الدوال keyctl_dh_compute(3) و keyctl_dh_compute_alloc(3).
تطبيق قيد على ربط المفاتيح بحلقة المفاتيح ذات المعرف المقدم في arg2 (بتحويله إلى key_serial_t). يجب أن يمتلك المستدعِي إذن setattr على المفتاح. إذا كان arg3 هو NULL، فستُحظر أي محاولة لإضافة مفتاح إلى حلقة المفاتيح؛ وإلا فإنه يحتوي على مؤشر لسلسلة بها اسم نوع المفتاح ويحتوي arg4 على مؤشر لسلسلة تصف القيد الخاص بالنوع. بدءاً من لينكس 4.12، حُددت قيود لنوع "asymmetric" (غير المتماثل) فقط:
يسمح فقط بالمفاتيح الموقعة بمفتاح مرتبط بحلقة المفاتيح المضمنة (".builtin_trusted_keys").
يسمح فقط بالمفاتيح الموقعة بمفتاح مرتبط بحلقة المفاتيح الثانوية (".secondary_trusted_keys") أو، بالتبعية، مفتاح في حلقة مفاتيح مضمنة، بما أن الأخيرة مرتبطة بالأولى.
إذا حدد key معرف مفتاح من نوع "asymmetric"، فسيُسمح فقط بالمفاتيح الموقعة بهذا المفتاح.
إذا حدد key معرف حلقة مفاتيح، فسيُسمح فقط بالمفاتيح الموقعة بمفتاح مرتبط بحلقة المفاتيح هذه.
إذا حُدد ":chain"، فسيُسمح أيضًا بالمفاتيح الموقعة بمفاتيح مرتبطة بحلقة المفاتيح الوجهة (أي حلقة المفاتيح ذات المعرف المحدد في المعامل arg2).
لاحظ أنه يمكن ضبط قيد مرة واحدة فقط لحلقة المفاتيح المحددة؛ وبمجرد ضبط القيد، لا يمكن تجاوزه.
يُتجاهل المعامل arg5.

قيمة الإرجاع

في حالة الاستدعاء الناجح، تعتمد قيمة الإرجاع على العملية:

معرف حلقة المفاتيح المطلوبة.
معرف حلقة مفاتيح الجلسة التي انُضم إليها.
حجم الوصف (بما في ذلك البايت الصفري المنتهي)، بغض النظر عن حجم المخزن المؤقت المقدم.
معرف المفتاح الذي عُثر عليه.
كمية البيانات المتوفرة في المفتاح، بغض النظر عن حجم المخزن المؤقت المقدم.
معرف حلقة المفاتيح المبدئية السابقة التي كانت المفاتيح المطلوبة ضمنيًا تُرتبط بها (أحد KEY_REQKEY_DEFL_USER_*).
إما 0، إذا كان المعرف المعطى 0، أو معرف مفتاح الاستيثاق المطابق للمفتاح المحدد، إذا قُدم معرف مفتاح غير صفري.
حجم سلسلة لصيقة أمان LSM (بما في ذلك البايت الصفري المنتهي)، بغض النظر عن حجم المخزن المؤقت المقدم.
معرف حلقة المفاتيح المستمرة.
عدد البايتات المنسوخة إلى المخزن المؤقت، أو، إذا كان arg4 هو 0، حجم المخزن المؤقت المطلوب.
جميع العمليات الأخرى
صفر.

عند الخطأ، تُعاد القيمة -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

العملية المطلوبة لم تكن مسموحة.
كانت operation هي KEYCTL_DH_COMPUTE وحدث خطأ أثناء تهيئة وحدة التعمية.
كانت operation هي KEYCTL_LINK والربط المطلوب سيؤدي إلى حلقة مفرغة (cycle).
كانت operation هي KEYCTL_RESTRICT_KEYRING وقيد حلقة المفاتيح المطلوب سيؤدي إلى حلقة مفرغة.
حصة المفاتيح لمستخدم المستدعِي ستُتجاوز بإنشاء مفتاح أو ربطه بحلقة المفاتيح.
كانت operation هي KEYCTL_RESTRICT_KEYRING وحلقة المفاتيح المقدمة في المعامل arg2 لها قيد مضبوط بالفعل.
كانت operation هي KEYCTL_DH_COMPUTE وفشل أحد الإجراءات التالية:
نسخ struct keyctl_dh_params، المقدم في المعامل arg2، من مساحة المستخدم؛
نسخ struct keyctl_kdf_params، المقدم في المعامل arg5 غير الصفري، من مساحة المستخدم (في حال كانت النواة تدعم إجراء عملية KDF على نتيجة عملية DH)؛
نسخ البيانات التي يشير إليها حقل hashname في struct keyctl_kdf_params من فضاء المستخدم؛
نسخ البيانات التي يشير إليها حقل otherinfo في struct keyctl_kdf_params من فضاء المستخدم إذا كان حقل otherinfolen غير صفري؛
نسخ النتيجة إلى فضاء المستخدم.
كانت الـ operation هي KEYCTL_SETPERM وحُدِّدت بتة صلاحية غير صالحة في arg3.
كانت الـ operation هي KEYCTL_SEARCH وتجاوز حجم الوصف في arg4 (بما في ذلك بايت الإنهاء الفارغ) 4096 بايت.
حجم السلسلة (بما في ذلك بايت الإنهاء الصفري) المحدد في arg3 (نوع المفتاح) أو arg4 (وصف المفتاح) تجاوز الحد (32 بايت و 4096 بايت على التوالي).
كانت الـ operation هي KEYCTL_DH_COMPUTE، وكان المعامل arg5 غير فارغ (non-NULL).
كانت الـ operation هي KEYCTL_DH_COMPUTE وحجم الخلاصة لخوارزمية التجزئة المقدمة صفر.
كانت الـ operation هي KEYCTL_DH_COMPUTE وحجم المخزن المؤقت المقدم غير كافٍ لاستيعاب النتيجة. قدم 0 كحجم للمخزن المؤقت للحصول على الحد الأدنى لحجم المخزن المؤقت.
كانت الـ operation هي KEYCTL_DH_COMPUTE واسم التجزئة المقدم في حقل hashname لـ struct keyctl_kdf_params الذي يشير إليه المعامل arg5 كبير جداً (هذا الحد يعتمد على التنفيذ ويختلف بين إصدارات النواة، ولكنه يُعد كافياً لجميع أسماء الخوارزميات الصالحة).
كانت الـ operation هي KEYCTL_DH_COMPUTE ويحتوي حقل __spare في struct keyctl_kdf_params المقدم في المعامل arg5 على قيم غير صفرية.
وُجد أو حُدد مفتاح منتهي الصلاحية.
وُجد أو حُدد مفتاح مرفوض.
وُجد أو حُدد مفتاح ملغى.
كانت الـ operation هي KEYCTL_LINK وسيؤدي الرابط المطلوب إلى تجاوز أقصى عمق تعشيش لحلقات المفاتيح.
كانت الـ operation هي KEYCTL_DH_COMPUTE وطول المخزن المؤقت يتجاوز KEYCTL_KDF_MAX_OUTPUT_LEN (وهو 1024 حالياً) أو يتجاوز حقل otherinfolen في struct keyctl_kdf_parms الممرر في arg5 القيمة KEYCTL_KDF_MAX_OI_LEN (وهي 64 حالياً).
كانت الـ operation هي KEYCTL_LINK وحلقة المفاتيح ممتلئة. (قبل لينكس 3.13، كانت المساحة المتاحة لتخزين روابط حلقات المفاتيح محدودة بصفحة ذاكرة واحدة؛ ومنذ لينكس 3.13، لا يوجد حد ثابت).
كانت الـ operation هي KEYCTL_UNLINK والمفتاح المراد فصله غير مرتبط بحلقة المفاتيح.
كانت الـ operation هي KEYCTL_DH_COMPUTE ولم يُعثر على خوارزمية التجزئة المحددة في حقل hashname لـ struct keyctl_kdf_params الذي يشير إليه المعامل arg5.
كانت الـ operation هي KEYCTL_RESTRICT_KEYRING والنوع المقدم في المعامل arg3 لا يدعم ضبط قيود ربط المفاتيح.
لم يُعثر على مفتاح مطابق أو حُدد مفتاح غير صالح.
حُدِّدت القيمة KEYCTL_GET_KEYRING_ID في operation، والمفتاح المحدد في arg2 غير موجود، وكان arg3 صفراً (بمعنى عدم إنشاء المفتاح إذا لم يكن موجوداً).
فشلت إحدى روتينات تخصيص ذاكرة النواة أثناء تنفيذ استدعاء النظام.
تُوقع مفتاح من نوع حلقة مفاتيح ولكن قُدم معرف مفتاح بنوع مختلف.
كانت الـ operation هي KEYCTL_READ ونوع المفتاح لا يدعم القراءة (على سبيل المثال، النوع هو "login").
كانت الـ operation هي KEYCTL_UPDATE ونوع المفتاح لا يدعم التحديث.
كانت الـ operation هي KEYCTL_RESTRICT_KEYRING، والنوع المقدم في المعامل arg3 هو "asymmetric"، والمفتاح المحدد في مواصفات القيد المقدمة في arg4 له نوع آخر غير "asymmetric" أو "keyring".
كانت الـ operation هي KEYCTL_GET_PERSISTENT، وحدد arg2 معرف مستخدم (UID) يختلف عن معرف المستخدم الحقيقي أو الفعلي للخيط المستدعِي، ولم يمتلك المستدعِي قدرة CAP_SETUID.
كانت الـ operation هي KEYCTL_SESSION_TO_PARENT وإما: أن جميع معرفات المستخدم (أو المجموعات) للعملية الأب لا تطابق معرف المستخدم (أو المجموعة) الفعلي للعملية المستدعِية؛ أو أن معرف المستخدم لحلقة مفاتيح الجلسة الحالية للأب أو معرف المستخدم لحلقة مفاتيح الجلسة للمستدعِي لم يطابق معرف المستخدم الفعلي للمستدعِي؛ أو أن العملية الأب ليست وحيدة الخيط؛ أو أن العملية الأب هي init(1) أو خيط نواة.
كانت الـ operation هي KEYCTL_DH_COMPUTE وانتهت مهلة تهيئة وحدات التعمية.

الإصدارات

يُوفّر غلاف في مكتبة libkeyutils. (تُوفّر الحزمة المرفقة ملف الترويسة <keyutils.h>). ومع ذلك، بدلاً من استخدام استدعاء النظام هذا مباشرةً، ربما تود استخدام دوال المكتبة المتنوعة المذكورة في أوصاف العمليات الفردية أعلاه.

المعايير

لينكس.

التاريخ

لينكس 2.6.10.

أمثلة

يوفر البرنامج أدناه مجموعة فرعية من وظائف برنامج request-key(8) الذي توفره حزمة keyutils. لأغراض إعلامية، يسجل البرنامج معلومات متنوعة في ملف سجل.

كما هو موضح في request_key(2)، يُستدعى برنامج request-key(8) بمعاملات سطر الأوامر التي تصف مفتاحاً سيُنشأ. يجلب برنامج المثال هذه المعاملات ويسجلها. يفترض البرنامج سلطة إنشاء المفتاح المطلوب، ثم ينشئ ذلك المفتاح.

توضح جلسة الصدفة التالية استخدام هذا البرنامج. في الجلسة، نصرف البرنامج ثم نستخدمه لاستبدال برنامج request-key(8) المعياري مؤقتاً. (لاحظ أن تعطيل برنامج request-key(8) المعياري مؤقتاً قد لا يكون آمناً في بعض الأنظمة). بينما يكون برنامج المثال الخاص بنا مثبتاً، نستخدم برنامج المثال الموضح في request_key(2) لطلب مفتاح.


$ cc -o key_instantiate key_instantiate.c -lkeyutils
$ sudo mv /sbin/request-key /sbin/request-key.backup
$ sudo cp key_instantiate /sbin/request-key
$ ./t_request_key user mykey somepayloaddata
Key ID is 20d035bf
$ sudo mv /sbin/request-key.backup /sbin/request-key

بالنظر إلى ملف السجل الذي أنشأه هذا البرنامج، يمكننا رؤية معاملات سطر الأوامر المقدمة لبرنامج المثال الخاص بنا:


$ cat /tmp/key_instantiate.log
Time: Mon Nov  7 13:06:47 2016
Command line arguments:

argv[0]: /sbin/request-key
operation: create
key_to_instantiate: 20d035bf
UID: 1000
GID: 1000
thread_keyring: 0
process_keyring: 0
session_keyring: 256e6a6 Key description: user;1000;1000;3f010000;mykey Auth key payload: somepayloaddata Destination keyring: 256e6a6 Auth key description: .request_key_auth;1000;1000;0b010000;20d035bf

تظهر الأسطر القليلة الأخيرة من المخرجات أعلاه أن برنامج المثال كان قادراً على جلب:

وصف المفتاح المُراد إنشاؤه، والذي يتضمن اسم المفتاح (mykey
حمولة مفتاح الاستيثاق، والتي تتكون من البيانات (somepayloaddata) الممرة إلى request_key(2)؛
حلقة مفاتيح الوجهة التي حُددت في استدعاء request_key(2)؛ و
وصف مفتاح الاستيثاق، حيث يمكننا رؤية أن اسم مفتاح الاستيثاق يطابق معرف المفتاح المُراد إنشاؤه (20d035bf).

حدد برنامج المثال في request_key(2) حلقة مفاتيح الوجهة بـ KEY_SPEC_SESSION_KEYRING. بفحص محتويات /proc/keys، يمكننا رؤية أن هذا قد تُرجم إلى معرف حلقة مفاتيح الوجهة (0256e6a6) الموضح في مخرجات السجل أعلاه؛ يمكننا أيضًا رؤية المفتاح المُنشأ حديثاً باسم mykey والمعرف 20d035bf.


$ cat /proc/keys | egrep 'mykey|256e6a6'
0256e6a6 I--Q---  194 perm 3f030000  1000  1000 keyring  _ses: 3
20d035bf I--Q---    1 perm 3f010000  1000  1000 user     mykey: 16

مصدر البرنامج

/* key_instantiate.c */
#include <errno.h>
#include <keyutils.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#ifndef KEY_SPEC_REQUESTOR_KEYRING
#define KEY_SPEC_REQUESTOR_KEYRING      (-8)
#endif
int
main(int argc, char *argv[])
{

int akp_size; /* حجم auth_key_payload */
int auth_key;
char dbuf[256];
char auth_key_payload[256];
char *operation;
FILE *fp;
gid_t gid;
uid_t uid;
time_t t;
key_serial_t key_to_instantiate, dest_keyring;
key_serial_t thread_keyring, process_keyring, session_keyring;
if (argc != 8) {
fprintf(stderr, "Usage: %s op key uid gid thread_keyring "
"process_keyring session_keyring\n", argv[0]);
exit(EXIT_FAILURE);
}
fp = fopen("/tmp/key_instantiate.log", "w");
if (fp == NULL)
exit(EXIT_FAILURE);
setbuf(fp, NULL);
t = time(NULL);
fprintf(fp, "Time: %s\n", ctime(&t));
/*
* تمرر النواة مجموعة ثابتة من المعاملات للبرنامج
* الذي تنفذه؛ لذا جلبهم.
*/
operation = argv[1];
key_to_instantiate = atoi(argv[2]);
uid = atoi(argv[3]);
gid = atoi(argv[4]);
thread_keyring = atoi(argv[5]);
process_keyring = atoi(argv[6]);
session_keyring = atoi(argv[7]);
fprintf(fp, "Command line arguments:\n");
fprintf(fp, " argv[0]: %s\n", argv[0]);
fprintf(fp, " operation: %s\n", operation);
fprintf(fp, " key_to_instantiate: %jx\n",
(uintmax_t) key_to_instantiate);
fprintf(fp, " UID: %jd\n", (intmax_t) uid);
fprintf(fp, " GID: %jd\n", (intmax_t) gid);
fprintf(fp, " thread_keyring: %jx\n",
(uintmax_t) thread_keyring);
fprintf(fp, " process_keyring: %jx\n",
(uintmax_t) process_keyring);
fprintf(fp, " session_keyring: %jx\n",
(uintmax_t) session_keyring);
fprintf(fp, "\n");
/*
* افتراض السلطة لتمثيل المفتاح المسمى في argv[2].
*/
if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) {
fprintf(fp, "KEYCTL_ASSUME_AUTHORITY failed: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
/*
* جلب وصف المفتاح المراد تمثيله.
*/
if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
dbuf, sizeof(dbuf)) == -1) {
fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "Key description: %s\n", dbuf);
/*
* جلب حمولة مفتاح الاستيثاق، والتي هي
* في الواقع بيانات الاستدعاء المعطاة لـ request_key().
*/
akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
auth_key_payload, sizeof(auth_key_payload));
if (akp_size == -1) {
fprintf(fp, "KEYCTL_READ failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
auth_key_payload[akp_size] = '\0';
fprintf(fp, "Auth key payload: %s\n", auth_key_payload);
/*
* للاهتمام، الحصول على معرف مفتاح الاستيثاق و
* عرضه.
*/
auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_REQKEY_AUTH_KEY);
if (auth_key == -1) {
fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "Auth key ID: %jx\n", (uintmax_t) auth_key);
/*
* جلب معرف المفتاح لحلقة مفاتيح الوجهة لـ request_key(2).
*/
dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
KEY_SPEC_REQUESTOR_KEYRING);
if (dest_keyring == -1) {
fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "Destination keyring: %jx\n", (uintmax_t) dest_keyring);
/*
* جلب وصف مفتاح الاستيثاق. هذا
* يسمح لنا برؤية نوع المفتاح، ومعرف المستخدم (UID)، ومعرف المجموعة (GID)،
* والصلاحيات، ووصف (اسم) المفتاح. من بين أمور أخرى،
* سنرى أن اسم المفتاح هو سلسلة ست عشرية
* تمثل معرف المفتاح المراد تمثيله.
*/
if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
dbuf, sizeof(dbuf)) == -1)
{
fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(fp, "Auth key description: %s\n", dbuf);
/*
* تمثيل المفتاح باستخدام بيانات الاستدعاء التي قُدِّمت
* في حمولة مفتاح الاستيثاق.
*/
if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
auth_key_payload, akp_size + 1, dest_keyring) == -1)
{
fprintf(fp, "KEYCTL_INSTANTIATE failed: %s\n",
strerror(errno));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS); }

انظر أيضًا

keyctl(1), add_key(2), request_key(2), keyctl(3), keyctl_assume_authority(3), keyctl_chown(3), keyctl_clear(3), keyctl_describe(3), keyctl_describe_alloc(3), keyctl_dh_compute(3), keyctl_dh_compute_alloc(3), keyctl_get_keyring_ID(3), keyctl_get_persistent(3), keyctl_get_security(3), keyctl_get_security_alloc(3), keyctl_instantiate(3), keyctl_instantiate_iov(3), keyctl_invalidate(3), keyctl_join_session_keyring(3), keyctl_link(3), keyctl_negate(3), keyctl_read(3), keyctl_read_alloc(3), keyctl_reject(3), keyctl_revoke(3), keyctl_search(3), keyctl_session_to_parent(3), keyctl_set_reqkey_keyring(3), keyctl_set_timeout(3), keyctl_setperm(3), keyctl_unlink(3), keyctl_update(3), recursive_key_scan(3), recursive_session_key_scan(3), capabilities(7), credentials(7), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user_namespaces(7), user-session-keyring(7), request-key(8)

ملفات مصدر النواة تحت Documentation/security/keys/ (أو، قبل لينكس 4.13، في الملف Documentation/security/keys.txt).

ترجمة

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

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

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

15 يونيو 2024 صفحات دليل لينكس 6.9.1