| POLKIT(8) | polkit | POLKIT(8) |
نام (NAME)
polkit - مدیر مجوزدهی
نمای کلی (OVERVIEW)
ابزار polkit یک API مجوزدهی ارائه میدهد که برای استفاده توسط برنامههای دارای دسترسی ویژه (“MECHANISMS” یا سازوکارها) در هنگام ارائه خدمات به برنامههای فاقد دسترسی ویژه (“SUBJECTS” یا موضوعها)، اغلب از طریق نوعی سازوکار ارتباط بینپردازشی (IPC) طراحی شده است. در این سناریو، سازوکار معمولاً با موضوع به عنوان موجودیتی غیرقابلاعتماد رفتار میکند. به ازای هر درخواست از جانب یک موضوع، سازوکار باید تعیین کند که آیا درخواست مجاز است یا باید از ارائه خدمات به موضوع امتناع ورزد. با استفاده از APIهای polkit، سازوکار میتواند این تصمیمگیری را به یک مرجع قابلاعتماد واگذار کند: مرجع polkit (یا همان polkit authority).
مرجع polkit به صورت یک دیمن سیستمی پیادهسازی شده است، polkitd(8)، که خودش دسترسیهای اندکی دارد زیرا با کاربر سیستمی polkitd اجرا میشود. سازوکارها، موضوعها و عاملهای احراز هویت با استفاده از گذرگاه پیام سیستم (system message bus) با مرجع ارتباط برقرار میکنند.
علاوه بر عمل به عنوان یک مرجع، polkit به کاربران اجازه میدهد تا از طریق احراز هویت یک کاربر مدیریتی یا مالک نشستی که کلاینت به آن تعلق دارد، مجوز موقت دریافت کنند. این ویژگی برای سناریوهایی مفید است که در آنها یک سازوکار نیاز دارد تأیید کند که گرداننده سیستم واقعاً همان کاربر یا یک کاربر مدیریتی است.
معماری سامانه (SYSTEM ARCHITECTURE)
معماری سامانه polkit از مرجع (Authority) (پیادهسازیشده به عنوان یک سرویس روی گذرگاه پیام سیستم) و یک عامل احراز هویت (Authentication Agent) به ازای هر نشست کاربری (ارائهشده و راهاندازیشده توسط محیط گرافیکی کاربر) تشکیل شده است. کنشها (Actions) توسط برنامهها تعریف میشوند. توزیعکنندگان، سازمانها و مدیران سیستم میتوانند سیاستهای مجوزدهی را از طریق قواعد مجوزدهی (Authorization Rules) کنترل کنند.
+-------------------+
| Authentication |
| Agent |
+-------------------+
| libpolkit-agent-1 |
+-------------------+
^ +---------+
| | Subject |
+--------------+ +---------+
| ^
| |
User Session | |
=======================|========================|=============
System Context | |
| |
| +---+
V |
/------------\ |
| System Bus | |
\------------/ |
^ ^ V
| | +---------------------+
+--------------+ | | Mechanism |
| | +---------------------+
V +----> | libpolkit-gobject-1 |
+------------------+ +---------------------+
| polkitd(8) |
+------------------+
| org.freedesktop. |
| PolicyKit1 |<---------+
+------------------+ |
^ |
| +--------------------------------------------+
| | /etc/polkit-1/actions/*.policy |
| | /run/polkit-1/actions/*.policy |
| | /usr/local/share/polkit-1/actions/*.policy |
| | /usr/share/polkit-1/actions/*.policy |
| +--------------------------------------------+
|
+--------------------------------------------+
| /etc/polkit-1/rules.d/*.rules |
| /run/polkit-1/rules.d/*.rules |
| /usr/local/share/polkit-1/rules.d/*.rules |
| /usr/share/polkit-1/rules.d/*.rules |
+--------------------------------------------+
برای سهولت، کتابخانه libpolkit-gobject-1 API مبتنی بر D-Bus پامک polkit را کپسولهسازی میکند و از هر برنامه C/C++ و همچنین زبانهای سطح بالاتری که از GObjectIntrospection[2] پشتیبانی میکنند (مانند JavaScript و Python) قابل استفاده است. یک سازوکار همچنین میتواند مستقیماً از API د-باس یا دستور pkcheck(1) برای بررسی مجوزها استفاده کند. کتابخانه libpolkit-agent-1 یک انتزاع از سیستم احراز هویت بومی، مانند pam(8)، و همچنین امکاناتی برای ثبتنام و ارتباط با سرویس D-Bus در polkit فراهم میآورد.
برای اطلاعات بیشتر درباره نوشتن برنامههای polkit به مستندات توسعهدهندگان[3] مراجعه فرمایید.
عاملهای احراز هویت (AUTHENTICATION AGENTS)
یک عامل احراز هویت برای این استفاده میشود که کاربر یک نشست ثابت کند واقعاً همان کاربر است (با احراز هویت به عنوان خود کاربر) یا یک کاربر مدیریتی است (با احراز هویت به عنوان مدیر سیستم). برای یکپارچگی مناسب با سایر بخشهای نشست کاربر (برای نمونه تطابق با ظاهر و احساس بصری)، عاملهای احراز هویت باید توسط همان نشست کاربری که کاربر از آن استفاده میکند ارائه شوند. برای نمونه، یک عامل احراز هویت ممکن است اینگونه باشد:
+----------------------------------------------------------+ | | | [Icon] Authentication required | | | | Authentication is required to format INTEL | | SSDSA2MH080G1GC (/dev/sda) | | | | Administrator | | | | Password: [__________________________________] | | | | [Cancel] [Authenticate] | +----------------------------------------------------------+
اگر سیستم بدون حساب root پیکربندی شده باشد، ممکن است برای کاربری خاص که به عنوان کاربر مدیریتی تعیین شده است اعلان هویت نمایش دهد:
+----------------------------------------------------------+ | | | [Icon] Authentication required | | | | Authentication is required to format INTEL | | SSDSA2MH080G1GC (/dev/sda) | | | | [Icon] David Zeuthen | | | | Password: [__________________________________] | | | | [Cancel] [Authenticate] | +----------------------------------------------------------+
برنامههایی که تحت یک محیط رومیزی اجرا نمیشوند (برای نمونه، اگر از طریق نشست ورودی ssh(1) راهاندازی شده باشند) ممکن است عامل احراز هویت مرتبطی در اختیار نداشته باشند. چنین برنامههایی میتوانند از نوع PolkitAgentTextListener یا ابزار کمکی pkttyagent(1) استفاده کنند تا کاربر بتواند با یک رابط متنی احراز هویت را انجام دهد.
تعریف کنشها (DECLARING ACTIONS)
یک سازوکار برای استفاده از polkit باید مجموعهای از کنشها (actions) را اعلان کند. کنشها متناظر با عملیاتی هستند که کلاینتها میتوانند از سازوکار درخواست کنند تا انجام دهد و در فایلهای XML تعریف میشوند که سازوکار آنها را در دایرکتوری /usr/share/polkit-1/actions نصب میکند.
کنشهای polkit دارای فضاینام (namespaced) هستند و فقط میتوانند شامل نویسههای "[A-Z][a-z][0-9].-" باشند، مانند ASCII، ارقام، نقطه و خط تیره. هر فایل XML میتواند شامل بیش از یک کنش باشد اما تمام کنشها باید در همان فضاینام قرار داشته باشند و نام فایل نیز باید بر اساس فضاینام نامگذاری شده و دارای پسوند .policy باشد.
فایل XML باید دارای اعلان نوع سند (doctype) زیر باشد:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD polkit Policy Configuration 1.0//EN" "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
عنصر policyconfig باید دقیقاً یک بار وجود داشته باشد. عناصری که میتوانند درون policyconfig استفاده شوند عبارتند از:
vendor
vendor_url
icon_name
action
عناصری که میتوانند درون action استفاده شوند شامل موارد زیر است:
description
message
defaults
allow_any
allow_inactive
allow_active
هر یک از عناصر allow_any، allow_inactive و allow_active میتوانند حاوی مقادیر زیر باشند:
no
yes
auth_self
auth_admin
auth_self_keep
auth_admin_keep
annotate
vendor
vendor_url
icon_name
برای بومیسازی، عناصر description و message میتوانند چندین بار با ویژگیهای مختلف xml:lang ظاهر شوند.
برای فهرست کردن کنشهای نصبشده polkit، از دستور pkaction(1) استفاده کنید.
یادداشتهای شناختهشده (Known annotations)
یادداشت org.freedesktop.policykit.exec.path توسط برنامه pkexec که به همراه polkit ارائه میشود مورد استفاده قرار میگیرد - برای جزئیات به صفحه راهنمای pkexec(1) مراجعه کنید.
یادداشت org.freedesktop.policykit.imply (مقدار آن رشتهای حاوی فهرستی از شناسههای کنش جداشده با فاصله است) میتواند برای تعریف ابَرکنشها (meta actions) استفاده شود. شیوه کار آن به این صورت است که اگر یک موضوع برای کنشی دارای این یادداشت مجاز شناخته شود، آنگاه برای هر کنش دیگری که توسط این یادداشت تعیین شده نیز مجاز خواهد بود. یک کاربرد معمول این یادداشت زمانی است که یک پوسته واسط کاربری دارای یک دکمه قفل واحد تعریف میشود که باید قفل چندین کنش از سازوکارهای متمایز را باز کند.
یادداشت org.freedesktop.policykit.owner میتواند برای تعریف مجموعهای از کاربران استفاده شود که مجازند بررسی کنند آیا یک کلاینت برای اجرای این کنش مجاز است یا خیر. اگر این یادداشت مشخص نشود، تنها کاربر root میتواند بررسی کند آیا کلاینتی که با کاربر متفاوتی اجرا شده مجاز به انجام کنش است یا خیر. مقدار این یادداشت رشتهای حاوی فهرستی فاصلهجدا از مدخلهای PolkitIdentity است، برای نمونه "unix-user:42 unix-user:colord". یک کاربرد رایج این یادداشت برای پردازههای دیمنی است که به جای root با یک کاربر سیستمی اجرا میشوند.
قواعد مجوزدهی (AUTHORIZATION RULES)
دیمن polkitd فایلهای دارای پسوند .rules را از دایرکتوریهای زیر و به همین ترتیب میخواند:
این دایرکتوریها بر اساس نام پایه (basename) هر فایل به ترتیب واژگانی پردازش میشوند. در صورت تساوی نام، فایلهای موجود در دایرکتوریهایی که بالاتر در فهرست قرار دارند زودتر پردازش میشوند. برای نمونه، برای چهار فایل زیر، ترتیب پردازش چنین است:
تمامی این دایرکتوریها پایش میشوند، بنابراین اگر یک فایل قواعد تغییر کند، اضافه شود یا حذف گردد، قواعد موجود پاکسازی شده و تمامی فایلها دوباره خوانده و پردازش میشوند. فایلهای قواعد با زبان برنامهنویسی JavaScript[7] نوشته میشوند و از طریق شیء عمومی polkit (از نوع Polkit) با polkitd تعامل برقرار میکنند.
اگرچه مفسر جاوااسکریپت استفادهشده در نسخههای خاصی از polkit ممکن است از ویژگیهای غیراستاندارد (مانند کلمه کلیدی let) پشتیبانی کند، اما قواعد مجوزدهی باید با ECMA-262 ویرایش ۵[8] سازگار باشند (به بیان دیگر، مفسر جاوااسکریپت مورداستفاده ممکن است در نسخههای آینده polkit تغییر کند).
قواعد مجوزدهی تنها برای دو گروه مخاطب مشخص در نظر گرفته شدهاند:
و فقط همین مخاطبان. به ویژه، برنامهها، سازوکارها و سیستمعاملهای چندمنظوره هرگز نباید هیچ قاعده مجوزدهی در خود بگنجانند.
نوع Polkit (The Polkit type)
متدهای زیر روی شیء polkit در دسترس هستند:
void addRule(polkit.Result function(action, subject) {...});
void addAdminRule(string[] function(action, subject) {...});
void log(string message);
string spawn(string[] argv);
متد addRule() برای افزودن تابعی استفاده میشود که هر زمان بررسی مجوز برای action و subject انجام گیرد، فراخوانی خواهد شد. توابع به همان ترتیبی که اضافه شدهاند فراخوانی میشوند تا زمانی که یکی از توابع مقداری بازگرداند. بنابراین، برای افزودن یک قاعده مجوزدهی که پیش از سایر قواعد پردازش شود، آن را در فایلی در /etc/polkit-1/rules.d قرار دهید که نام آن از نظر الفبایی پیش از سایر فایلهای قواعد مرتب شود، برای نمونه 00-early-checks.rules. هر تابع باید مقداری از polkit.Result را بازگرداند
polkit.Result = {
NO : "no",
YES : "yes",
AUTH_SELF : "auth_self",
AUTH_SELF_KEEP : "auth_self_keep",
AUTH_ADMIN : "auth_admin",
AUTH_ADMIN_KEEP : "auth_admin_keep",
NOT_HANDLED : null
};
که متناظر با مقادیری است که میتوانند به عنوان پیشفرضها استفاده شوند. اگر تابع polkit.Result.NOT_HANDLED، null، undefined را بازگرداند یا اصلاً مقداری بازنگرداند، تابع کاربری بعدی امتحان میشود.
به خاطر داشته باشید که اگر polkit.Result.AUTH_SELF_KEEP یا polkit.Result.AUTH_ADMIN_KEEP بازگردانده شود، بررسیهای مجوزدهی برای شناسه کنش و موضوع یکسان برای مدت کوتاه بعدی (مثلاً پنج دقیقه) با موفقیت مواجه خواهند شد (یعنی مقدار polkit.Result.YES را برمیگردانند)، حتی اگر متغیرهای ارائهشده به همراه بررسی متفاوت باشند. بنابراین، اگر نتیجه یک قاعده مجوزدهی به چنین متغیرهایی وابسته است، نباید از ثابتهای "*_KEEP" استفاده کند (اگر عملکرد مشابهی نیاز باشد، قاعده مجوزدهی میتواند با استفاده از نوع Date[9] برای برچسبهای زمانی، مجوزهای موقت را به سادگی پیادهسازی کند).
متد addAdminRule() برای افزودن تابعی استفاده میشود که هر زمان احراز هویت مدیر سیستم نیاز باشد، فراخوانی خواهد شد. این تابع برای تعیین هویتهایی به کار میرود که ممکن است برای احراز هویت مدیریتی در بررسی مجوزی که با action و subject شناسایی شده، مورد استفاده قرار گیرند. توابع اضافهشده به ترتیبی که افزوده شدهاند فراخوانی میشوند تا زمانی که یکی از آنها مقداری برگرداند. هر تابع باید آرایهای از رشتهها را برگرداند که هر رشته به شکل "unix-group:<group>", "unix-netgroup:<netgroup>" یا "unix-user:<user>" باشد. اگر تابع مقدار null، undefined یا هیچ مقداری بازنگرداند، تابع بعدی آزموده میشود.
هیچ تضمینی وجود ندارد که تابعی که با addRule() یا addAdminRule() ثبت شده است حتماً فراخوانی شود - برای نمونه یک فایل قواعد اولیه ممکن است تابعی را ثبت کند که همواره مقداری برمیگرداند و در نتیجه مانع از فراخوانی توابعی شود که بعداً اضافه شدهاند.
اگر اجرای کد ارائهشده توسط کاربر زمان زیادی طول بکشد، استثنایی ایجاد نخواهد شد و اسکریپت بلافاصله خاتمه داده میشود (محدودیت فعلی ۱۵ ثانیه است). این کار برای مهار اسکریپتهای مهارنشدنی استفاده میشود.
متد spawn() یک برنامه کمکی بیرونی را که با بردار آرگومانهای argv مشخص شده اجرا میکند و منتظر پایان آن میماند. اگر خطایی رخ دهد یا برنامه کمکی به صورت عادی با کد خروج ۰ پایان نیابد، یک استثنا صادر میشود. اگر برنامه کمکی ظرف مدت ۱۰ ثانیه به پایان نرسد، متوقف و کشته خواهد شد. در غیر این صورت، خروجی استاندارد برنامه به عنوان یک رشته بازگردانده میشود. متد spawn() باید با احتیاط و به ندرت استفاده شود زیرا برنامههای کمکی ممکن است زمان طولانی یا نامشخصی برای تکمیل نیاز داشته باشند و در زمان اجرای آنها هیچ بررسی مجوز دیگری قابل انجام نیست. توجه داشته باشید که برنامههای اجراشده با کاربر سیستمی فاقد امتیاز polkitd اجرا خواهند شد.
متد log() پیام message دادهشده را با پیشوند نام فایل جاوااسکریپت و شماره خط در ثبتکننده وقایع سیستم (logger) مینویسد. ورودیهای لاگ با فلگ LOG_AUTHPRIV ارسال میشوند به این معنی که معمولاً در فایل /var/log/secure قرار میگیرند. متد log() معمولاً فقط هنگام اشکالزدایی قواعد به کار میرود. انواع Action و Subject متدهای مناسب toString() را برای لاگگیری آسان تعریف کردهاند، برای نمونه:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.policykit.exec") {
polkit.log("action=" + action);
polkit.log("subject=" + subject);
}
});
هنگامی که کاربر دستور 'pkexec -u bateman bash -i' را از یک پوسته اجرا کند، خروجی زیر تولید خواهد شد:
May 24 14:28:50 thinkpad polkitd[32217]: /etc/polkit-1/rules.d/10-test.rules:3: action=[Action id='org.freedesktop.policykit.exec' command_line='/usr/bin/bash -i' program='/usr/bin/bash' user='bateman' user.gecos='Patrick Bateman' user.display='Patrick Bateman (bateman)'] May 24 14:28:50 thinkpad polkitd[32217]: /etc/polkit-1/rules.d/10-test.rules:4: subject=[Subject pid=1352 user='davidz' groups=davidz,wheel, seat='seat0' session='1' local=true active=true]
نوع Action (The Action type)
پارامتر action که به توابع کاربری فرستاده میشود شیئی حاوی اطلاعاتی درباره کنش در حال بررسی است. این شیء از نوع Action بوده و دارای ویژگی زیر است:
string id
متدهای زیر روی نوع Action در دسترس هستند:
string lookup(string key);
متد lookup() برای جستجوی متغیرهای polkit که از سازوکار ارسال شدهاند استفاده میشود. برای نمونه، سازوکار pkexec(1) متغیر program را تنظیم میکند که میتوان آن را در جاوااسکریپت با استفاده از عبارت action.lookup("program") به دست آورد. اگر هیچ مقداری برای key دادهشده وجود نداشته باشد، مقدار undefined بازگردانده میشود.
برای اینکه بدانید چه متغیرهایی برای هر کنش در دسترس هستند به مستندات هر سازوکار مراجعه کنید.
نوع Subject (The Subject type)
پارامتر subject که به توابع کاربری ارسال میشود شیئی با اطلاعاتی درباره پردازه در حال بررسی است. این شیء از نوع Subject بوده و دارای ویژگیهای زیر است:
int pid
int uid
string user
string[] groups
string seat
string session
string system_unit
boolean local
boolean no_new_privileges
boolean active
متدهای زیر روی نوع Subject در دسترس هستند:
boolean isInGroup(string groupName);
boolean isInNetGroup(string netGroupName);
متد isInGroup() میتواند برای بررسی عضویت موضوع در یک گروه مشخص استفاده شود و isInNetGroup() میتواند برای بررسی اینکه آیا موضوع در یک netgroup مشخص قرار دارد یا خیر به کار رود.
مثالهای قواعد مجوزدهی (Authorization Rules Examples)
اجازه به تمام کاربران در گروه admin برای انجام مدیریت کاربران بدون تغییر سیاست برای سایر کاربران:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.accounts.user-administration" &&
subject.isInGroup("admin")) {
return polkit.Result.YES;
}
});
تعریف کاربران گروه wheel به عنوان کاربران مدیریتی:
polkit.addAdminRule(function(action, subject) {
return ["unix-group:wheel"];
});
منع کاربران در گروه children از تغییر پیکربندی نام میزبان (یعنی هر کنشی با شناسهای که با org.freedesktop.hostname1. آغاز میشود) و اجازه دادن به دیگران پس از احراز هویت به عنوان خودشان:
polkit.addRule(function(action, subject) {
if (action.id.indexOf("org.freedesktop.hostname1.") == 0) {
if (subject.isInGroup("children")) {
return polkit.Result.NO;
} else {
return polkit.Result.AUTH_SELF_KEEP;
}
}
});
اجرای یک برنامه کمکی خارجی برای تعیین اینکه آیا کاربر فعلی میتواند سیستم را مجدداً راهاندازی کند:
polkit.addRule(function(action, subject) {
if (action.id.indexOf("org.freedesktop.login1.reboot") == 0) {
try {
// user-may-reboot exits with success (exit code 0)
// only if the passed username is authorized
polkit.spawn(["/opt/company/bin/user-may-reboot",
subject.user]);
return polkit.Result.YES;
} catch (error) {
// Nope, but do allow admin authentication
return polkit.Result.AUTH_ADMIN;
}
}
});
مثال زیر نشان میدهد که چگونه تصمیم مجوزدهی میتواند به متغیرهای ارسالشده توسط سازوکار pkexec(1) وابسته باشد:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.policykit.exec" &&
action.lookup("program") == "/usr/bin/cat") {
return polkit.Result.AUTH_ADMIN;
}
});
مثال زیر کاربرد دیگری از متغیرهای ارسالشده از سازوکار را نشان میدهد. در این حالت، سازوکار UDisks[10] است که مجموعهای از کنشها و متغیرها[11] را تعریف میکند که برای تطبیق استفاده میشوند:
// Allow users in group 'engineers' to perform any operation on
// some drives without having to authenticate
//
polkit.addRule(function(action, subject) {
if (action.id.indexOf("org.freedesktop.udisks2.") == 0 &&
action.lookup("drive.vendor") == "SEAGATE" &&
action.lookup("drive.model") == "ST3300657SS" &&
subject.isInGroup("engineers")) {
return polkit.Result.YES;
}
}
});
اجازه به تمام پردازههایی که به عنوان بخشی از واحد سیستمی admin.service در systemd اجرا میشوند برای انجام مدیریت کاربران، تا زمانی که نتوانند دسترسیهای جدید کسب کنند:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.accounts.user-administration" &&
subject.system_unit == "admin.service" &&
subject.no_new_privileges) {
return polkit.Result.YES;
}
});
نویسندگان (AUTHORS)
نوشتهشده توسط David Zeuthen <davidz@redhat.com> با کمکهای بسیار از جانب دیگران.
گزارش باگها (BUGS)
لطفاً گزارشهای باگ را به توزیع خود یا به لیست پستی polkit-devel ارسال کنید، ببینید: https://github.com/polkit-org/polkit#bugs-and-development.
همچنین ببینید (SEE ALSO)
polkitd(8), pkaction(1), pkcheck(1), pkexec(1), pkttyagent(1)
یادداشتها (NOTES)
- 1.
- /usr/share/gtk-doc/html/polkit-1/polkit-architecture.png
- 2.
- GObjectIntrospection
- 3.
- مستندات توسعهدهندگان
- 4.
- /usr/share/gtk-doc/html/polkit-1/polkit-authentication-agent-example.png
- 5.
- /usr/share/gtk-doc/html/polkit-1/polkit-authentication-agent-example-wheel.png
- 6.
- شیوهنامه نامگذاری آیکون Freedesktop.org
- 7.
- JavaScript
- 8.
- ECMA-262 ویرایش ۵
- 9.
- Date
- 10.
- UDisks
- 11.
- کنشها و متغیرها
| February 2021 | polkit |