| SUDO_PLUGIN(5) | File Formats Manual | SUDO_PLUGIN(5) |
نام (NAME)
sudo_plugin —
رابط
افزونههای
sudo
توضیحات (DESCRIPTION)
از نسخه
۱.۸ به بعد،
sudo از یک
رابط
برنامهنویسی
(API) افزونه
برای
سیاستگذاری
(policy) و ثبت
نشستها (session logging)
پشتیبانی
میکند.
افزونهها
میتوانند
بهصورت
اشیاء
اشتراکی
پویا (dynamic shared objects - حالت
پیشفرض در
سیستمهایی
که از آنها
پشتیبانی
میکنند)
کامپایل
شوند، یا
بهصورت
ایستا (statically)
درون خود
باینری
sudo
کامپایل
گردند.
بهطور
پیشفرض،
افزونه
sudoers
قابلیتهای
بازرسی (audit)،
سیاستگذاری
امنیتی و
ثبت
ورودی/خروجی
(I/O) را فراهم
میکند. از
طریق API
افزونه،
sudo
میتواند
برای
استفاده از
افزونههای
جایگزینِ
ارائهشده
توسط اشخاص
ثالث
پیکربندی
شود.
افزونههای
مورد
استفاده در
فایل
sudo.conf(5)
مشخص
میشوند.
این API با شمارههای نسخه اصلی (major) و فرعی (minor) نسخهگذاری میشود. با اعمال تغییرات افزایشی، شماره نسخه فرعی افزایش مییابد. با اعمال تغییرات ناسازگار، شماره نسخه اصلی افزایش مییابد. یک افزونه باید نسخهای که به آن ارسال شده است را بررسی کند و مطمئن شود که نسخه اصلی مطابقت دارد.
رابط API
افزونه
توسط فایل
سرآیند
<sudo_plugin.h>
تعریف شده
است.
رابط API افزونه سیاستگذاری (Policy plugin API)
یک افزونه
سیاستگذاری
باید یک struct
policy_plugin را در
دامنه
سراسری (global scope)
اعلان کرده
و مقداردهی
کند. این
ساختار
شامل
اشارهگرهایی
به توابعی
است که
بررسیهای
سیاستگذاری
sudo را
پیادهسازی
میکنند.
نام نماد (symbol)
باید در
sudo.conf(5)
همراه با
مسیری به
افزونه
مشخص شود تا
sudo
بتواند آن
را
بارگذاری
کند.
struct policy_plugin {
#define SUDO_POLICY_PLUGIN 1
unsigned int type; /* always SUDO_POLICY_PLUGIN */
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_plugin_printf, char * const settings[],
char * const user_info[], char * const user_env[],
char * const plugin_options[], const char **errstr);
void (*close)(int exit_status, int error);
int (*show_version)(int verbose);
int (*check_policy)(int argc, char * const argv[],
char *env_add[], char **command_info[],
char **argv_out[], char **user_env_out[], const char **errstr);
int (*list)(int argc, char * const argv[], int verbose,
const char *user, const char **errstr);
int (*validate)(const char **errstr);
void (*invalidate)(int rmcred);
int (*init_session)(struct passwd *pwd, char **user_env[],
const char **errstr);
void (*register_hooks)(int version,
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
struct sudo_plugin_event * (*event_alloc)(void);
};
یک struct policy_plugin دارای فیلدهای زیر است:
- type
- فیلد type همیشه باید روی SUDO_POLICY_PLUGIN تنظیم شود.
- version
- فیلد version
باید روی
SUDO_API_VERSIONتنظیم شود.این به
sudoاجازه میدهد تا نسخه API که افزونه بر اساس آن ساخته شده است را تعیین کند. - open
-
int (*open)(unsigned int version, sudo_conv_t conversation, sudo_printf_t sudo_plugin_printf, char * const settings[], char * const user_info[], char * const user_env[], char * const plugin_options[], const char **errstr);در صورت موفقیت مقدار ۱، در صورت شکست ۰، در صورت بروز خطای عمومی -۱، و در صورت خطای نحوه استفاده (usage error) مقدار -۲ را برمیگرداند. در حالت آخر،
sudoپیش از خروج پیام نحوه استفاده را چاپ خواهد کرد. اگر خطایی رخ دهد، افزونه میتواند به صورت اختیاری تابعconversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری را به کاربر نمایش دهد.آرگومانهای تابع به شرح زیر هستند:
- version
- نسخهای
که توسط
sudoارسال میشود، به افزونه امکان میدهد شماره نسخه اصلی و فرعی API افزونه که توسطsudoپشتیبانی میشود را تعیین کند. - conversation
- اشارهگری
به تابع
conversation() که میتواند توسط افزونه برای تعامل با کاربر استفاده شود (برای جزئیات به Conversation API مراجعه کنید). در صورت موفقیت ۰ و در صورت شکست -۱ برمیگرداند. - sudo_plugin_printf
- اشارهگری
به یک تابع
به سبک
printf() که میتواند برای نمایش پیامهای اطلاعاتی یا خطا استفاده شود (برای جزئیات به Conversation API مراجعه کنید). در صورت موفقیت تعداد نویسههای چاپشده و در صورت شکست -۱ برمیگرداند. - settings
- یک بردار
از
تنظیمات
ارائهشده
توسط
کاربر
برای
sudoبه صورت رشتههای “name=value” است. این بردار با یک اشارهگرNULLخاتمه مییابد. این تنظیمات مربوط به گزینههایی است که کاربر هنگام اجرایsudoمشخص کرده است. بنابراین، آنها تنها زمانی وجود خواهند داشت که گزینه متناظر در خط فرمان مشخص شده باشد.هنگام تجزیه settings ، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تقسیم کند، زیرا فیلد name هرگز شامل مساوی نخواهد بود، اما مقدار value ممکن است شامل آن باشد.مقادیر زیر ممکن است توسط
sudoتنظیم شوند:- bsdauth_type=string
- نوع احراز
هویت، در
صورت مشخص
شدن با
گزینه
-a-،جهت استفاده در سیستمهایی که از احراز هویت BSD پشتیبانی میکنند. - closefrom=number
- در صورت
مشخص شدن،
کاربر از
طریق
گزینه
-Cدرخواست کرده است کهsudoتمام توصیفکنندههای فایل (file descriptors) با مقدار number یا بالاتر را ببندد. افزونه میتواند به صورت اختیاری این مقدار یا مقدار دیگری را در لیست command_info بازگرداند. - cmnd_chroot=string
- دایرکتوری
ریشه (به
chroot(2)
مراجعه
کنید) برای
اجرای
دستور در
آن،
همانطور
که توسط
کاربر از
طریق
گزینه
-Rمشخص شده است. افزونه ممکن است توانایی کاربر برای تعیین یک دایرکتوری ریشه جدید را نادیده گرفته یا محدود کند. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است. - cmnd_cwd=string
- دایرکتوری
کاری برای
اجرای
دستور در
آن،
همانطور
که توسط
کاربر از
طریق
گزینه
-Dمشخص شده است. افزونه ممکن است توانایی کاربر برای تعیین یک دایرکتوری کاری جدید را نادیده گرفته یا محدود کند. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است. - debug_flags=string
- نام مسیر
فایل
اشکالزدایی
به همراه
یک فاصله و
یک لیست
جداشده با
کاما از
فلگهای
اشکالزدایی
که متناظر
با مدخل
Debug
افزونه در
sudo.conf(5)
است (در
صورت
وجود).
فلگها
دقیقاً
همانطور
که در
sudo.conf(5)
آمدهاند
به افزونه
ارسال
میشوند.
نحو مورد
استفاده
توسط
sudoو افزونهsudoersبه صورت subsystem@priority است، اما یک افزونه تا زمانی که از کاما (‘,’) استفاده نکند، در انتخاب قالبی متفاوت آزاد است. پیش ازsudoنسخه 1.8.12، راهی برای تعیین debug_flags مخصوص افزونه وجود نداشت، بنابراین مقدار آن همیشه همان مقداری بود که توسط بخش فرانتاندsudoاستفاده میشد و شامل نام مسیر نبود، بلکه تنها خود فلگها را دربرداشت. از نسخه ۱.۷ رابط افزونه،sudoتنها در صورتی debug_flags را ارسال میکند که sudo.conf(5) شامل یک مدخل Debug مخصوص آن افزونه باشد. - ignore_ticket=bool
- اگر کاربر
گزینه
-kرا همراه با یک دستور مشخص کرده باشد، روی true تنظیم میشود و نشان میدهد که کاربر مایل است از هرگونه اعتبارنامههای احراز هویت ذخیرهشده (cached) چشمپوشی کند. implied_shell به true. این بهsudoبدون هیچ آرگومانی امکان میدهد تا به روشی مشابه با su(1) مورد استفاده قرار گیرد. اگر افزونه از این شیوه استفاده پشتیبانی نکند، میتواند مقدار -۲ را از تابعcheck_policy() برگرداند، که باعث میشودsudoپیام نحوه استفاده را چاپ کرده و خارج شود. - implied_shell=bool
- اگر کاربر
برنامهای
را در خط
فرمان
مشخص
نکند،
sudoمسیر پوسته کاربر را به افزونه ارسال کرده و implied_shell را تنظیم میکند. - intercept_ptrace=bool
- مشخص میکند که آیا سیستم از حالت رهگیری (intercept mode) با استفاده از ptrace(2) پشتیبانی میکند یا خیر. این مورد در حال حاضر تنها برای سیستمهای لینوکسی صادق است که از فیلتر کردن seccomp(2) و عمل “trap” پشتیبانی میکنند. سایر سیستمها برای پیادهسازی رهگیری از یک شیء اشتراکی پویا استفاده خواهند کرد. تنها از نسخه ۱.۱۹ رابط API به بعد در دسترس است.
- intercept_setid=bool
- مشخص میکند که آیا سیستم از اجرای باینریهای set-user-ID و set-group-ID در حالت رهگیری پشتیبانی میکند یا خیر. این مورد در حال حاضر تنها برای سیستمهای لینوکسی صادق است که از فیلتر کردن seccomp(2) و عمل “trap” پشتیبانی میکنند. در سیستمهایی که برای پیادهسازی رهگیری از یک شیء اشتراکی پویا استفاده میکنند، پیونددهنده پویا (ld.so یا معادل آن) پیشبارگذاری اشیاء اشتراکی را هنگام اجرای باینریهای set-user-ID یا set-group-ID غیرفعال میکند. این امر حالت رهگیری را برای آن برنامه و هر برنامه دیگری که توسط آن اجرا میشود غیرفعال خواهد کرد. افزونه سیاستگذاری میتواند برای جلوگیری از این وضعیت، از اجرای یک باینری set-user-ID یا set-group-ID در حالت رهگیری خودداری کند. تنها از نسخه ۱.۱۹ رابط API به بعد در دسترس است.
- login_class=string
- کلاس ورود
BSD جهت
استفاده
هنگام
تنظیم
محدودیتهای
منابع و
مقدار nice،
در صورت
مشخص شدن
با گزینه
-c. - login_shell=bool
- اگر کاربر
گزینه
-iرا مشخص کرده باشد روی true تنظیم میشود و نشان میدهد که کاربر مایل است یک پوسته ورود (login shell) را اجرا کند. - max_groups=int
- حداکثر تعداد گروههایی که یک کاربر میتواند عضو آنها باشد. این مقدار تنها در صورتی وجود خواهد داشت که تنظیم متناظر در sudo.conf(5) موجود باشد.
- network_addrs=list
- یک لیست
جداشده با
فاصله از
آدرسهای
شبکه IP و
ماسکهای
شبکه به
فرم “addr/netmask ،”
به عنوان
مثال،
“192.168.1.2/255.255.255.0”.
جفتهای
آدرس و
ماسک شبکه
بسته به
پشتیبانی
سیستمعامل
میتوانند
IPv4 یا IPv6
باشند. اگر
آدرس شامل
دونقطه
(‘
:’) باشد، یک آدرس IPv6 است، در غیر این صورت IPv4 است. - noninteractive=bool
- اگر کاربر
گزینه
-nرا مشخص کرده باشد روی true تنظیم میشود و نشان میدهد کهsudoباید در حالت غیرتعاملی عمل کند. اگر تعامل با کاربر مورد نیاز باشد، افزونه ممکن است فرمانی را که در حالت غیرتعاملی اجرا شده است رد کند. - plugin_dir=string
- پوشه
پیشفرض
افزونهها
که توسط
بخش
فرانتاند
sudoاستفاده میشود. این دایرکتوری پیشفرضی است که در زمان کامپایل تنظیم شده و ممکن است با دایرکتوری که افزونه در حال اجرا از آن بارگذاری شده است، مطابقت نداشته باشد. این مقدار ممکن است توسط افزونه برای یافتن فایلهای پشتیبان استفاده شود. - plugin_path=string
- نام مسیر
افزونهای
که توسط
فرانتاند
sudoبارگذاری شده است. این نام مسیر به صورت کامل (fully-qualified) خواهد بود، مگر اینکه افزونه به صورت ایستا درونsudoکامپایل شده باشد. - preserve_environment=bool
- اگر کاربر
گزینه
-Eرا مشخص کرده باشد روی true تنظیم میشود و نشان میدهد که کاربر مایل به حفظ محیط متغیرها است. - preserve_groups=bool
- اگر کاربر
گزینه
-Pرا مشخص کرده باشد روی true تنظیم میشود و نشان میدهد که کاربر مایل است بردار گروهها را به جای تنظیم بر اساس کاربر هدف (runas user)، حفظ کند. - progname=string
- نام دستوری که sudo تحت عنوان آن اجرا شده است، معمولاً “sudo” یا “sudoedit”.
- prompt=string
- اعلانی که
هنگام
درخواست
گذرواژه
باید
استفاده
شود، در
صورت مشخص
شدن از
طریق
گزینه
-p. - remote_host=string
- نام
میزبان
راه دور
برای
اجرای
دستور روی
آن، در
صورت مشخص
شدن از
طریق
گزینه
-h. پشتیبانی از اجرای دستور روی میزبان راه دور به گونهای طراحی شده که از طریق یک برنامه کمکی که به جای دستور تعیینشده توسط کاربر اجرا میشود، پیادهسازی گردد. فرانتاندsudoتنها قادر به اجرای دستورات روی میزبان محلی است. تنها از نسخه ۱.۴ رابط API به بعد در دسترس است. - run_shell=bool
- اگر کاربر
گزینه
-sرا مشخص کرده باشد روی true تنظیم میشود و نشان میدهد که کاربر مایل به اجرای یک پوسته است. - runas_group=string
- نام گروه
یا شناسه
گروه (group-ID)
برای
اجرای
دستور با
آن، در
صورت مشخص
شدن از
طریق
گزینه
-g. - runas_user=string
- نام کاربر
یا شناسه
کاربر (user-ID)
برای
اجرای
دستور با
آن، در
صورت مشخص
شدن از
طریق
گزینه
-u. - selinux_role=string
- نقش SELinux مورد
استفاده
هنگام
اجرای
دستور، در
صورت مشخص
شدن با
گزینه
-r. - selinux_type=string
- نوع SELinux مورد
استفاده
هنگام
اجرای
دستور، در
صورت مشخص
شدن با
گزینه
-t. - set_home=bool
- اگر کاربر
گزینه
-Hرا مشخص کرده باشد روی true تنظیم میشود. در صورت true بودن، متغیر محیطیHOMEروی پوشه خانگی کاربر هدف تنظیم میشود. - sudoedit=bool
- هنگامی که
گزینه
-eمشخص شده باشد یا دستور به صورتsudoeditفراخوانی گردد، روی true تنظیم میشود. افزونه باید یک ویرایشگر را در argv در تابعcheck_policy() جایگزین کند، یا در صورتی که افزونه از sudoedit پشتیبانی نکند مقدار -۲ را همراه با خطای نحوه استفاده بازگرداند. برای اطلاعات بیشتر، بخشcheck_policy() را ببینید. - timeout=string
- مهلت
زمانی (timeout)
دستور که
توسط
کاربر از
طریق
گزینه
-Tمشخص شده است. همه افزونهها از مهلت زمانی دستور پشتیبانی نمیکنند و توانایی کاربر در تعیین مهلت زمانی ممکن است توسط سیاستگذاری محدود شده باشد. قالب رشته مهلت زمانی وابسته به هر افزونه است. - update_ticket=bool
- اگر کاربر
گزینه
-Nرا مشخص کرده باشد روی false تنظیم میشود و نشان میدهد که کاربر میخواهد از بهروزرسانی هرگونه اعتبارنامه احراز هویت ذخیرهشده خودداری کند. تنها از نسخه ۱.۲۰ رابط API به بعد در دسترس است.
ممکن است تنظیمات بیشتری در آینده اضافه شوند، بنابراین افزونه باید تنظیماتی را که نمیشناسد، بدون خطا نادیده بگیرد.
- user_info
- برداری از
اطلاعات
مربوط به
کاربری که
دستور را
اجرا
میکند در
قالب
رشتههای
“name=value” است.
این بردار
با یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه user_info ، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تقسیم کند، زیرا فیلد name هرگز شامل مساوی نخواهد بود، اما مقدار value ممکن است شامل آن باشد.مقادیر زیر ممکن است توسط
sudoتنظیم شوند:- cols=int
- تعداد ستونهایی که ترمینال کاربر پشتیبانی میکند. اگر هیچ دستگاه ترمینالی در دسترس نباشد، مقدار پیشفرض ۸۰ استفاده میشود.
- cwd=string
- دایرکتوری کاری فعلی کاربر.
- egid=gid_t
- شناسه
گروه موثر
(effective group-ID)
کاربری که
sudoرا فراخوانی کرده است. - euid=uid_t
- شناسه
کاربر
موثر (effective user-ID)
کاربری که
sudoرا فراخوانی کرده است. - gid=gid_t
- شناسه
گروه
واقعی (real group-ID)
کاربری که
sudoرا فراخوانی کرده است. - groups=list
- لیست گروههای تکمیلی کاربر در قالب رشتهای از شناسههای گروه جداشده با کاما.
- host=string
- نام میزبان (hostname) ماشین محلی که توسط فراخوانی سیستمی gethostname(2) بازگردانده شده است.
- lines=int
- تعداد خطوطی که ترمینال کاربر پشتیبانی میکند. اگر هیچ دستگاه ترمینالی در دسترس نباشد، مقدار پیشفرض ۲۴ استفاده میشود.
- pgid=int
- شناسه
گروه
فرآیندی
که فرآیند
در حال
اجرای
sudoعضو آن است. تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. - pid=int
- شناسه
فرآیند (PID)
مربوط به
فرآیند در
حال اجرای
sudo. تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. - ppid=int
- شناسه
فرآیند
والد (PPID)
فرآیند در
حال اجرای
sudo. تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. - rlimit_as=soft,hard
- حداکثر اندازهای که فضای آدرسدهی فرآیند میتواند رشد کند (به بایت)، در صورت پشتیبانی سیستمعامل. حدود نرم (soft) و سخت (hard) با کاما از هم جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_core=soft,hard
- بزرگترین اندازه فایل core dump که میتواند ایجاد شود (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_cpu=soft,hard
- حداکثر زمان پردازنده (CPU time) که فرآیند میتواند استفاده کند (به ثانیه). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_data=soft,hard
- حداکثر اندازه بخش داده (data segment) برای فرآیند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_fsize=soft,hard
- بزرگترین اندازه فایلی که فرآیند میتواند ایجاد کند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_locks=soft,hard
- حداکثر تعداد قفلهایی که فرآیند میتواند ایجاد کند، در صورت پشتیبانی سیستمعامل. حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_memlock=soft,hard
- حداکثر اندازهای که فرآیند میتواند در حافظه قفل کند (به بایت)، در صورت پشتیبانی سیستمعامل. حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_nofile=soft,hard
- حداکثر تعداد فایلهایی که فرآیند میتواند همزمان باز نگه دارد. حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_nproc=soft,hard
- حداکثر تعداد فرآیندهایی که کاربر میتواند به طور همزمان اجرا کند. حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_rss=soft,hard
- حداکثر اندازهای که مقدار فضای مقیم (resident set size) فرآیند میتواند رشد کند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- rlimit_stack=soft,hard
- حداکثر اندازهای که پشته (stack) فرآیند میتواند رشد کند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا شدهاند. مقدار “infinity” نشان میدهد که هیچ محدودیتی وجود ندارد. تنها از نسخه ۱.۱۶ رابط API به بعد در دسترس است.
- sid=int
- شناسه
نشست (session ID)
مربوط به
فرآیند در
حال اجرای
sudoیا ۰ اگرsudoبخشی از یک نشست کنترل کار (job control) سازگار با POSIX نباشد. تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. - tcpgid=int
- شناسه
گروه
فرآیند
پیشزمینه
مرتبط با
دستگاه
ترمینال
متصل به
فرآیند
sudoیا ۰ اگر هیچ ترمینالی موجود نباشد. تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. - tty=string
- مسیر به دستگاه ترمینال کاربر، در صورت وجود. این مدخل تنها در صورتی موجود است که کاربر دستگاه ترمینال مرتبط با نشست داشته باشد.
- ttydev=dev_t
- شماره دستگاه ترمینال کاربر، در صورت وجود، قالببندیشده به عنوان یک مقدار long long. این مدخل تنها در صورتی وجود دارد که کاربر دستگاه ترمینال مرتبط با این نشست داشته باشد. تنها از نسخه ۱.۲۲ رابط API به بعد در دسترس است.
- uid=uid_t
- شناسه
کاربر
واقعی (real user-ID)
کاربری که
sudoرا فراخوانی میکند. - umask=octal
- ماسک ایجاد فایل کاربر فراخوان. تنها از نسخه ۱.۱۰ رابط API به بعد در دسترس است.
- user=string
- نام
کاربری که
sudoرا فراخوانی میکند.
- user_env
- محیط
متغیرهای
کاربر در
قالب یک
بردار
خاتمهیافته
با
NULLاز رشتههای “name=value” است.هنگام تجزیه user_env ، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تقسیم کند، زیرا فیلد name هرگز شامل مساوی نخواهد بود، اما مقدار value ممکن است شامل آن باشد. - plugin_options
- هر
رشتهای
(غیر از
کامنتها)
که
بلافاصله
پس از مسیر
افزونه
قرار
گیرد، به
عنوان
آرگومان
به افزونه
ارسال
میشود.
این
آرگومانها
با فاصله
جدا
میشوند و
در قالب یک
آرایه از
رشتهها
که با
NULLخاتمه یافته است به افزونه ارسال میگردند. اگر هیچ آرگومانی مشخص نشده باشد، plugin_options یک اشارهگرNULLخواهد بود.پارامتر plugin_options تنها از نسخه ۱.۲ رابط API به بعد در دسترس است. یک افزونه باید پیش از استفاده از plugin_options ، نسخه API مشخصشده توسط فرانتاند
sudoرا بررسی کند. کوتاهی در این کار ممکن است منجر به کرش و فروپاشی برنامه شود. - errstr
- اگر تابع
open() مقداری غیر از ۱ برگرداند، افزونه ممکن است پیامی را برای توصیف شکست یا خطا در errstr ذخیره کند. سپس فرانتاندsudoاین مقدار را به تمام افزونههای بازرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود معتبر بماند.پارامتر errstr تنها از نسخه ۱.۱۵ رابط API به بعد در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API مشخصشده توسط فرانتاند
sudoرا بررسی کند. کوتاهی در این کار ممکن است منجر به کرش و فروپاشی برنامه شود.
- close
-
void (*close)(int exit_status, int error);
تابع
close() هنگامی فراخوانی میشود که کارsudoبه پایان رسیده باشد، اندکی پیش از خروج آن. از نسخه ۱.۱۵ رابط API به بعد،close() صرفنظر از اینکه دستوری واقعاً اجرا شده باشد یا خیر فراخوانی میشود. این امر به افزونهها امکان میدهد تا حتی در صورت اجرا نشدن یک دستور نیز عملیات پاکسازی را انجام دهند. تنها بر اساس آرگومانهای ارائهشده به تابعclose() نمیتوان تشخیص داد که آیا دستوری اجرا شده است یا خیر. برای تعیین اینکه آیا یک دستور واقعاً اجرا شده است یا نه، افزونه باید پیگیری کند که آیا تابعcheck_policy() با موفقیت بازگشته است یا خیر.آرگومانهای تابع به شرح زیر هستند:
- exit_status
- وضعیت خروج دستور، همانطور که توسط فراخوانی سیستمی wait(2) برگردانده شده است، یا صفر در صورتی که هیچ دستوری اجرا نشده باشد. اگر مقدار error غیر صفر باشد، مقدار exit_status تعریفنشده است.
- error
- اگر دستور
نتواند
اجرا شود،
این فیلد
روی مقدار
errno تنظیم
میشود که
توسط
فراخوانی
سیستمی
execve(2)
ایجاد شده
است.
افزونه
مسئول
نمایش
اطلاعات
خطا از
طریق تابع
conversation() یاsudo_plugin_printf() است. اگر دستور با موفقیت اجرا شده باشد، مقدار error صفر است.
اگر هیچ تابع
close() تعریف نشده باشد، هیچ افزونه ثبت ورودی/خروجی (I/O logging) بارگذاری نشده باشد، و هیچیک از گزینههای timeout یا use_pty در لیست command_info تنظیم نشده باشند، فرانتاندsudoممکن است به جای اجرای دستور به عنوان یک فرآیند فرزند، آن را مستقیماً اجرا کند. - show_version
-
int (*show_version)(int verbose);
تابع
show_version() توسطsudoهنگامی فراخوانی میشود که کاربر گزینه-Vرا مشخص کرده باشد. افزونه میتواند اطلاعات نسخه خود را از طریق تابعconversation() یاsudo_plugin_printf() با استفاده ازSUDO_CONV_INFO_MSGبه کاربر نمایش دهد. اگر کاربر اطلاعات دقیق نسخه را درخواست کند، فلگ verbose غیر صفر خواهد بود.در صورت موفقیت ۱، در صورت شکست ۰، در صورت خطای عمومی -۱، و در صورت خطای نحوه استفاده -۲ برمیگرداند، اگرچه مقدار بازگشتی در حال حاضر نادیده گرفته میشود.
- check_policy
-
int (*check_policy)(int argc, char * const argv[], char *env_add[], char **command_info[], char **argv_out[], char **user_env_out[], const char **errstr);تابع
check_policy() توسطsudoفراخوانی میشود تا مشخص گردد آیا کاربر مجاز به اجرای دستورات مشخصشده هست یا خیر.اگر گزینه sudoedit در آرایه settings که به تابع
open() ارسال شده است فعال شده باشد، کاربر حالت sudoedit را درخواست کرده است. sudoedit مکانیزمی برای ویرایش یک یا چند فایل است که در آن ویرایشگر به جای دسترسیهای ارتقاءیافته، با اعتبارنامههای خود کاربر اجرا میشود.sudoاین کار را با ایجاد نسخههای موقت قابل نوشتن توسط کاربر از فایلهای مورد نظر و سپس رونویسی نسخههای اصلی با این نسخههای موقت پس از اتمام ویرایش انجام میدهد. اگر افزونه از sudoedit پشتیبانی کند، باید sudoedit=true را در لیست command_info تنظیم نماید. افزونه مسئول انتخاب ویرایشگر مورد استفاده است، که میتواند از یک متغیر در محیط کاربر مانندEDITORانتخاب شده و باید در argv_out ذخیره شود (متغیرهای محیطی ممکن است شامل گزینههای خط فرمان باشند). فایلهایی که باید ویرایش شوند باید از argv به argv_out کپی شوند و با یک عنصر ‘--’ از ویرایشگر و آرگومانهای آن جدا گردند. این ‘--’ پیش از اجرای ویرایشگر توسطsudoحذف خواهد شد. افزونه همچنین میتواند sudoedit_nfiles را روی تعداد فایلهای مورد ویرایش در لیست command_info تنظیم کند؛ این مقدار تنها از نسخه ۱.۲۱ رابط API به بعد توسط فرانتاندsudoاستفاده خواهد شد.تابع
check_policy() در صورتی که دستور مجاز باشد مقدار ۱، در صورت عدم مجاز بودن ۰، در صورت خطای عمومی -۱، و در صورت خطای نحوه استفاده یا در صورتی که sudoedit مشخص شده باشد ولی توسط افزونه پشتیبانی نشود، مقدار -۲ را بازمیگرداند. در حالت آخر،sudoپیش از خروج، پیام نحوه استفاده را چاپ خواهد کرد. اگر خطایی رخ دهد، افزونه میتواند به صورت اختیاری تابعconversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری را به کاربر نمایش دهد.آرگومانهای تابع به شرح زیر هستند:
- argc
- تعداد
عناصر
موجود در
argv ، بدون
احتساب
اشارهگر
پایانی
NULL. - argv
- بردار
آرگومان
که دستوری
را که
کاربر
مایل به
اجرای آن
است توصیف
میکند،
به همان
شکلی که به
فراخوانی
سیستمی
execve(2)
ارسال
میشود.
این بردار
با یک
اشارهگر
NULLخاتمه مییابد. - env_add
- متغیرهای
محیطی
اضافی که
توسط
کاربر در
خط فرمان
مشخص
شدهاند،
در قالب یک
بردار
خاتمهیافته
با
NULLاز رشتههای “name=value”. افزونه در صورتی که یک یا چند متغیر مجاز به تنظیم نباشند میتواند دستور را رد کند، یا ممکن است چنین متغیرهایی را بدون اعلام خطا نادیده بگیرد.هنگام تجزیه env_add ، افزونه باید بر اساس اولین علامت مساوی (‘
=’) تقسیم کند، زیرا فیلد name هرگز شامل مساوی نخواهد بود، اما مقدار value ممکن است شامل آن باشد. - command_info
- اطلاعات
مربوط به
دستوری که
اجرا
میشود در
قالب
رشتههای
“name=value”. این
مقادیر
توسط
sudoبرای تنظیم محیط اجرا هنگام اجرای یک دستور استفاده میشوند. این افزونه مسئول ایجاد و پر کردن بردار است، که باید با یک اشارهگرNULLخاتمه یابد. مقادیر زیر توسطsudoشناسایی میشوند:- apparmor_profile=string
- پروفایل AppArmor برای انتقال به آن هنگام اجرای دستور. تنها از نسخه 1.19 به بعد API در دسترس است.
- chroot=string
- دایرکتوری ریشه برای استفاده هنگام اجرای دستور.
- closefrom=number
- در صورت
مشخص شدن،
sudoتمام توصیفکنندههای فایل با مقداری برابر با number یا بالاتر را خواهد بست. - command=string
- مسیر کامل دستوری که باید اجرا شود.
- cwd=string
- دایرکتوری
کاری فعلی
برای
تغییر به
آن هنگام
اجرای
دستور. اگر
sudoنتواند به دایرکتوری کاری جدید تغییر مسیر دهد، دستور اجرا نخواهد شد مگر اینکه cwd_optional نیز تنظیم شده باشد (به زیر نگاه کنید). - cwd_optional=bool
- در صورت
تنظیم،
sudoناتوانی در تغییر به دایرکتوری کاری جدید را به عنوان خطای غیرمهلک در نظر میگیرد. این تنظیم هیچ تاثیری ندارد مگر اینکه cwd نیز تنظیم شده باشد. - exec_background=bool
- بهطور
پیشفرض،
sudoتا زمانی که خودش در پیشزمینه در حال اجرا است، دستور را به عنوان فرایند پیشزمینه اجرا میکند. هنگامی که exec_background فعال باشد و دستور در یک شبهترمینال اجرا شود (به دلیل ثبت لاگ I/O یا تنظیم use_pty )، دستور به عنوان یک فرایند پسزمینه اجرا خواهد شد. تلاشها برای خواندن از ترمینال کنترلی (یا تغییر تنظیمات ترمینال) منجر به تعلیق دستور با سیگنالSIGTTIN(یا در مورد تنظیمات ترمینال،SIGTTOU) خواهد شد. اگر این اتفاق زمانی بیفتد کهsudoیک فرایند پیشزمینه است، ترمینال کنترلی به دستور واگذار شده و بدون نیاز به دخالت کاربر، در پیشزمینه از سر گرفته میشود. مزیت اجرای اولیه دستور در پسزمینه این است کهsudoنیازی به خواندن از ترمینال ندارد مگر اینکه دستور صریحاً آن را درخواست کند. در غیر این صورت، هر ورودی ترمینال باید به دستور تحویل داده شود، چه به آن نیاز داشته باشد و چه نداشته باشد (هسته سیستمعامل ترمینالها را بافر میکند، بنابراین نمیتوان تشخیص داد که آیا دستور واقعاً ورودی را میخواهد یا خیر). این با رفتار تاریخیsudoیا وضعیتی که دستور در شبهترمینال اجرا نمیشود تفاوت دارد.برای اینکه این سازوکار بدون مشکل کار کند، سیستمعامل باید از راهاندازی مجدد خودکار فراخوانهای سیستمی پشتیبانی کند. متاسفانه همه سیستمعاملها بهطور پیشفرض این کار را انجام نمیدهند، و حتی سیستمهایی که انجام میدهند نیز ممکن است اشکالاتی داشته باشند. برای مثال، macOS در راهاندازی مجدد فراخوانهای سیستمی
tcgetattr() وtcsetattr() ناموفق است (این یک باگ در macOS است). علاوه بر این، از آنجا که این رفتار به متوقف شدن دستور با سیگنالهایSIGTTINیاSIGTTOUوابسته است، برنامههایی که این سیگنالها را دریافت کرده و خود را با سیگنال دیگری (معمولاًSIGTOP) معلق میکنند، بهطور خودکار به پیشزمینه منتقل نخواهند شد. برخی از نسخههای دستور su(1) در لینوکس به این شکل رفتار میکنند. به همین دلیل، یک افزونه نباید exec_background را تنظیم کند مگر اینکه صریحاً توسط مدیر سیستم فعال شده باشد و باید راهی برای فعال یا غیرفعال کردن آن بر مبنای هر دستور وجود داشته باشد.این تنظیم هیچ تاثیری ندارد مگر اینکه ثبت لاگ I/O فعال باشد یا use_pty فعال شده باشد.
- execfd=number
- در صورت
مشخص شدن،
sudoاز فراخوان سیستمی fexecve(2) به جای execve(2) برای اجرای دستور استفاده خواهد کرد. مقدار مشخصشده number باید به یک توصیفکننده فایل باز ارجاع داشته باشد. - intercept=bool
- در صورت
تنظیم،
sudoتلاشها برای اجرای یک دستور بعدی را رهگیری کرده و با استفاده از تابعcheck_policy() افزونه خطمشی، یک بررسی خطمشی انجام میدهد تا مشخص کند که آیا اجرای دستور مجاز است یا خیر. از این سازوکار میتوان برای جلوگیری از گریز به پوسته در پلتفرمهای پشتیبانیشده استفاده کرد، اما دارای محدودیتهای متعددی است. برای جزئیات بیشتر به بخش Preventing shell escapes در sudoers(5) مراجعه کنید. تنها از نسخه 1.18 به بعد API در دسترس است. - intercept_verify=bool
- در صورت
تنظیم،
sudoتلاش خواهد کرد تا بررسی کند که دستوری که در حالت رهگیری اجرا میشود، نام مسیر، آرگومانهای خط فرمان و محیط مورد انتظار را دارد یا خیر. این تنظیم هیچ تاثیری ندارد مگر اینکه use_ptrace نیز فعال باشد. تنها از نسخه 1.20 به بعد API در دسترس است. - iolog_compress=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید دادههای لاگ را فشرده کنند، روی true تنظیم شود. این یک راهنمایی (hint) برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_group=string
- گروهی که مالک فایلها و دایرکتوریهای لاگ I/O تازه ایجادشده خواهد بود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_mode=octal
- حالت دسترسی فایل برای استفاده هنگام ایجاد فایلها و دایرکتوریهای لاگ I/O. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_user=string
- کاربری که مالک فایلها و دایرکتوریهای لاگ I/O تازه ایجادشده خواهد بود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_path=string
- مسیر کامل فایل یا دایرکتوریای که لاگ I/O در آن ذخیره میشود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد. اگر هیچ افزونه ثبت لاگ I/O بارگذاری نشده باشد، این تنظیم هیچ تاثیری ندارد.
- iolog_stdin=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید ورودی استاندارد را در صورتی که به یک دستگاه ترمینال متصل نیست ثبت کنند، روی true تنظیم شود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_stdout=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید خروجی استاندارد را در صورتی که به یک دستگاه ترمینال متصل نیست ثبت کنند، روی true تنظیم شود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_stderr=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید خطای استاندارد را در صورتی که به یک دستگاه ترمینال متصل نیست ثبت کنند، روی true تنظیم شود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_ttyin=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید تمام ورودیهای ترمینال را ثبت کنند، روی true تنظیم شود. این فقط شامل ورودی تایپشده توسط کاربر است و شامل ورودی از طریق لوله (pipe) یا تغییرمسیریافته از یک فایل نمیشود. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- iolog_ttyout=bool
- اگر افزونههای ثبت لاگ I/O (در صورت وجود) باید تمام خروجیهای ترمینال را ثبت کنند، روی true تنظیم شود. این فقط شامل خروجی نمایشیافته بر روی صفحه است، نه خروجی ارسالشده به لوله یا فایل. این یک راهنمایی برای افزونه ثبت لاگ I/O است که ممکن است آن را نادیده بگیرد.
- login_class=string
- کلاس ورود BSD برای استفاده هنگام تنظیم محدودیتهای منابع و مقدار nice (اختیاری). این گزینه فقط روی سیستمهایی تنظیم میشود که از کلاسهای ورود پشتیبانی میکنند.
- nice=int
- مقدار nice (اولویت) برای استفاده هنگام اجرای دستور. مقدار nice، در صورت مشخص شدن، اولویت مرتبط با login_class را در سیستمهای BSD نادیده میگیرد.
- log_subcmds=bool
- در صورت
تنظیم،
sudoتابعaccept() افزونه ممیزی را فراخوانی میکند تا هنگام اجرای یک دستور بعدی توسط دستور اصلی، در صورت پشتیبانی سیستم، آن را ثبت کند. اگر intercept نیز مشخص شده باشد، log_subcmds نادیده گرفته خواهد شد. برای اطلاعات بیشتر به بخش Preventing shell escapes در sudoers(5) مراجعه کنید. تنها از نسخه 1.18 به بعد API در دسترس است. - noexec=bool
- در صورت تنظیم، از اجرای سایر برنامهها توسط دستور جلوگیری میکند.
- preserve_fds=list
- فهرستی از توصیفکنندههای فایل که با کاما از یکدیگر جدا شدهاند و باید صرفنظر از مقدار تنظیم closefrom حفظ شوند. تنها از نسخه 1.5 به بعد API در دسترس است.
- preserve_groups=bool
- در صورت
تنظیم،
sudoبردار گروههای کاربر را به جای مقداردهی اولیه بر اساس runas_user حفظ خواهد کرد. - rlimit_as=soft,hard
- حداکثر اندازهای که فضای آدرس فرایند میتواند تا آن گسترش یابد (به بایت)، در صورت پشتیبانی سیستمعامل. حدود نرم (soft) و سخت (hard) با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_core=soft,hard
- بزرگترین اندازه فایل تخلیه حافظه (core dump) که ممکن است ایجاد شود (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_cpu=soft,hard
- حداکثر مدت زمان پردازنده که فرایند میتواند استفاده کند (به ثانیه). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_data=soft,hard
- حداکثر اندازه بخش داده برای فرایند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_fsize=soft,hard
- بزرگترین اندازه فایلی که فرایند میتواند ایجاد کند (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_locks=soft,hard
- حداکثر تعداد قفلهایی که فرایند میتواند برقرار کند، در صورت پشتیبانی سیستمعامل. حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_memlock=soft,hard
- حداکثر اندازهای که فرایند میتواند در حافظه قفل کند (به بایت)، در صورت پشتیبانی سیستمعامل. حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_nofile=soft,hard
- حداکثر تعداد فایلهایی که فرایند میتواند باز داشته باشد. حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_nproc=soft,hard
- حداکثر تعداد فرایندهایی که کاربر میتواند بهطور همزمان اجرا کند. حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_rss=soft,hard
- حداکثر اندازهای که اندازه مجموعه مقیم (resident set size) فرایند میتواند تا آن گسترش یابد (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- rlimit_stack=soft,hard
- حداکثر اندازهای که پشته فرایند میتواند تا آن گسترش یابد (به بایت). حدود نرم و سخت با کاما از یکدیگر جدا میشوند. اگر تنها یک مقدار مشخص شود، هر دو حد سخت و نرم روی آن تنظیم میشوند. مقدار “infinity” نشاندهنده عدم وجود محدودیت است. مقدار “user” باعث حفظ محدودیت منبع کاربر فراخواننده میشود. مقدار “default” باعث استفاده از محدودیت منبع پیشفرض کاربر هدف در سیستمهایی میشود که امکان پیکربندی محدودیتهای منبع به ازای هر کاربر را فراهم میکنند. تنها از نسخه 1.18 به بعد API در دسترس است.
- runas_egid=gid
- شناسه گروه مؤثر (effective group-ID) برای اجرای دستور با آن. در صورت عدم تعیین، مقدار runas_gid استفاده میشود.
- runas_euid=uid
- شناسه کاربر مؤثر (effective user-ID) برای اجرای دستور با آن. در صورت عدم تعیین، مقدار runas_uid استفاده میشود.
- runas_gid=gid
- شناسه گروه (group-ID) برای اجرای دستور با آن.
- runas_group=string
- نام گروهی
که دستور
با آن اجرا
خواهد شد،
در صورتی
که با گروه
پیشفرض
runas_user
متفاوت
باشد. این
مقدار
صرفاً
برای
مقاصد
ممیزی
ارائه شده
است؛
پیشخوان
sudoهنگام اجرای دستور از runas_egid و runas_gid استفاده میکند. - runas_groups=list
- بردار گروههای کمکی (supplementary group vector) برای استفاده در دستور به شکل فهرستی از شناسههای گروه جداشده با کاما. اگر preserve_groups تنظیم شده باشد، این گزینه نادیده گرفته میشود.
- runas_uid=uid
- شناسه کاربر (user-ID) برای اجرای دستور با آن.
- runas_user=string
- نام
کاربری که
دستور با
آن اجرا
خواهد شد،
که باید با
runas_euid (یا در
صورت عدم
تنظیم runas_euid
، با runas_uid )
مطابقت
داشته
باشد. این
مقدار
صرفاً
برای
مقاصد
ممیزی
ارائه شده
است؛
پیشخوان
sudoهنگام اجرای دستور از runas_euid و runas_uid استفاده میکند. - selinux_role=string
- نقش SELinux برای استفاده هنگام اجرای دستور.
- selinux_type=string
- نوع SELinux برای استفاده هنگام اجرای دستور.
- set_utmp=bool
- ایجاد یک ورودی utmp (یا utmpx) هنگام تخصیص یک شبهترمینال. بهطور پیشفرض، ورودی جدید یک کپی از ورودی utmp موجود کاربر (در صورت وجود) خواهد بود، همراه با بهروزرسانی فیلدهای tty، time، type و pid.
- sudoedit=bool
- روی true
تنظیم
میشود
هنگامی که
در حالت
sudoedit باشد.
این
افزونه
ممکن است
حالت sudoedit
را فعال
کند حتی
اگر
sudoبهعنوانsudoeditفراخوانی نشده باشد. این به افزونه اجازه میدهد تا جایگزینی دستور را انجام داده و در صورت تلاش کاربر برای اجرای یک ویرایشگر، حالت sudoedit را بهطور شفاف فعال سازد. - sudoedit_checkdir=bool
- برای
غیرفعال
کردن
بررسیهای
قابلیت
نوشتن در
دایرکتوری
در
sudoeditروی false تنظیم کنید. بهطور پیشفرض،sudoeditنسخه 1.8.16 و بالاتر، تمام بخشهای دایرکتوری در مسیر مورد ویرایش را از نظر قابلیت نوشتن توسط کاربر فراخواننده بررسی میکند. پیوندهای نمادین در دایرکتوریهای قابل نوشتن دنبال نخواهند شد وsudoeditاز ویرایش فایلی که در یک دایرکتوری قابل نوشتن قرار دارد خودداری میکند. این محدودیتها زمانی کهsudoeditتوسط root اجرا شود اعمال نمیگردند. گزینه sudoedit_checkdir میتواند روی false تنظیم شود تا این بررسی غیرفعال گردد. تنها از نسخه 1.8 به بعد API در دسترس است. - sudoedit_follow=bool
- روی true
تنظیم شود
تا به
sudoeditاجازه ویرایش فایلهایی که پیوند نمادین هستند داده شود. بهطور پیشفرض،sudoeditنسخه 1.8.15 و بالاتر از باز کردن یک پیوند نمادین خودداری میکند. گزینه sudoedit_follow میتواند برای بازگرداندن رفتار قدیمیتر و مجاز ساختنsudoeditبه باز کردن پیوندهای نمادین استفاده شود. تنها از نسخه 1.8 به بعد API در دسترس است. - sudoedit_nfiles=number
- تعداد
فایلهایی
که باید
توسط
کاربر
ویرایش
شوند. در
صورت
وجود، این
مقدار
توسط
پیشخوان
sudoاستفاده خواهد شد تا مشخص شود کدام عناصر بردار argv_out فایلهای مورد ویرایش هستند. عنصر ‘--’ باید بلافاصله پیش از اولین فایل مورد ویرایش قرار گیرد. اگر sudoedit_nfiles مشخص نشده باشد، پیشخوانsudoاز موقعیت عنصر ‘--’ برای تعیین محل شروع فهرست فایلها استفاده خواهد کرد. تنها از نسخه 1.21 به بعد API در دسترس است. - timeout=int
- مهلت زمانی دستور. اگر غیرصفر باشد، پس از انقضای مهلت زمانی دستور خاتمه داده خواهد شد (کشته میشود).
- umask=octal
- ماسک ایجاد فایل برای استفاده هنگام اجرای دستور. این مقدار ممکن است در برخی سیستمها توسط PAM یا login.conf نادیده گرفته شود، مگر اینکه گزینه umask_override نیز تنظیم شده باشد.
- umask_override=bool
- مقدار مشخصشده توسط گزینه umask را مجبور میکند تا هر umask تعیینشده توسط PAM یا login.conf را نادیده بگیرد.
- use_ptrace=bool
- در صورت
تنظیم،
sudoاز ptrace(2) برای پیادهسازی حالت رهگیری در صورت پشتیبانی سیستم استفاده خواهد کرد. این تنظیم هیچ تاثیری ندارد مگر اینکه intercept نیز تنظیم شده باشد. تنها از نسخه 1.19 به بعد API در دسترس است. - use_pty=bool
- صرفنظر
از اینکه
لاگگیری
I/O در حال
استفاده
باشد یا
خیر، یک
شبهترمینال
برای
اجرای
دستور در
آن تخصیص
میدهد.
بهطور
پیشفرض،
sudoتنها زمانی دستور را در یک شبهترمینال اجرا میکند که یک افزونه ثبت لاگ I/O بارگذاری شده باشد. - utmp_user=string
- نام
کاربری
برای
استفاده
هنگام
ساخت یک
ورودی utmp (یا
utmpx) جدید در
زمانی که
set_utmp
فعال است.
این گزینه
میتواند
برای
تنظیم
فیلد
کاربر در
ورودی utmp
روی
کاربری که
دستور با
آن اجرا
میشود به
جای کاربر
فراخواننده
استفاده
گردد. در
صورت عدم
تنظیم،
sudoورودی جدید را بر اساس ورودی موجود کاربر فراخواننده پایهگذاری خواهد کرد.
مقادیر پشتیبانینشده نادیده گرفته خواهند شد.
- argv_out
- بردار
آرگومانهای
خاتمهیافته
با
NULLبرای ارسال به فراخوان سیستمی execve(2) هنگام اجرای دستور. افزونه مسئول تخصیص حافظه و پر کردن این بردار است. - user_env_out
- بردار
محیطی
خاتمهیافته
با
NULLبرای استفاده هنگام اجرای دستور. افزونه مسئول تخصیص حافظه و پر کردن این بردار است. - errstr
- اگر تابع
check_policy() مقداری به جز 1 بازگرداند، افزونه میتواند پیامی حاوی شرح شکست یا خطا را در errstr ذخیره کند. سپس پیشخوانsudoاین مقدار را به تمام افزونههای ممیزی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود معتبر باقی بماند.پارامتر errstr تنها از نسخه 1.15 به بعد API در دسترس است. یک افزونه باید نسخه API مشخصشده توسط پیشخوان
sudoرا قبل از استفاده از errstr بررسی کند. عدم انجام این کار ممکن است منجر به کرش شود.
- list
-
int (*list)(int argc, char * const argv[], int verbose, const char *user, const char **errstr);فهرست کردن اختیارات موجود برای کاربر فراخواننده. در صورت موفقیت 1، در صورت شکست 0، و در صورت بروز خطا -1 بازمیگرداند. در صورت بروز خطا، افزونه میتواند به صورت اختیاری تابع
conversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری به کاربر ارائه دهد.اختیارات باید از طریق تابع
conversation() یاsudo_plugin_printf() با استفاده ازSUDO_CONV_INFO_MSGارائه شوند.آرگومانهای تابع به شرح زیر هستند:
- argc
- تعداد
عناصر
موجود در
argv ، بدون
احتساب
اشارهگر
پایانی
NULL. - argv
- اگر غیر از
NULLباشد، یک بردار آرگومان است که دستوری را که کاربر مایل است در برابر خطمشی بررسی کند توصیف مینماید، به همان صورتی که به فراخوان سیستمی execve(2) ارسال میشد. اگر دستور توسط خطمشی مجاز باشد، مسیر کامل دستور باید همراه با هرگونه آرگومان خط فرمان نمایش داده شود. - verbose
- فلگی که مشخص میکند فهرستبندی در حالت پرگو (verbose) انجام شود یا خیر.
- user
- نام یک
کاربر
دیگر برای
فهرست
کردن
اختیارات
او در
صورتی که
خطمشی
اجازه دهد.
اگر
NULLباشد، افزونه باید اختیارات کاربر فراخواننده را فهرست کند. - errstr
- اگر تابع
list() مقداری به جز 1 بازگرداند، افزونه میتواند پیامی حاوی شرح شکست یا خطا را در errstr ذخیره کند. سپس پیشخوانsudoاین مقدار را به تمام افزونههای ممیزی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود معتبر باقی بماند.پارامتر errstr تنها از نسخه 1.15 به بعد API در دسترس است. یک افزونه باید نسخه API مشخصشده توسط پیشخوان
sudoرا قبل از استفاده از errstr بررسی کند. عدم انجام این کار ممکن است منجر به کرش شود.
- validate
-
int (*validate)(const char **errstr);
تابع
validate() زمانی فراخوانی میشود کهsudoبا گزینه-vاجرا شده باشد. برای افزونههای خطمشی مانندsudoersکه گواهیهای احراز هویت را کش میکنند، این تابع گواهیها را اعتبارسنجی کرده و در کش قرار میدهد.اگر افزونه از کش کردن گواهیهای احراز هویت پشتیبانی نمیکند، تابع
validate() بایدNULLباشد.در صورت موفقیت 1، در صورت شکست 0، و در صورت بروز خطا -1 بازمیگرداند. در صورت بروز خطا، افزونه میتواند به صورت اختیاری تابع
conversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری به کاربر ارائه دهد.آرگومانهای تابع به شرح زیر هستند:
- errstr
- اگر تابع
validate() مقداری به جز 1 بازگرداند، افزونه میتواند پیامی حاوی شرح شکست یا خطا را در errstr ذخیره کند. سپس پیشخوانsudoاین مقدار را به تمام افزونههای ممیزی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود معتبر باقی بماند.پارامتر errstr تنها از نسخه 1.15 به بعد API در دسترس است. یک افزونه باید نسخه API مشخصشده توسط پیشخوان
sudoرا قبل از استفاده از errstr بررسی کند. عدم انجام این کار ممکن است منجر به کرش شود.
- invalidate
-
void (*invalidate)(int rmcred);
تابع
invalidate() زمانی فراخوانی میشود کهsudoبا گزینه-kیا-Kاجرا شده باشد. برای افزونههای خطمشی مانندsudoersکه گواهیهای احراز هویت را کش میکنند، این تابع گواهیها را باطل میسازد. اگر فلگ rmcred غیرصفر باشد، افزونه ممکن است گواهیها را به جای باطلسازیِ ساده حذف کند.اگر افزونه از کش کردن گواهیهای احراز هویت پشتیبانی نمیکند، تابع
invalidate() بایدNULLباشد. - init_session
-
int (*init_session)(struct passwd *pwd, char **user_env[], const char **errstr);تابع
init_session() قبل از اینکهsudoمحیط اجرا را برای دستور آماده کند فراخوانی میشود. این تابع در فرایند والدsudoقبل از هرگونه تغییر شناسه کاربر یا شناسه گروه اجرا میشود. از این تابع میتوان برای راهاندازی نشستهایی استفاده کرد که توسط command_info پشتیبانی نمیشوند، مانند باز کردن یک نشست PAM. از تابعclose() میتوان برای بستن نشستی که توسطinit_session() باز شده است استفاده کرد.در صورت موفقیت 1، در صورت شکست 0، و در صورت بروز خطا -1 بازمیگرداند. در صورت بروز خطا، افزونه میتواند به صورت اختیاری تابع
conversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری به کاربر ارائه دهد.آرگومانهای تابع به شرح زیر هستند:
- pwd
- اگر شناسه
کاربری که
دستور با
آن اجرا
میشود در
پایگاه
داده
گذرواژهها
پیدا شده
باشد، pwd
آن کاربر
را توصیف
خواهد
کرد، در
غیر این
صورت
NULLخواهد بود. - user_env_out
- بردار
محیطی
خاتمهیافته
با
NULLبرای استفاده هنگام اجرای دستور. این همان رشتهای است که از طریق پارامتر user_env_out افزونه خطمشی به پیشخوان بازگردانده میشود. اگر تابعinit_session() نیاز به اصلاح محیط کاربر داشته باشد، باید اشارهگر ذخیرهشده در user_env_out را بهروز کند. کاربرد مورد انتظار، ادغام محتویات محیط PAM (در صورت وجود) با محتویات user_env_out است. پارامتر user_env_out تنها از نسخه 1.2 به بعد API در دسترس است. یک افزونه باید نسخه API مشخصشده توسط پیشخوانsudoرا قبل از استفاده از user_env_out بررسی کند. عدم انجام این کار ممکن است منجر به کرش شود. - errstr
- اگر تابع
init_session() مقداری به جز 1 بازگرداند، افزونه میتواند پیامی حاوی شرح شکست یا خطا را در errstr ذخیره کند. سپس پیشخوانsudoاین مقدار را به تمام افزونههای ممیزی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود معتبر باقی بماند.پارامتر errstr تنها از نسخه 1.15 به بعد API در دسترس است. یک افزونه باید نسخه API مشخصشده توسط پیشخوان
sudoرا قبل از استفاده از errstr بررسی کند. عدم انجام این کار ممکن است منجر به کرش شود.
- register_hooks
-
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
تابع
register_hooks() توسط پیشخوان sudo برای ثبت هرگونه قلابی که افزونه نیاز دارد فراخوانی میشود. اگر افزونه از قلابها پشتیبانی نمیکند، register_hooks باید روی اشارهگرNULLتنظیم شود.آرگومان version نسخه API قلابهای پشتیبانیشده توسط پیشخوان
sudoرا توصیف میکند.تابع
register_hook() باید برای ثبت هر قلاب پشتیبانیشدهای که افزونه به آن نیاز دارد استفاده شود. این تابع در صورت موفقیت 0، در صورتی که نوع قلاب پشتیبانی نشود 1، و در صورتی که نسخه اصلی در struct sudo_hook با نسخه اصلی API قلابهای پیشخوان مطابقت نداشته باشد -1 بازمیگرداند.برای اطلاعات بیشتر درباره قلابها به بخش Hook function API در زیر مراجعه کنید.
تابع
register_hooks() تنها از نسخه 1.2 به بعد API در دسترس است. اگر پیشخوانsudoاز نسخه 1.2 یا بالاتر API پشتیبانی نکند،register_hooks() فراخوانی نخواهد شد. - deregister_hooks
-
void (*deregister_hooks)(int version, int (*deregister_hook)(struct sudo_hook *hook));
تابع
deregister_hooks() توسط پیشخوان sudo برای لغو ثبت هر قلابی که توسط افزونه ثبت شده است فراخوانی میشود. اگر افزونه از قلابها پشتیبانی نمیکند، deregister_hooks باید روی اشارهگرNULLتنظیم شود.آرگومان version نسخه API قلابهای پشتیبانیشده توسط پیشخوان
sudoرا توصیف میکند.تابع
deregister_hook() باید برای لغو ثبت هر قلابی که توسط تابعregister_hook() به کار گرفته شده بود استفاده شود. اگر افزونه تلاش کند قلابی را لغو ثبت کند که پیشخوان از آن پشتیبانی نمیکند،deregister_hook() یک خطا بازمیگرداند.برای اطلاعات بیشتر درباره قلابها به بخش Hook function API در زیر مراجعه کنید.
تابع
deregister_hooks() تنها از نسخه 1.2 به بعد API در دسترس است. اگر پیشخوانsudoاز نسخه 1.2 یا بالاتر API پشتیبانی نکند،deregister_hooks() فراخوانی نخواهد شد. - event_alloc
-
struct sudo_plugin_event * (*event_alloc)(void);
تابع
event_alloc() برای تخصیص یک struct sudo_plugin_event استفاده میشود که دسترسی به حلقه رویدادهای اصلیsudoرا فراهم میکند. برخلاف سایر فیلدها، اشارهگر event_alloc توسط پیشخوانsudoپر میشود، نه توسط افزونه.برای اطلاعات بیشتر درباره رویدادها به بخش Event API در زیر مراجعه کنید.
تابع
event_alloc() تنها از نسخه 1.15 به بعد API در دسترس است. اگر پیشخوانsudoاز نسخه 1.15 یا بالاتر API پشتیبانی نکند، event_alloc تنظیم نخواهد شد.
ماکروهای نسخه افزونه خطمشی (Policy Plugin Version Macros)
/* Plugin API version major/minor. */
#define SUDO_API_VERSION_MAJOR 1
#define SUDO_API_VERSION_MINOR 13
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
SUDO_API_VERSION_MINOR)
/* Getters and setters for API version */
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
} while(0)
#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \
*(vp) = (*(vp) & 0xffff0000) | (n); \
} while(0)
رابط افزونههای ورودی/خروجی (I/O plugin API)
struct io_plugin {
#define SUDO_IO_PLUGIN 2
unsigned int type; /* always SUDO_IO_PLUGIN */
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_plugin_printf, char * const settings[],
char * const user_info[], char * const command_info[],
int argc, char * const argv[], char * const user_env[],
char * const plugin_options[], const char **errstr);
void (*close)(int exit_status, int error); /* wait status or error */
int (*show_version)(int verbose);
int (*log_ttyin)(const char *buf, unsigned int len,
const char **errstr);
int (*log_ttyout)(const char *buf, unsigned int len,
const char **errstr);
int (*log_stdin)(const char *buf, unsigned int len,
const char **errstr);
int (*log_stdout)(const char *buf, unsigned int len,
const char **errstr);
int (*log_stderr)(const char *buf, unsigned int len,
const char **errstr);
void (*register_hooks)(int version,
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
int (*change_winsize)(unsigned int lines, unsigned int cols,
const char **errstr);
int (*log_suspend)(int signo, const char **errstr);
struct sudo_plugin_event * (*event_alloc)(void);
};
هنگامی که
یک افزونه
ورودی/خروجی
بارگذاری
میشود،
sudo دستور
را در یک
شبهترمینال
اجرا
میکند. این
امر ثبت
ورودی و
خروجی نشست
کاربر را
امکانپذیر
میسازد.
اگر هر یک از
ورودی
استاندارد،
خروجی
استاندارد
یا خطای
استاندارد
به یک tty
مربوط
نباشد،
sudo یک
لوله (pipe) باز
میکند تا
ورودی/خروجی
را پیش از
ارسال،
برای ثبت
دریافت
کند.
تابع
log_ttyin()
ورودی خام
کاربر را از
دستگاه
ترمینال
دریافت
میکند (این
شامل ورودی
حتی در زمان
غیرفعال
بودن
انعکاس (echo ،)
مانند
زمانی که یک
گذرواژه
خوانده
میشود،
نیز خواهد
بود). تابع
log_ttyout()
خروجی را از
شبهترمینال
دریافت
میکند که
برای
بازپخش
نشست کاربر
در آینده
مناسب است.
توابع
log_stdin(،)
log_stdout() و
log_stderr() تنها
در صورتی
فراخوانی
میشوند که
به ترتیب،
ورودی
استاندارد،
خروجی
استاندارد
یا خطای
استاندارد
به چیزی غیر
از یک tty
مربوط
باشند.
در صورتی
که قرار
نباشد هیچ
ثبتی انجام
شود، هر یک
از توابع
ثبت وقایع
میتوانند
روی
اشارهگر
NULL تنظیم
شوند. اگر
تابع open
مقدار 0
بازگرداند،
هیچ
ورودی/خروجیای
به افزونه
ارسال
نخواهد شد.
اگر یک تابع ثبت وقایع خطایی (-1) بازگرداند، دستور در حال اجرا پایان خواهد یافت و تمام توابع ثبت وقایع افزونه غیرفعال خواهند شد. سایر افزونههای ثبت وقایع ورودی/خروجی همچنان هرگونه ورودی یا خروجی باقیماندهای را که هنوز پردازش نشده است دریافت خواهند کرد.
اگر یک تابع ثبت وقایع ورودی، داده را با بازگرداندن 0 رد کند، دستور پایان خواهد یافت و داده به دستور منتقل نخواهد شد، هرچند همچنان به سایر افزونههای ثبت وقایع ورودی/خروجی ارسال میشود. اگر یک تابع ثبت وقایع خروجی، داده را با بازگرداندن 0 رد کند، دستور پایان خواهد یافت و داده در ترمینال نوشته نخواهد شد، هرچند همچنان به سایر افزونههای ثبت وقایع ورودی/خروجی ارسال میشود.
یک struct audit_plugin دارای فیلدهای زیر است:
- type
- فیلد type
همیشه باید
روی
SUDO_IO_PLUGINتنظیم شود. - version
- فیلد version
باید روی
SUDO_API_VERSIONتنظیم شود.این به
sudoامکان میدهد تا نسخه API که افزونه بر اساس آن ساخته شده است را تعیین کند. - open
-
int (*open)(unsigned int version, sudo_conv_t conversation, sudo_printf_t sudo_plugin_printf, char * const settings[], char * const user_info[], char * const command_info[], int argc, char * const argv[], char * const user_env[], char * const plugin_options[]);تابع
open() پیش از فراخوانی توابعlog_ttyin(،)log_ttyout(،)log_stdin(،)log_stdout(،)log_stderr(،)log_suspend(،)change_winsize() یاshow_version() اجرا میشود. این تابع تنها در صورتی فراخوانی میشود که نسخه درخواست شده باشد یا تابعcheck_policy() افزونه خطمشی با موفقیت بازگشته باشد. در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز خطای عمومی -1 و در صورت خطای نحوه استفاده -2 را برمیگرداند. در حالت اخیر،sudoپیش از خروج پیامی درباره نحوه استفاده چاپ خواهد کرد. اگر خطایی رخ دهد، افزونه میتواند به صورت اختیاری تابعconversation() یاsudo_plugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری به کاربر ارائه دهد.آرگومانهای تابع به شرح زیر هستند:
- version
- نسخه
ارائهشده
توسط
sudoبه افزونه امکان میدهد شماره نسخه اصلی و فرعی API افزونه پشتیبانیشده توسطsudoرا تعیین کند. - conversation
- اشارهگری
به تابع
conversation() که ممکن است توسط تابعFa(show_version) جهت نمایش اطلاعات نسخه استفاده شود (بهshow_version() در زیر مراجعه کنید). تابعconversation() همچنین ممکن است برای نمایش پیام خطای اضافی به کاربر استفاده شود. تابعconversation() در صورت موفقیت مقدار 0 و در صورت شکست -1 بازمیگرداند. - sudo_plugin_printf
- اشارهگری
به یک تابع
به سبک
printf()-style که ممکن است توسط تابعshow_version() جهت نمایش اطلاعات نسخه استفاده شود (به show_version در زیر مراجعه کنید). تابعsudo_plugin_printf() همچنین میتواند برای نمایش پیام خطای اضافی به کاربر استفاده شود. تابعsudo_plugin_printf() در صورت موفقیت تعداد نویسههای چاپشده و در صورت شکست -1 بازمیگرداند. - settings
- برداری از
تنظیمات
ارائهشده
توسط
کاربر
برای
sudoبه شکل رشتههای “name=value”. این بردار با اشارهگرNULLپایان مییابد. این تنظیمات مربوط به گزینههایی هستند که کاربر هنگام اجرایsudoمشخص کرده است. بنابراین، آنها تنها زمانی وجود خواهند داشت که گزینه متناظر در خط فرمان مشخص شده باشد.هنگام تجزیه settings ، افزونه باید بر اساس اولین علامت مساوی (‘
=’) تفکیک را انجام دهد، چرا که فیلد name هرگز خودش شامل علامت مساوی نخواهد بود، اما value ممکن است باشد.برای فهرستی از تمامی تنظیمات ممکن، بخش Policy plugin API را ببینید.
- user_info
- برداری از
اطلاعات
مربوط به
کاربری که
دستور را
اجرا
میکند به
شکل
رشتههای
“name=value”. این
بردار با
اشارهگر
NULLپایان مییابد.هنگام تجزیه user_info ، افزونه باید بر اساس اولین علامت مساوی (‘
=’) تفکیک را انجام دهد، چرا که فیلد name هرگز خودش شامل مساوی نخواهد بود، اما value ممکن است باشد.برای فهرستی از تمامی رشتههای ممکن، بخش Policy plugin API را ببینید.
- command_info
- برداری از
اطلاعات
توصیفکننده
دستور در
حال اجرا
به شکل
رشتههای
“name=value”. این
بردار با
اشارهگر
NULLپایان مییابد.هنگام تجزیه command_info ، افزونه باید بر اساس اولین علامت مساوی (‘
=’) تفکیک را انجام دهد، چرا که فیلد name هرگز خودش شامل مساوی نخواهد بود، اما value ممکن است باشد.برای فهرستی از تمامی رشتههای ممکن، بخش Policy plugin API را ببینید.
- argc
- تعداد
عناصر
موجود در
argv ، بدون
احتساب
اشارهگر
پایانی
NULL. این مقدار میتواند صفر باشد، مانند زمانی کهsudoبا گزینه-Vفراخوانی میشود. - argv
- در صورت
غیر
NULLبودن (non-NULL)،یک بردار آرگومان است که دستوری را که کاربر مایل به اجرای آن است توصیف میکند، به همان شکلی که به فراخوانی سیستمی execve(2) ارسال میگردد. - user_env
- محیط
کاربر به
شکل یک
بردار
پایانیافته
با
NULLاز رشتههای “name=value”.هنگام تجزیه user_env ، افزونه باید بر اساس اولین علامت مساوی (‘
=’) تفکیک را انجام دهد، چرا که فیلد name هرگز خودش شامل مساوی نخواهد بود، اما value ممکن است باشد. - plugin_options
- هر
رشتهای
(غیر از
کامنت)
بلافاصله
پس از مسیر
افزونه،
به عنوان
آرگومانهای
افزونه
تلقی
میشود.
این
آرگومانها
در مرزهای
فاصله
خالی
تفکیک شده
و در قالب
یک آرایه
از
رشتهها
که با
NULLخاتمه مییابد به افزونه ارسال میشوند. اگر هیچ آرگومانی مشخص نشده باشد، plugin_options اشارهگرNULLخواهد بود.پارامتر plugin_options تنها با شروع از نسخه 1.2 از API در دسترس است. یک افزونه باید پیش از استفاده از plugin_options ، نسخه API ارائهشده توسط بخش فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به از کار افتادن برنامه شود. - errstr
- اگر تابع
open() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API مشخصشده توسط بخش فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به از کار افتادن برنامه شود.
- close
-
void (*close)(int exit_status, int error);
تابع
close() زمانی که کارsudoپایان یابد، اندکی پیش از خروج فراخوانی میشود.آرگومانهای تابع به شرح زیر هستند:
- exit_status
- وضعیت خروج دستور، همانطور که توسط فراخوانی سیستمی wait(2) بازگردانده شده است، یا در صورتی که هیچ دستوری اجرا نشده باشد صفر است. اگر error غیر صفر باشد، مقدار exit_status تعریفنشده است.
- error
- اگر دستور نتواند اجرا شود، این مقدار روی مقدار errno تنظیمشده توسط فراخوانی سیستمی execve(2) تنظیم میشود. اگر دستور با موفقیت اجرا شده باشد، مقدار error صفر است.
- show_version
-
int (*show_version)(int verbose);
تابع
show_version() زمانی توسطsudoفراخوانی میشود که کاربر گزینه-Vرا مشخص کرده باشد. افزونه میتواند اطلاعات نسخه خود را از طریق تابعconversation() یاsudo_plugin_printf() با استفاده ازSUDO_CONV_INFO_MSGبه کاربر نمایش دهد. اگر کاربر اطلاعات دقیق نسخه را درخواست کند، پرچم verbose غیر صفر خواهد بود.در صورت موفقیت 1، در صورت شکست 0، در صورت بروز خطای عمومی -1، یا اگر خطای نحوه استفاده وجود داشته باشد -2 بازمیگرداند، هرچند مقدار بازگشتی در حال حاضر نادیده گرفته میشود.
- log_ttyin
-
int (*log_ttyin)(const char *buf, unsigned int len, const char **errstr);تابع
log_ttyin() هر زمان که دادهای از کاربر قابل خواندن باشد، اما پیش از انتقال آن به دستور در حال اجرا، فراخوانی میشود. این به افزونه امکان میدهد تا در صورت تمایل داده را رد کند (مثلاً اگر ورودی شامل محتوای ممنوعه باشد). اگر داده باید به دستور منتقل شود مقدار 1، اگر داده رد شود مقدار 0 (که دستور در حال اجرا را خاتمه میدهد)، یا در صورت بروز خطا مقدار -1 بازمیگرداند.آرگومانهای تابع به شرح زیر هستند:
- buf
- بافر حاوی ورودی کاربر.
- len
- طول buf به بایت.
- errstr
- اگر تابع
log_ttyin() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط بخش فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به از کار افتادن برنامه شود.
- log_ttyout
-
int (*log_ttyout)(const char *buf, unsigned int len, const char **errstr);تابع
log_ttyout() هر زمان که دادهای از دستور قابل خواندن باشد، اما پیش از نوشته شدن در ترمینال کاربر، فراخوانی میشود. این به افزونه اجازه میدهد تا در صورت تمایل داده را رد کند (مثلاً اگر خروجی شامل محتوای ممنوعه باشد). اگر داده باید به کاربر تحویل داده شود مقدار 1، اگر داده رد شود مقدار 0 (که دستور در حال اجرا را متوقف میکند)، یا در صورت بروز خطا مقدار -1 بازمیگرداند.آرگومانهای تابع به شرح زیر هستند:
- buf
- بافر حاوی خروجی دستور.
- len
- طول buf به بایت.
- errstr
- اگر تابع
log_ttyout() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود.
- log_stdin
-
int (*log_stdin)(const char *buf, unsigned int len, const char **errstr);تابع
log_stdin() تنها در صورتی استفاده میشود که ورودی استاندارد مربوط به یک دستگاه tty نباشد. این تابع هر زمان که دادهای از ورودی استاندارد قابل خواندن باشد، اما پیش از انتقال آن به دستور در حال اجرا فراخوانی میشود. این به افزونه امکان میدهد در صورت تمایل داده را رد کند (مثلاً اگر ورودی شامل محتوای ممنوعه باشد). اگر داده باید به دستور ارسال شود مقدار 1، اگر داده رد شود مقدار 0 (که دستور در حال اجرا را متوقف میکند)، یا در صورت بروز خطا مقدار -1 بازمیگرداند.آرگومانهای تابع به شرح زیر است:
- buf
- بافر حاوی ورودی کاربر.
- len
- طول buf به بایت.
- errstr
- اگر تابع
log_stdin() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود.
- log_stdout
-
int (*log_stdout)(const char *buf, unsigned int len, const char **errstr);تابع
log_stdout() تنها در صورتی استفاده میشود که خروجی استاندارد به یک دستگاه tty مربوط نباشد. این تابع هر زمان که دادهای از دستور قابل خواندن باشد، اما پیش از نوشته شدن در خروجی استاندارد، فراخوانی میشود. این به افزونه امکان میدهد تا در صورت تمایل داده را رد کند (مثلاً اگر خروجی شامل محتوای ممنوعه باشد). اگر داده باید به کاربر تحویل شود مقدار 1، اگر داده رد شود مقدار 0 (که دستور در حال اجرا را خاتمه میدهد)، یا در صورت بروز خطا مقدار -1 بازمیگرداند.آرگومانهای تابع به شرح زیر است:
- buf
- بافر حاوی خروجی دستور.
- len
- طول buf به بایت.
- errstr
- اگر تابع
log_stdout() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود.
- log_stderr
-
int (*log_stderr)(const char *buf, unsigned int len, const char **errstr);تابع
log_stderr() تنها در صورتی استفاده میشود که خطای استاندارد به یک دستگاه tty مربوط نباشد. این تابع هر زمان که دادهای از دستور قابل خواندن باشد، اما پیش از نوشته شدن در خطای استاندارد، فراخوانی میشود. این به افزونه امکان میدهد تا در صورت تمایل داده را رد کند (مثلاً اگر خروجی شامل محتوای ممنوعه باشد). اگر داده باید به کاربر تحویل شود مقدار 1، اگر داده رد شود مقدار 0 (که دستور در حال اجرا را متوقف میکند)، یا در صورت بروز خطا مقدار -1 بازمیگرداند.آرگومانهای تابع به شرح زیر است:
- buf
- بافر حاوی خروجی دستور.
- len
- طول buf به بایت.
- errstr
- اگر تابع
log_stderr() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود.
- register_hooks
- برای شرح
register_hooks() به بخش Policy plugin API مراجعه کنید. - deregister_hooks
- برای شرح
deregister_hooks() به بخش Policy plugin API مراجعه کنید. - change_winsize
-
int (*change_winsize)(unsigned int lines, unsigned int cols, const char **errstr);تابع
change_winsize() هر زمان که اندازه پنجره ترمینال از مقادیر اولیه مشخصشده در فهرست user_info تغییر کند، فراخوانی میشود. در صورت بروز خطا -1 بازمیگرداند که در این حالت تماس دیگری باchange_winsize() برقرار نخواهد شد،آرگومانهای تابع به شرح زیر هستند:
- lines
- تعداد خطوط (سطرها) در ترمینال تغییراندازهیافته.
- cols
- تعداد ستونها در ترمینال تغییراندازهیافته.
- errstr
- اگر تابع
change_winsize() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود.
- log_suspend
-
int (*log_suspend)(int signo, const char **errstr);
تابع
log_suspend() هر زمان که دستوری معلق شده یا ازسرگرفته شود فراخوانی میشود. ثبت این اطلاعات، صرفنظر کردن از بازه زمانی تعلیق بودن دستور در زمان بازپخش یک نشست را امکانپذیر میسازد. در صورت بروز خطا -1 بازمیگرداند که در این حالت تماس دیگری باlog_suspend() برقرار نخواهد شد،آرگومانهای تابع به شرح زیر هستند:
- signo
- سیگنالی
که باعث
معلق شدن
دستور شده
است، یا
SIGCONTدر صورتی که اجرای دستور ازسرگرفته شده باشد. - errstr
- اگر تابع
log_suspend() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر بماند.پارامتر errstr تنها با شروع از نسخه 1.15 از API در دسترس است. یک افزونه باید پیش از استفاده از errstr ، نسخه API ارائهشده توسط فرانتاند
sudoرا بررسی کند. عدم انجام این کار ممکن است منجر به خرابی برنامه شود. - event_alloc
-
struct sudo_plugin_event * (*event_alloc)(void);
تابع
event_alloc() برای تخصیص دادن یک struct sudo_plugin_event استفاده میشود که دسترسی به حلقه رویداد اصلیsudoرا فراهم میکند. برخلاف سایر فیلدها، اشارهگرevent_alloc() توسط بخش فرانتاندsudoپر میشود، نه توسط افزونه.برای اطلاعات بیشتر درباره رویدادها، بخش Event API در زیر را ببینید.
تابع
event_alloc() تنها با شروع از نسخه 1.15 از API در دسترس است. اگر فرانتاندsudoاز نسخه 1.15 یا بالاتر API پشتیبانی نکند،event_alloc() تنظیم نخواهد شد.
ماکروهای نسخه افزونه ورودی/خروجی (I/O Plugin Version Macros)
مشابه موارد بخش Policy plugin API.
رابط افزونههای حسابرسی (Audit plugin API)
/* Audit plugin close function status types. */
#define SUDO_PLUGIN_NO_STATUS 0
#define SUDO_PLUGIN_WAIT_STATUS 1
#define SUDO_PLUGIN_EXEC_ERROR 2
#define SUDO_PLUGIN_SUDO_ERROR 3
#define SUDO_AUDIT_PLUGIN 3
struct audit_plugin {
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_plugin_printf, char * const settings[],
char * const user_info[], int submit_optind,
char * const submit_argv[], char * const submit_envp[],
char * const plugin_options[], const char **errstr);
void (*close)(int status_type, int status);
int (*accept)(const char *plugin_name,
unsigned int plugin_type, char * const command_info[],
char * const run_argv[], char * const run_envp[],
const char **errstr);
int (*reject)(const char *plugin_name, unsigned int plugin_type,
const char *audit_msg, char * const command_info[],
const char **errstr);
int (*error)(const char *plugin_name, unsigned int plugin_type,
const char *audit_msg, char * const command_info[],
const char **errstr);
int (*show_version)(int verbose);
void (*register_hooks)(int version,
int (*register_hook)(struct sudo_hook *hook));
void (*deregister_hooks)(int version,
int (*deregister_hook)(struct sudo_hook *hook));
struct sudo_plugin_event * (*event_alloc)(void);
}
یک افزونه
حسابرسی
میتواند
برای ثبت
تلاشهای
موفق و
ناموفق جهت
اجرای sudo
مستقل از
خطمشی یا
هر یک از
افزونههای
I/O استفاده
شود.
میتوان
چندین
افزونه
حسابرسی را
در sudo.conf(5)
مشخص کرد.
یک struct audit_plugin دارای فیلدهای زیر است:
- type
- فیلد type
باید همیشه
روی
SUDO_AUDIT_PLUGINتنظیم شود. - version
- فیلد version
باید روی
SUDO_API_VERSIONتنظیم شود.این به
sudoامکان میدهد تا نسخه API که افزونه بر اساس آن ساخته شده است را تعیین کند. - open
-
int (*open)(unsigned int version, sudo_conv_t conversation, sudo_printf_t sudo_plugin_printf, char * const settings[], char * const user_info[], int submit_optind, char * const submit_argv[], char * const submit_envp[], char * const plugin_options[], const char **errstr);تابع
open() حسابرسی، پیش از هر تابع API افزونه دیگرsudoاجرا میشود. این کار امکان حسابرسی خرابیها در سایر افزونهها را ممکن میسازد. این تابع در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز یک خطای عمومی -1، یا در صورت بروز خطای نحوه استفاده مقدار -2 را برمیگرداند. در حالت اخیر،sudoپیش از خروج پیامی درباره نحوه استفاده چاپ خواهد کرد. در صورت بروز خطا، افزونه میتواند به صورت اختیاری تابعconversation() یاplugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای اضافی را به کاربر نمایش دهد.آرگومانهای تابع به شرح زیر هستند:
- version
- نسخه
ارسالشده
توسط
sudoبه افزونه امکان میدهد تا شماره نسخه اصلی و فرعی API افزونه پشتیبانیشده توسطsudoرا تعیین کند. - conversation
- اشارهگری
به تابع
conversation() که ممکن است توسط تابعshow_version() برای نمایش اطلاعات نسخه استفاده شود (بهshow_version() در زیر مراجعه کنید). همچنین تابعconversation() میتواند برای نمایش پیام خطای اضافی به کاربر استفاده شود. تابعconversation() در صورت موفقیت مقدار 0 و در صورت شکست مقدار -1 را برمیگرداند. - plugin_printf
- اشارهگری
به تابعی
به سبک
printf() که ممکن است توسط تابعshow_version() برای نمایش اطلاعات نسخه استفاده شود (بهshow_version() در زیر مراجعه کنید). همچنین تابعplugin_printf() میتواند برای نمایش پیام خطای اضافی به کاربر استفاده شود. تابعplugin_printf() در صورت موفقیت تعداد کاراکترهای چاپشده و در صورت شکست مقدار -1 را برمیگرداند. - settings
- برداری از
تنظیمات
ارائهشده
توسط
کاربر
برای
sudoدر قالب رشتههای “name=value”. این بردار با یک اشارهگرNULLخاتمه مییابد. این تنظیمات متناظر با گزینههایی هستند که کاربر هنگام اجرایsudoمشخص کرده است. به این ترتیب، آنها تنها زمانی وجود خواهند داشت که گزینه متناظر در خط فرمان مشخص شده باشد.هنگام تجزیه کردن settings، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد.برای فهرستی از تمام تنظیمات ممکن، به بخش Policy plugin API مراجعه کنید.
- user_info
- برداری از
اطلاعات
درباره
کاربر
اجراکننده
دستور در
قالب
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه کردن user_info، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد.برای فهرستی از تمام رشتههای ممکن، به بخش Policy plugin API مراجعه کنید.
- submit_optind
- اندیس
درون submit_argv
که متناظر
با اولین
ورودی است
که یک
گزینه خط
فرمان
نیست. اگر
submit_argv تنها
شامل
گزینهها
باشد، که
ممکن است
در مورد
گزینههای
-lیا-vرخ دهد، submit_argv[submit_optind] به اشارهگر NULL ارزیابی میشود. - submit_argv
- بردار
آرگومانی
که
sudoبا آن فراخوانی شده بود، شامل تمام گزینههای خط فرمان. از آرگومان submit_optind میتوان برای تعیین انتهای گزینههای خط فرمان استفاده کرد. - submit_envp
- محیط
کاربر
فراخواننده
در قالب
برداری از
رشتههای
“name=value” که با
NULLخاتمه مییابد.هنگام تجزیه کردن submit_envp، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد. - plugin_options
- هر رشته
(غیر از
کامنت) که
بلافاصله
پس از مسیر
افزونه
قرار گیرد
به عنوان
آرگومانهای
افزونه در
نظر گرفته
میشود.
این
آرگومانها
بر اساس
مرز
فاصلههای
خالی
تفکیک شده
و در قالب
آرایهای
از
رشتهها
با
خاتمهدهنده
NULLبه افزونه ارسال میشوند. اگر هیچ آرگومانی مشخص نشده باشد، plugin_options برابر با اشارهگرNULLخواهد بود. - errstr
- اگر تابع
open() مقداری غیر از 1 برگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا را در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به تمام افزونههای حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود، معتبر باقی بماند.
- close
-
void (*close)(int status_type, int status);
تابع
close() زمانی که کارsudoتمام میشود، اندکی پیش از خروج آن فراخوانی میگردد.آرگومانهای تابع به شرح زیر هستند:
- status_type
- نوع
وضعیتی که
ارسال
میشود.
یکی از
مقادیر
SUDO_PLUGIN_NO_STATUS ،SUDO_PLUGIN_WAIT_STATUS ،SUDO_PLUGIN_EXEC_ERRORیاSUDO_PLUGIN_SUDO_ERROR. - status
- بسته به
مقدار status_type
، این
مقدار یا
نادیده
گرفته
میشود،
یا وضعیت
خروج
دستور
برگشتی
توسط
فراخوانی
سیستمی
wait(2) ،
یا مقدار
errno
تنظیمشده
توسط
فراخوانی
سیستمی
execve(2) ،
یا مقدار
errno ناشی
از بروز
خطا در
فرانتاند
sudoاست.
- accept
-
int (*accept)(const char *plugin_name, unsigned int plugin_type, char * const command_info[], char * const run_argv[], char * const run_envp[], const char **errstr);تابع
accept() زمانی فراخوانی میشود که یک دستور یا کنش توسط یک افزونه خطمشی یا تأیید پذیرفته شود. آرگومانهای تابع به شرح زیر هستند:- plugin_name
- نام
افزونهای
که دستور
را
پذیرفته
است یا “sudo”
برای
فرانتاند
sudo. - plugin_type
- نوع
افزونهای
که دستور
را
پذیرفته
است، که در
حال حاضر
یکی از
مقادیر
SUDO_POLICY_PLUGIN ،SUDO_POLICY_APPROVALیاSUDO_FRONT_ENDاست. تابعaccept() چندین بار فراخوانی میشود – یک بار به ازای هر افزونه خطمشی یا تأیید که موفق شود و یک بار برای فرانتاند sudo. هنگامی که به نمایندگی از فرانتاند sudo فراخوانی شود، command_info ممکن است شامل اطلاعاتی از یک افزونه ثبت وقایع I/O نیز باشد.معمولاً یک افزونه حسابرسی یا علاقهمند به وضعیت پذیرش از سوی فرانتاند
sudoاست یا از سوی افزونههای مختلف خطمشی و تأیید، اما نه هر دوی آنها. این امکان وجود دارد که افزونه خطمشی دستوری را بپذیرد که بعداً توسط یک افزونه تأیید رد شود، که در این صورت هر دو تابعaccept() وreject() افزونه حسابرسی فراخوانی خواهند شد. - command_info
- برداری
اختیاری
از
اطلاعات
توصیفکننده
دستور در
حال اجرا
در قالب
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه کردن command_info، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد.برای فهرستی از تمام رشتههای ممکن، به بخش Policy plugin API مراجعه کنید.
- run_argv
- یک بردار
آرگومان
خاتمهیافته
با
NULLکه دستوری را توصیف میکند که قرار است اجرا شود، در همان قالبی که به فراخوانی سیستمی execve(2) ارسال میگردد. - run_envp
- محیطی که
دستور با
آن اجرا
خواهد شد
در قالب
برداری از
رشتههای
“name=value” که با
NULLخاتمه مییابد.هنگام تجزیه کردن run_envp، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد. - errstr
- اگر تابع
accept() مقداری غیر از 1 برگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا را در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به تمام افزونههای حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود، معتبر باقی بماند.
- reject
-
int (*reject)(const char *plugin_name, unsigned int plugin_type, const char *audit_msg, char * const command_info[], const char **errstr);تابع
reject() زمانی فراخوانی میشود که یک دستور یا کنش توسط یک افزونه رد شود. آرگومانهای تابع به شرح زیر هستند:- plugin_name
- نام افزونهای که دستور را رد کرده است.
- plugin_type
- نوع
افزونهای
که دستور
را رد کرده
است، که در
حال حاضر
یکی از
مقادیر
SUDO_POLICY_PLUGIN ،SUDO_APPROVAL_PLUGINیاSUDO_IO_PLUGINاست.برخلاف تابع
accept()، تابعreject() به نمایندگی از فرانتاندsudoفراخوانی نمیشود. - audit_msg
- رشتهای
اختیاری
در توصیف
دلیل رد
شدن دستور
توسط
افزونه.
اگر
افزونه
دلیلی
ارائه
نداده
باشد،
audit_msg
برابر با
اشارهگر
NULLخواهد بود. - command_info
- برداری
اختیاری
از
اطلاعات
توصیفکننده
دستور در
حال اجرا
در قالب
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه کردن command_info، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد.برای فهرستی از تمام رشتههای ممکن، به بخش Policy plugin API مراجعه کنید.
- errstr
- اگر تابع
reject() مقداری غیر از 1 برگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا را در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به تمام افزونههای حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود، معتبر باقی بماند.
- error
-
int (*error)(const char *plugin_name, unsigned int plugin_type, const char *audit_msg, char * const command_info[], const char **errstr);تابع
error() زمانی فراخوانی میشود که یک افزونه یا فرانتاندsudoخطایی را برگرداند. آرگومانهای تابع به شرح زیر هستند:- plugin_name
- نام
افزونهای
که خطا را
ایجاد
کرده است
یا “sudo” برای
فرانتاند
sudo. - plugin_type
- نوع
افزونهای
که خطا را
ایجاد
کرده است،
یا
SUDO_FRONT_ENDبرای فرانتاندsudo. - audit_msg
- رشتهای
اختیاری
در توصیف
خطای
افزونه.
اگر
افزونه
توضیحی
ارائه
نداده
باشد،
audit_msg
برابر با
اشارهگر
NULLخواهد بود. - command_info
- برداری
اختیاری
از
اطلاعات
توصیفکننده
دستور در
حال اجرا
در قالب
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه کردن command_info، افزونه باید آن را بر اساس اولین علامت مساوی (‘
=’) تفکیک کند، زیرا خود فیلد name هرگز شامل مساوی نخواهد بود، اما value ممکن است شامل آن باشد.برای فهرستی از تمام رشتههای ممکن، به بخش Policy plugin API مراجعه کنید.
- errstr
- اگر تابع
error() مقداری غیر از 1 برگرداند، افزونه میتواند پیامی در توصیف شکست یا خطا را در errstr ذخیره کند. سپس بخش فرانتاندsudoاین مقدار را به تمام افزونههای حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمانی که تابعclose() افزونه فراخوانی شود، معتبر باقی بماند.
- show_version
-
int (*show_version)(int verbose);
تابع
show_version() توسطsudoزمانی فراخوانی میشود که کاربر گزینه-Vرا مشخص کند. افزونه میتواند اطلاعات نسخه خود را از طریق تابعconversation() یاplugin_printf() با استفاده ازSUDO_CONV_INFO_MSGبه کاربر نمایش دهد. اگر کاربر اطلاعات نسخه همراه با جزئیات را درخواست کند، فلگ verbose تنظیم خواهد شد.در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز یک خطای عمومی -1، یا در صورت بروز خطای نحوه استفاده مقدار -2 را برمیگرداند، اگرچه مقدار بازگشتی در حال حاضر نادیده گرفته میشود.
- register_hooks
- برای
توضیحات
مربوط به
register_hooks() به بخش Policy plugin API مراجعه کنید. - deregister_hooks
- برای
توضیحات
مربوط به
deregister_hooks() به بخش Policy plugin API مراجعه کنید. - event_alloc
-
struct sudo_plugin_event * (*event_alloc)(void);
تابع
event_alloc() برای تخصیص یک struct sudo_plugin_event استفاده میشود که امکان دسترسی به حلقه رویداد اصلیsudoرا فراهم میکند. برخلاف سایر فیلدها، اشارهگر event_alloc توسط فرانتاندsudoپر میشود، نه توسط افزونه.برای کسب اطلاعات بیشتر درباره رویدادها، به بخش Event API در زیر مراجعه کنید.
تابع
event_alloc() تنها از نسخه API 1.17 به بعد در دسترس است. اگر فرانتاندsudoاز نسخه API 1.17 یا بالاتر پشتیبانی نکند،event_alloc() تنظیم نخواهد شد.
رابط افزونههای تأیید (Approval plugin API)
struct approval_plugin {
#define SUDO_APPROVAL_PLUGIN 4
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
unsigned int version; /* always SUDO_API_VERSION */
int (*open)(unsigned int version, sudo_conv_t conversation,
sudo_printf_t sudo_plugin_printf, char * const settings[],
char * const user_info[], int submit_optind,
char * const submit_argv[], char * const submit_envp[],
char * const plugin_options[], const char **errstr);
void (*close)(void);
int (*check)(char * const command_info[], char * const run_argv[],
char * const run_envp[], const char **errstr);
int (*show_version)(int verbose);
};
یک
افزونه
تأیید
میتواند
برای اعمال
محدودیتهای
اضافی پس از
پذیرفته
شدن دستور
توسط
افزونه
خطمشی به
کار رود.
برخلاف
سایر انواع
افزونهها،
این افزونه
تا زمان
تکمیل
دستور باز
نمیماند.
افزونه پیش
از
فراخوانی
check()
یا show_version()
باز میشود
و اندکی پس
از آن بسته
میشود
(توابع
افزونه
حسابرسی
باید پیش از
بسته شدن
افزونه
فراخوانی
شوند).
میتوان
چندین
افزونه
تأیید را در
sudo.conf(5)
مشخص کرد.
ساختار struct approval_plugin دارای فیلدهای زیر است:
- type
- فیلد type
باید همیشه
روی
SUDO_APPROVAL_PLUGINتنظیم شود. - version
- فیلد version
باید روی
SUDO_API_VERSIONتنظیم شود.این به
sudoامکان میدهد نسخه API که افزونه بر اساس آن ساخته شده است را تشخیص دهد. - open
-
int (*open)(unsigned int version, sudo_conv_t conversation, sudo_printf_t sudo_plugin_printf, char * const settings[], char * const user_info[], int submit_optind, char * const submit_argv[], char * const submit_envp[], char * const plugin_options[], const char **errstr);تابع
open() تأیید بلافاصله پیش از فراخوانی توابعcheck() یاshow_version() افزونه اجرا میشود. این تابع تنها در صورتی فراخوانی میشود که نسخه درخواست شده باشد یا اینکه تابعcheck_policy() افزونه خطمشی با موفقیت بازگشته باشد. این تابع در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز خطای عمومی مقدار -1 یا در صورت خطای نحوه استفاده مقدار -2 را بازمیگرداند. در حالت آخر،sudoپیش از خروج یک پیام نحوه استفاده را چاپ خواهد کرد. اگر خطایی رخ دهد، افزونه میتواند به صورت اختیاری تابعconversation() یاplugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری را به کاربر نمایش دهد.آرگومانهای تابع به شرح زیر هستند:
- version
- نسخه
ارسالشده
توسط
sudoبه افزونه امکان میدهد شماره نسخه اصلی (major) و فرعی (minor) رابط API افزونه را که توسطsudoپشتیبانی میشود، تشخیص دهد. - conversation
- اشارهگری
به تابع
conversation() که میتواند توسط افزونه برای تعامل با کاربر استفاده شود (برای جزئیات به Conversation API مراجعه کنید). در صورت موفقیت 0 و در صورت شکست -1 را بازمیگرداند. - plugin_printf
- اشارهگری
به یک تابع
به سبک
printf() که میتواند برای نمایش پیامهای اطلاعاتی یا خطا استفاده شود (برای جزئیات به Conversation API مراجعه کنید). در صورت موفقیت تعداد نویسههای چاپشده و در صورت شکست -1 را بازمیگرداند. - settings
- برداری از
تنظیمات
ارائهشده
توسط
کاربر
برای
sudoبه شکل رشتههای “name=value”. این بردار با یک اشارهگرNULLخاتمه مییابد. این تنظیمات با گزینههایی مطابقت دارند که کاربر هنگام اجرایsudoمشخص کرده است. به این ترتیب، آنها تنها زمانی وجود خواهند داشت که گزینه متناظر در خط فرمان مشخص شده باشد.هنگام تجزیه settings ، افزونه باید رشته را بر اساس اولین علامت مساوی (‘
=’) جدا کند، زیرا خود فیلد name هرگز شامل علامت مساوی نخواهد بود اما value ممکن است باشد.برای فهرستی از تمام تنظیمات ممکن به بخش Policy plugin API مراجعه کنید.
- user_info
- برداری از
اطلاعات
مربوط به
کاربری که
دستور را
اجرا
میکند به
شکل
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه user_info ، افزونه باید رشته را بر اساس اولین علامت مساوی (‘
=’) جدا کند، زیرا خود فیلد name هرگز شامل علامت مساوی نخواهد بود اما value ممکن است باشد.برای فهرستی از تمام رشتههای ممکن به بخش Policy plugin API مراجعه کنید.
- submit_optind
- اندیس در
submit_argv که به
اولین
مدخلی
مربوط
میشود که
یک گزینه
خط فرمان
نیست. اگر
submit_argv فقط
شامل
گزینهها
باشد، که
ممکن است
در مورد
گزینههای
-lیا-vصادق باشد، submit_argv[submit_optind] به اشارهگر NULL ارزیابی میشود. - submit_argv
- بردار
آرگومانی
که
sudoبا آن فراخوانی شده است، شامل تمامی گزینههای خط فرمان. آرگومان submit_optind میتواند برای تعیین پایان گزینههای خط فرمان استفاده شود. - submit_envp
- محیط
کاربری
فراخواننده
به صورت یک
بردار
خاتمهیافته
با
NULLاز رشتههای “name=value”.هنگام تجزیه submit_envp ، افزونه باید رشته را بر اساس اولین علامت مساوی (‘
=’) جدا کند، زیرا خود فیلد name هرگز شامل علامت مساوی نخواهد بود اما value ممکن است باشد. - plugin_options
- هر رشته
(غیر کامنت)
بلافاصله
پس از مسیر
افزونه به
عنوان
آرگومانهای
افزونه در
نظر گرفته
میشود.
این
آرگومانها
در مرزهای
فاصله
خالی (whitespace) جدا
شده و در
قالب یک
آرایه از
رشتههای
خاتمهیافته
با
NULLبه افزونه ارسال میشوند. اگر هیچ آرگومانی مشخص نشده باشد، plugin_options اشارهگرNULLخواهد بود. - errstr
- اگر تابع
open() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی را در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش جلویی (front-end)sudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر باقی بماند.
- close
-
void (*close)(void);
تابع
close() پس از فراخوانی توابعcheck() یاshow_version() افزونه تأیید، فراخوانی میشود. این تابع هیچ آرگومانی دریافت نمیکند. تابعclose() معمولاً برای پاکسازیهای خاص افزونه، مانند آزادسازی اشیاء حافظه تخصیصیافته توسط افزونه، استفاده میشود. اگر افزونه نیازی به پاکسازی نداشته باشد،close() میتواند روی اشارهگرNULLتنظیم شود. - check
-
int (*check)(char * const command_info[], char * const run_argv[], char * const run_envp[], const char **errstr);تابع
check() تأیید پس از تابعcheck_policy() افزونه خطمشی و پیش از هر افزونه ثبت وقایع I/O اجرا میشود. اگر چندین افزونه تأیید بارگذاری شده باشند، همه آنها باید موفقیتآمیز باشند تا اجرای دستور مجاز شود. این تابع در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز خطای عمومی مقدار -1 یا در صورت خطای نحوه استفاده مقدار -2 را بازمیگرداند. در حالت آخر،sudoپیش از خروج یک پیام نحوه استفاده را چاپ خواهد کرد. اگر خطایی رخ دهد، افزونه میتواند به صورت اختیاری تابعconversation() یاplugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری را به کاربر ارائه دهد.آرگومانهای تابع به شرح زیر هستند:
- command_info
- برداری از
اطلاعات
توصیفکننده
دستور در
حال اجرا
به شکل
رشتههای
“name=value”. این
بردار با
یک
اشارهگر
NULLخاتمه مییابد.هنگام تجزیه command_info ، افزونه باید رشته را بر اساس اولین علامت مساوی (‘
=’) جدا کند، زیرا خود فیلد name هرگز شامل علامت مساوی نخواهد بود اما value ممکن است باشد.برای فهرستی از تمام رشتههای ممکن به بخش Policy plugin API مراجعه کنید.
- run_argv
- یک بردار
آرگومان
خاتمهیافته
با
NULLکه دستوری را توصیف میکند که اجرا خواهد شد، به همان شکلی که به فراخوانی سیستمی execve(2) ارسال میشود. - run_envp
- محیطی که
دستور با
آن اجرا
خواهد شد
به شکل یک
بردار
خاتمهیافته
با
NULLاز رشتههای “name=value”.هنگام تجزیه run_envp ، افزونه باید رشته را بر اساس اولین علامت مساوی (‘
=’) جدا کند، زیرا خود فیلد name هرگز شامل علامت مساوی نخواهد بود اما value ممکن است باشد. - errstr
- اگر تابع
open() مقداری غیر از 1 بازگرداند، افزونه میتواند پیامی را در توصیف شکست یا خطا در errstr ذخیره کند. سپس بخش جلوییsudoاین مقدار را به هر افزونه حسابرسی ثبتشده ارسال خواهد کرد. رشته ذخیرهشده در errstr باید تا زمان فراخوانی تابعclose() افزونه معتبر باقی بماند.
- show_version
-
int (*show_version)(int verbose);
تابع
show_version() توسطsudoهنگامی که کاربر گزینه-Vرا مشخص کند فراخوانی میشود. افزونه میتواند اطلاعات نسخه خود را از طریق تابعconversation() یاplugin_printf() با استفاده ازSUDO_CONV_INFO_MSGبه کاربر نمایش دهد. اگر کاربر اطلاعات تفصیلی نسخه را درخواست کند، فلگ verbose تنظیم خواهد شد.در صورت موفقیت مقدار 1، در صورت شکست 0، در صورت بروز خطای عمومی مقدار -1 یا در صورت خطای نحوه استفاده مقدار -2 را بازمیگرداند، اگرچه مقدار بازگشتی در حال حاضر نادیده گرفته میشود.
کنترلکنندههای سیگنال (Signal handlers)
بخش جلویی
(front-end) sudo
کنترلکنندههای
سیگنال
پیشفرض را
برای به دام
انداختن
سیگنالهای
متداول در
حین اجرای
توابع
افزونه نصب
میکند.
سیگنالهای
زیر پیش از
اجرای
دستور به
طور
پیشفرض به
دام
انداخته
میشوند:
اگر پیش
از اجرای
دستور یک
سیگنال
کشنده (fatal signal)
دریافت
شود، sudo
تابع
close()
افزونه را
با وضعیت
خروج 128 به
اضافه
مقدار
سیگنال
دریافتشده
فراخوانی
میکند. این
امر برای
افزونههایی
که چنین
اطلاعاتی
را در تابع
close() خود
ثبت
میکنند،
امکان ثبت
یکدست
وقایع
دستوراتی
که با
سیگنال
خاتمه
یافتهاند
را فراهم
میسازد. یک
استثنا در
این مورد
SIGPIPE است که
تا زمان
اجرای
دستور
نادیده
گرفته
میشود.
یک افزونه میتواند به طور موقت کنترلکنندههای سیگنال خود را نصب کند اما باید پیش از بازگشت تابع افزونه، کنترلکننده اصلی را بازیابی نماید.
رابط توابع هوک (Hook function API)
با شروع از
نسخه 1.2 رابط API
افزونه،
امکان نصب
هوکها
(قلابها)
برای توابع
خاصی که
توسط بخش
جلویی sudo
فراخوانی
میشوند
وجود دارد.
در حال
حاضر، تنها
هوکهای
پشتیبانیشده
مربوط به
مدیریت
متغیرهای
محیطی
هستند.
هوکها
میتوانند
برای
رهگیری
تلاشها به
منظور
دریافت،
تنظیم یا
حذف
متغیرهای
محیطی
استفاده
شوند تا این
تغییرات در
نسخه محیطی
که برای
اجرای یک
دستور به
کار میرود
منعکس شوند.
نسخههای
آتی API از
قلاب کردن
عملکردهای
داخلی بخش
جلویی sudo
نیز
پشتیبانی
خواهند
کرد.
ساختار هوک (Hook structure)
هوکها در
sudo توسط
ساختار زیر
توصیف
میشوند:
typedef int (*sudo_hook_fn_t)();
struct sudo_hook {
unsigned int hook_version;
unsigned int hook_type;
sudo_hook_fn_t hook_fn;
void *closure;
};
یک struct sudo_hook دارای فیلدهای زیر است:
- hook_version
- فیلد hook_version
باید روی
SUDO_HOOK_VERSIONتنظیم شود. - hook_type
- فیلد hook_type
میتواند
یکی از
انواع هوک
پشتیبانیشده
زیر باشد:
SUDO_HOOK_SETENV- تابع
setenv(3)
کتابخانه C.
هر هوک
ثبتشده
پیش از
پیادهسازی
کتابخانه C
اجرا
خواهد شد.
فیلد hook_fn
باید
تابعی
باشد که با
تعاریف typedef
زیر
مطابقت
داشته
باشد:
typedef int (*sudo_hook_fn_setenv_t)(const char *name, const char *value, int overwrite, void *closure);
اگر هوک ثبتشده با typedef مطابقت نداشته باشد، نتایج نامشخص خواهد بود.
SUDO_HOOK_UNSETENV- تابع
unsetenv(3)
کتابخانه C.
هر هوک
ثبتشده
پیش از
پیادهسازی
کتابخانه C
اجرا
خواهد شد.
فیلد hook_fn
باید
تابعی
باشد که با
تعاریف typedef
زیر
مطابقت
داشته
باشد:
typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, void *closure);
SUDO_HOOK_GETENV- تابع
getenv(3)
کتابخانه C.
هر هوک
ثبتشده
پیش از
پیادهسازی
کتابخانه C
اجرا
خواهد شد.
فیلد hook_fn
باید
تابعی
باشد که با
تعاریف typedef
زیر
مطابقت
داشته
باشد:
typedef int (*sudo_hook_fn_getenv_t)(const char *name, char **value, void *closure);
اگر هوک ثبتشده با typedef مطابقت نداشته باشد، نتایج نامشخص خواهد بود.
SUDO_HOOK_PUTENV- تابع
putenv(3)
کتابخانه C.
هر هوک
ثبتشده
پیش از
پیادهسازی
کتابخانه C
اجرا
خواهد شد.
فیلد hook_fn
باید
تابعی
باشد که با
تعاریف typedef
زیر
مطابقت
داشته
باشد:
typedef int (*sudo_hook_fn_putenv_t)(char *string, void *closure);
اگر هوک ثبتشده با typedef مطابقت نداشته باشد، نتایج نامشخص خواهد بود.
- hook_fn
-
sudo_hook_fn_t hook_fn;
فیلد hook_fn باید روی پیادهسازی هوک افزونه تنظیم شود. آرگومانهای واقعی تابع بسته به hook_type متفاوت خواهند بود (به hook_type در بالا مراجعه کنید). در تمام موارد، فیلد closure از struct sudo_hook به عنوان آخرین پارامتر تابع ارسال میشود. این میتواند برای ارسال دادههای دلخواه به پیادهسازی هوک افزونه استفاده شود.
مقدار بازگشتی تابع میتواند یکی از موارد زیر باشد:
SUDO_HOOK_RET_ERROR- تابع هوک با خطا مواجه شد.
SUDO_HOOK_RET_NEXT- هوک بدون
خطا تکمیل
شد، به هوک
بعدی
بروید
(شامل
پیادهسازی
سیستم در
صورت
امکان). به
عنوان
مثال، یک
هوک
getenv(3)
اگر متغیر
مشخصشده
در نسخه
اختصاصی
محیط یافت
نشود،
ممکن است
مقدار
SUDO_HOOK_RET_NEXTرا بازگرداند. SUDO_HOOK_RET_STOP- هوک بدون خطا تکمیل شد، پردازش هوکها برای این فراخوانی متوقف شود. این میتواند برای جایگزینی پیادهسازی سیستم استفاده شود. برای مثال، یک هوک setenv که روی یک نسخه اختصاصی از محیط عمل میکند اما environ را بدون تغییر باقی میگذارد.
هنگام قلاب کردن (hooking) توابع کتابخانه C باید دقت شود، زیرا ایجاد یک حلقه بینهایت بسیار آسان است. به عنوان مثال، یک هوک getenv(3) که تابع snprintf(3) را فراخوانی میکند، اگر پیادهسازی snprintf(3) برای بررسی محلیسازی (locale) تابع getenv(3) را فراخوانی کند، ممکن است یک حلقه ایجاد کند. برای جلوگیری از این امر، ممکن است بخواهید از یک متغیر ایستا (static) در تابع هوک برای محافظت در برابر فراخوانیهای تو در تو استفاده کنید. برای مثال:
static int in_progress = 0; /* avoid recursion */
if (in_progress)
return SUDO_HOOK_RET_NEXT;
in_progress = 1;
...
in_progress = 0;
return SUDO_HOOK_RET_STOP;
ماکروهای نسخه رابط هوک (Hook API Version Macros)
/* Hook API version major/minor */
#define SUDO_HOOK_VERSION_MAJOR 1
#define SUDO_HOOK_VERSION_MINOR 0
#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
SUDO_HOOK_VERSION_MINOR)
برای توابع دریافتکننده و تنظیمکننده (getters and setters) به بخش Policy plugin API مراجعه کنید.
رابط رویداد (Event API)
هنگامی که
sudo
دستوری را
اجرا
میکند، از
یک حلقه
رویداد (event loop)
برای
رسیدگی به
سیگنالها
و I/O استفاده
مینماید.
رویدادها
ممکن است بر
اساس زمان،
آماده شدن
یک
توصیفگر
فایل یا
سوکت، یا به
دلیل
دریافت یک
سیگنال
فعال شوند.
از نسخه ۱.۱۵
رابط
برنامهنویسی
(API) به بعد،
این امکان
برای یک
افزونه
فراهم شده
است که با
فراخوانی
تابع
event_alloc()
در این حلقه
رویداد
مشارکت
کند.
ساختار رویداد (Event structure)
رویدادها توسط ساختار زیر توصیف میشوند:
typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, void *closure);
struct sudo_plugin_event {
int (*set)(struct sudo_plugin_event *pev, int fd, int events,
sudo_plugin_ev_callback_t callback, void *closure);
int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout);
int (*del)(struct sudo_plugin_event *pev);
int (*pending)(struct sudo_plugin_event *pev, int events,
struct timespec *ts);
int (*fd)(struct sudo_plugin_event *pev);
void (*setbase)(struct sudo_plugin_event *pev, void *base);
void (*loopbreak)(struct sudo_plugin_event *pev);
void (*free)(struct sudo_plugin_event *pev);
};
یک struct sudo_plugin_event شامل اشارهگرهای تابع زیر است:
- set
-
int (*set)(struct sudo_plugin_event *pev, int fd, int events, sudo_plugin_ev_callback_t callback, void *closure);تابع
set() آرگومانهای زیر را دریافت میکند:- struct sudo_plugin_event *pev
- اشارهگری به خود struct sudo_plugin_event.
- fd
- توصیفگر فایل یا سوکت برای رویدادهای مبتنی بر I/O یا شماره سیگنال برای رویدادهای سیگنال. برای رویدادهای مبتنی بر زمان، fd باید -1 باشد.
- events
- مقادیر
زیر مشخص
میکنند
که چه چیزی
بازخوانی
(callback) رویداد
را فعال
میکند:
SUDO_PLUGIN_EV_TIMEOUT- کالبک پس از انقضای مهلت زمانی (timeout) مشخصشده اجرا میشود
SUDO_PLUGIN_EV_READ- کالبک هنگامی که توصیفگر فایل آماده خواندن باشد اجرا میشود
SUDO_PLUGIN_EV_WRITE- کالبک هنگامی که توصیفگر فایل آماده نوشتن باشد اجرا میشود
SUDO_PLUGIN_EV_PERSIST- رویداد ماندگار است و تا زمانی که صریحاً حذف نشود فعال باقی میماند
SUDO_PLUGIN_EV_SIGNAL- کالبک هنگام دریافت سیگنال مشخصشده اجرا میشود
فلگ
SUDO_PLUGIN_EV_PERSISTمیتواند با هر یک از انواع رویدادها با عملگر OR ترکیب شود. همچنین میتوانSUDO_PLUGIN_EV_READوSUDO_PLUGIN_EV_WRITEرا با هم OR کرد تا کالبک هنگامی که یک توصیفگر چه برای خواندن و چه برای نوشتن آماده باشد اجرا شود. سایر مقادیر رویداد نسبت به یکدیگر مانعةالجمع هستند. - sudo_plugin_ev_callback_t callback
-
typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, void *closure);تابعی که هنگام فعال شدن یک رویداد باید فراخوانی شود. تابع
callback() با آرگومانهای زیر اجرا میشود:- fd
- توصیفگر فایل یا سوکت برای رویدادهای مبتنی بر I/O یا شماره سیگنال برای رویدادهای سیگنال.
- what
- نوع
رویدادی
که موجب
فعال شدن
آن کالبک
شده است.
برای
رویدادهایی
که دارای
چندین نوع
رویداد
هستند
(برای مثال
SUDO_PLUGIN_EV_READوSUDO_PLUGIN_EV_WRITE) یا دارای مهلت زمانی مرتبط هستند، what میتواند برای تعیین علت اجرای کالبک استفاده شود. - closure
- اشارهگر
عمومی که
در تابع
set() مشخص شده است.
- closure
- اشارهگر عمومی که به تابع کالبک ارسال خواهد شد.
تابع
set() در صورت موفقیت مقدار 1 و در صورت بروز خطا مقدار -1 را بازمیگرداند. - add
-
int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout);
تابع
add() رویداد pev را به حلقه رویدادsudoاضافه میکند. رویداد باید پیشتر از طریق تابعset() مقداردهی اولیه شده باشد. اگر آرگومان timeout مقدار NULL نباشد، باید یک مهلت زمانی (نسبی) را مشخص کند که اگر معیار اصلی رویداد برآورده نشده باشد، رویداد پس از آن فعال شود. این اغلب برای پیادهسازی مهلت زمانی I/O استفاده میشود، جایی که اگر توصیفگر در یک بازه زمانی مشخص آماده نشود، رویداد شلیک میشود. اگر رویداد از قبل در حلقه رویداد موجود باشد، timeout آن برای مطابقت با مقدار جدید (در صورت وجود) بهروزرسانی خواهد شد.تابع
add() در صورت موفقیت مقدار 1 و در صورت بروز خطا مقدار -1 را بازمیگرداند. - del
-
int (*del)(struct sudo_plugin_event *pev);
تابع
del() رویداد pev را از حلقه رویدادsudoحذف میکند. رویدادهای حذفشده میتوانند دوباره از طریق تابعadd() اضافه شوند.تابع
del() در صورت موفقیت مقدار 1 و در صورت بروز خطا مقدار -1 را بازمیگرداند. - pending
-
int (*pending)(struct sudo_plugin_event *pev, int events, struct timespec *ts);تابع
pending() میتواند برای بررسی اینکه آیا یک یا چند رویداد در انتظار (pending) هستند یا خیر به کار رود. آرگومان events مشخص میکند که چه رویدادهایی بررسی شوند. برای مشاهده فهرستی از انواع رویدادهای معتبر، تابعset() را ببینید. اگرSUDO_PLUGIN_EV_TIMEOUTدر events مشخص شده باشد، رویداد دارای مهلت زمانی مرتبط باشد و اشارهگر ts غیر NULL باشد، با زمان باقیمانده پر خواهد شد. - fd
-
int (*fd)(struct sudo_plugin_event *pev);
تابع
fd() توصیفگر یا شماره سیگنال مرتبط با رویداد pev را بازمیگرداند. - setbase
-
void (*setbase)(struct sudo_plugin_event *pev, void *base);
تابع
setbase() پایه رویداد زیرین base را برای pev روی مقدار مشخصشده تنظیم میکند. این تابع میتواند برای انتقال رویدادی که از طریقevent_alloc() ایجاد شده است به یک حلقه رویداد جدید تخصیصیافته توسط زیرسیستم رویداد sudo استفاده شود. اگر base برابرNULLباشد، پایه رویداد pev به مقدار پیشفرض بازنشانی میشود، که متناظر با حلقه رویداد اصلیsudoاست. استفاده از این تابع نیازمند پیوند دادن (link) افزونه با کتابخانه sudo_util است. بعید است که در خارج از افزونهsudoersاستفاده شود. - loopbreak
-
void (*loopbreak)(struct sudo_plugin_event *pev);
تابع
loopbreak() باعث میشود حلقه رویدادsudoبلافاصله خارج شود و دستور در حال اجرا پایان یابد. - free
-
void (*free)(struct sudo_plugin_event *pev);
تابع
free() رویداد pev را از حلقه رویداد حذف کرده و حافظه مرتبط با آن را آزاد میکند.
اجرای دستور از راه دور (Remote command execution)
فرانتاند
sudo از
اجرای
دستورات از
راه دور
پشتیبانی
نمیکند. با
این حال، از
نسخه ۱.۸.۸
sudo به
بعد، گزینه
-h
میتواند
برای مشخص
کردن یک
میزبان راه
دور که به
افزونه
خطمشی
ارسال
میشود
استفاده
شود. یک
افزونه
همچنین
ممکن است یک
runas_user را در
قالب “user@hostname”
بپذیرد که
با
نسخههای
قدیمیتر
sudo نیز
کار خواهد
کرد.
پیشبینی
میشود که
دستورات
راه دور با
اجرای یک
برنامه
کمکی ( “helper” )
پشتیبانی
شوند.
افزونه
خطمشی
باید محیط
اجرا را به
گونهای
آماده کند
که
فرانتاند
sudo
برنامه
کمکی را
اجرا کند، و
آن برنامه
نیز به نوبه
خود به
میزبان راه
دور متصل
شده و دستور
را اجرا
نماید.
به عنوان
مثال،
افزونه
خطمشی
میتواند
از ssh
برای اجرای
دستور از
راه دور
بهره ببرد.
برنامه
کمکی مسئول
اجرای ssh
با
گزینههای
مناسب برای
استفاده از
کلید خصوصی
یا گواهی
معتبر جهت
پذیرش توسط
میزبان راه
دور، و
اجرای
برنامهای
در میزبان
راه دور
خواهد بود
که محیط
اجرا را
متناسب با
آن آماده
کند.
قابلیت
راه دور
sudoedit باید
توسط
افزونه
خطمشی
مدیریت
شود، نه خود
sudo ، چرا
که
فرانتاند
اطلاعی از
در حال اجرا
بودن یک
دستور راه
دور ندارد.
این موضوع
ممکن است در
بازنگریهای
آینده رابط
برنامهنویسی
افزونه
برطرف شود.
رابط مکالمه (Conversation API)
اگر
افزونه
نیاز به
تعامل با
کاربر
داشته
باشد،
میتواند
این کار را
از طریق
تابع
conversation()
انجام دهد.
یک افزونه
نباید تلاش
کند
مستقیماً
از ورودی
استاندارد
یا ترمینال
کاربر
بخواند
(وجود
هیچکدام
تضمین نشده
است).
فراخواننده
در صورتی که
نیاز به چاپ
خط جدید
باشد، باید
یک کاراکتر
خط جدید
انتهایی را
در msg
بگنجاند.
یک تابع
به سبک
printf()
نیز در
دسترس است
که
میتواند
برای نمایش
پیامهای
اطلاعاتی
یا خطا به
کاربر
استفاده
شود، که
معمولاً
برای
پیامهای
سادهای که
به هیچ
ورودی
کاربری
نیاز
ندارند
مناسبتر
است.
ساختارهای تابع مکالمه (Conversation function structures)
تابع مکالمه به عنوان آرگومان، اشارهگرهایی به ساختارهای زیر را میگیرد:
struct sudo_conv_message {
#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
int msg_type;
int timeout;
const char *msg;
};
#define SUDO_CONV_REPL_MAX 1023
struct sudo_conv_reply {
char *reply;
};
typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
struct sudo_conv_callback {
unsigned int version;
void *closure;
sudo_conv_callback_fn_t on_suspend;
sudo_conv_callback_fn_t on_resume;
};
اشارهگرها
به توابع
conversation()
و به سبک
printf() هنگام
مقداردهی
اولیه
افزونه، به
تابع open()
افزونه
ارسال
میشوند.
تعاریف نوع
زیر
میتوانند
در اعلان
تابع open()
استفاده
شوند:
typedef int (*sudo_conv_t)(int num_msgs,
const struct sudo_conv_message msgs[],
struct sudo_conv_reply replies[], struct sudo_conv_callback *callback);
typedef int (*sudo_printf_t)(int msg_type, const char * restrict fmt, ...);
برای
استفاده از
تابع
conversation()
، افزونه
باید
آرایهای
از struct sudo_conv_message و
struct sudo_conv_reply را
ارسال کند.
باید برای
هر پیام در
مکالمه یک
struct sudo_conv_message و یک
struct sudo_conv_reply
وجود داشته
باشد، به
این معنی که
هر دو آرایه
باید دارای
تعداد
عناصر
یکسانی
باشند. هر
struct sudo_conv_reply
باید عضو
reply خود را
با NULL
مقداردهی
اولیه کرده
باشد.
اشارهگر
struct sudo_conv_callback ،
اگر NULL
نباشد،
باید شامل
اشارهگرهای
تابعی باشد
که هنگام
تعلیق (suspend) یا
ازسرگیری (resume)
فرآیند
sudo در حین
دریافت
ورودی
مکالمه
فراخوانی
شوند. توابع
on_suspend و on_resume
با سیگنالی
که باعث
تعلیق sudo
شده است و
اشارهگر
closure از struct
sudo_conv_callback
فراخوانی
میشوند.
این توابع
باید در
صورت
موفقیت
مقدار 0 و در
صورت بروز
خطا مقدار -1
را
بازگردانند.
در صورت
بروز خطا،
مکالمه
خاتمه
مییابد و
تابع
مکالمه
مقدار -1 را
بازمیگرداند.
کاربرد
مورد نظر
این است که
به افزونه
اجازه داده
شود منابعی
مانند
قفلها را
که نباید
هنگام
تعلیق به
طور
نامحدود
نگه داشته
شوند آزاد
کند و سپس با
ازسرگیری
فرآیند،
دوباره
آنها را در
اختیار
بگیرد. این
توابع در
واقع از
داخل یک
گرداننده
سیگنال (signal handler)
اجرا
نمیشوند.
مقدار msg_type باید روی یکی از مقادیر زیر تنظیم شود:
SUDO_CONV_PROMPT_ECHO_OFF- درخواست
ورودی از
کاربر با
غیرفعال
بودن پژواک
(echo) ورودی؛
این گزینه
معمولاً
برای
گذرواژهها
استفاده
میشود.
پاسخ در
آرایه replies
ذخیره
خواهد شد و
هرگز
NULLنخواهد بود. SUDO_CONV_PROMPT_ECHO_ON- درخواست
ورودی از
کاربر با
فعال بودن
پژواک (echo)
ورودی. پاسخ
در آرایه
replies ذخیره
خواهد شد و
هرگز
NULLنخواهد بود. SUDO_CONV_ERROR_MSG- نمایش یک
پیام خطا.
پیام در
خروجی خطای
استاندارد
(standard error) نوشته
میشود مگر
اینکه فلگ
SUDO_CONV_PREFER_TTYتنظیم شده باشد، که در این صورت در صورت امکان در ترمینال کاربر نوشته میشود. SUDO_CONV_INFO_MSG- نمایش یک
پیام. پیام
در خروجی
استاندارد
(standard output) نوشته
میشود مگر
اینکه فلگ
SUDO_CONV_PREFER_TTYتنظیم شده باشد، که در این صورت در صورت امکان در ترمینال کاربر نوشته میشود. SUDO_CONV_PROMPT_MASK- درخواست
ورودی از
کاربر با
نمایش
نویسه
ستاره به
ازای هر
نویسه
خواندهشده.
پاسخ در
آرایه replies
ذخیره
خواهد شد و
هرگز
NULLنخواهد بود. این میتواند برای ارائه بازخورد بصری به کاربر در حین خواندن اطلاعات حساسی که نباید نمایش داده شوند استفاده شود.
علاوه بر مقادیر فوق، بیتهای فلگ زیر نیز میتوانند تنظیم شوند:
SUDO_CONV_PROMPT_ECHO_OK- اجازه
خواندن
ورودی در
حالتی که
غیرفعال
کردن echo ممکن
نیست،
هنگامی که
نوع پیام
SUDO_CONV_PROMPT_ECHO_OFFیاSUDO_CONV_PROMPT_MASKباشد. به طور پیشفرض، اگر نتوان echo را برای این نوع پیامها غیرفعال کرد،sudoاز خواندن ورودی امتناع میورزد. SUDO_CONV_PREFER_TTY- هنگام
نمایش پیام
از طریق
SUDO_CONV_ERROR_MSGیاSUDO_CONV_INFO_MSG، تلاش میکند پیام را در ترمینال کاربر بنویسد. اگر ترمینال در دسترس نباشد، بسته به اینکه ازSUDO_CONV_ERROR_MSGیاSUDO_CONV_INFO_MSGاستفاده شده باشد، خروجی خطای استاندارد یا خروجی استاندارد استفاده خواهد شد. ترمینال کاربر همیشه در صورت امکان برای ورودی استفاده میشود؛ این فلگ تنها برای خروجی کاربرد دارد.
پارامتر timeout به ثانیه مشخص میکند که اعلان تا چه مدت منتظر ورودی بماند. مقدار صفر به معنای مهلت زمانی نامحدود است.
افزونه
مسئول
آزادسازی
بافر پاسخ
موجود در هر
struct sudo_conv_reply
است، در
صورتی که
مقدار آن
NULL نباشد.
ثابت SUDO_CONV_REPL_MAX
نشاندهنده
حداکثر طول
بافر پاسخ
است (بدون
احتساب
نویسه NUL
انتهایی). از
دیدگاه
کاربردی،
این
طولانیترین
گذرواژهای
است که sudo
پشتیبانی
خواهد کرد.
تابع به
سبک
printf()
از همان
سازوکار
زیرین تابع
conversation()
استفاده
میکند اما
فقط از
SUDO_CONV_INFO_MSG و
SUDO_CONV_ERROR_MSG برای
پارامتر
msg_type
پشتیبانی
مینماید.
اگر نیازی
به پاسخ
کاربر
نباشد، این
تابع
میتواند
راحتتر از
تابع conversation()
باشد و از
دنبالههای
فرار
استاندارد
printf()
پشتیبانی
میکند.
برای
مشاهده یک
مثال از
کاربرد
تابع
conversation()
، افزونه
نمونه را
ببینید.
ترتیب فراخوانی افزونهها (Plugin invocation order)
از نسخه
۱.۹.۰ sudo به
بعد، توابع
open() و close()
افزونه به
ترتیب زیر
فراخوانی
میشوند:
- audit open
- policy open
- approval open
- approval close
- I/O log open
- اجرای دستور (command runs)
- خاتمه دستور (command exits)
- I/O log close
- policy close
- audit close
- خروج sudo
پیش از
نسخه ۱.۹.۰
sudo ، تابع
close()
لاگ I/O پس
از تابع
close()
خطمشی
فراخوانی
میشد.
رابط افزونههای گروه sudoers (Sudoers group plugin API)
افزونه
sudoers از
رابط
افزونه
اختصاصی
خود برای
فعالسازی
جستجوی
گروههای
غیر
یونیکسی
پشتیبانی
میکند. این
قابلیت
میتواند
برای
پرسوجو از
یک منبع
گروه به غیر
از
پایگاهداده
استاندارد
گروههای
یونیکس به
کار رود. دو
افزونه
گروه نمونه
همراه با
sudo عرضه
شدهاند،
group_file
و
system_group
، که جزئیات
آنها در
sudoers(5)
آمده است.
افزونههای
گروه شخص
ثالث شامل
یک افزونه QAS AD
هستند که
توسط Quest Software
عرضه شده
است.
یک افزونه گروه باید یک struct sudoers_group_plugin را در حوزه سراسری (global scope) اعلان کرده و مقداردهی کند. این ساختار حاوی اشارهگرهایی به توابعی است که مقداردهی اولیه افزونه، پاکسازی و جستجوی گروه را پیادهسازی میکنند.
struct sudoers_group_plugin {
unsigned int version;
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
char *const argv[]);
void (*cleanup)(void);
int (*query)(const char *user, const char *group,
const struct passwd *pwd);
};
یک struct sudoers_group_plugin دارای فیلدهای زیر است:
- version
- فیلد version
باید روی
GROUP_API_VERSION تنظیم
شود.
این به
sudoersامکان میدهد تا نسخه API که افزونه گروه بر اساس آن ساخته شده است را تشخیص دهد. - init
-
int (*init)(int version, sudo_printf_t sudo_plugin_printf, char *const argv[]);تابع
init() پس از تجزیه شدن sudoers اما پیش از هرگونه بررسی خطمشی فراخوانی میشود. در صورت موفقیت مقدار 1، در صورت عدم موفقیت (یا اگر افزونه پیکربندی نشده باشد) مقدار 0 و در صورت بروز خطا مقدار -1 را بازمیگرداند. اگر خطایی رخ دهد، افزونه میتواند تابعplugin_printf() را باSUDO_CONF_ERROR_MSGفراخوانی کند تا اطلاعات خطای بیشتری را به کاربر نمایش دهد.آرگومانهای تابع به شرح زیر هستند:
- version
- نسخه
ارسالشده
توسط
sudoersبه افزونه امکان میدهد تا شماره نسخه اصلی و فرعی رابط افزونه گروه که توسطsudoersپشتیبانی میشود را مشخص کند. - plugin_printf
- اشارهگری
به یک تابع
به سبک
printf() که میتواند برای نمایش پیامهای اطلاعاتی یا خطا به کاربر استفاده شود. در صورت موفقیت، تعداد نویسههای چاپشده و در صورت شکست، مقدار -1 را بازمیگرداند. - argv
- یک آرایه
خاتمهیافته
با
NULLاز آرگومانهای تولیدشده از گزینه group_plugin در sudoers است. اگر هیچ آرگومانی داده نشده باشد، argv برابرNULLخواهد بود.
- cleanup
-
void (*cleanup)();
تابع
cleanup() زمانی فراخوانی میشود کهsudoersبررسیهای گروه خود را به پایان رسانده باشد. افزونه باید هرگونه حافظهای را که تخصیص داده است آزاد کند و توصیفگرهای باز فایل را ببندد. - query
-
int (*query)(const char *user, const char *group, const struct passwd *pwd);تابع
query() برای پرسش از افزونه گروه در این باره که آیا user عضوی از group است یا خیر استفاده میشود.آرگومانهای تابع به شرح زیر هستند:
- user
- نام کاربری که در پایگاهداده خارجی گروه جستجو میشود.
- group
- نام گروهی که مورد پرسوجو قرار میگیرد.
- pwd
- مدخل
پایگاهداده
گذرواژه
برای user
(در صورت
وجود). اگر
user در
پایگاهداده
گذرواژه
موجود
نباشد،
pwd برابر
NULLخواهد بود.
ماکروهای نسخه رابط برنامهنویسی گروه (Group API Version Macros)
/* Sudoers group plugin version major/minor */
#define GROUP_API_VERSION_MAJOR 1
#define GROUP_API_VERSION_MINOR 0
#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
GROUP_API_VERSION_MINOR)
تغییرات رابط افزونه (PLUGIN API CHANGELOG)
بازبینیهای زیر در رابط برنامهنویسی افزونههای (API) سدو اعمال شده است.
- Version 1.0
- نسخه اولیه API.
- Version 1.1 (sudo 1.8.0)
- تابع
open() در افزونههای ثبت وقایع ورودی/خروجی (I/O logging) به گونهای اصلاح شد که فهرست command_info را به عنوان یک آرگومان دریافت کند. - Version 1.2 (sudo 1.8.5)
- به توابع
open() در افزونههای خطمشی (Policy) و ثبت ورودی/خروجی (I/O logging) اکنون در صورت مشخص شدن پارامترهای افزونه در sudo.conf(5) ، فهرستی از آنها ارسال میشود.یک رابط هوک (hooks API) ساده معرفی شده است که به افزونهها اجازه میدهد به توابع مدیریت محیط سیستم متصل شوند.
به تابع
init_session() در افزونه خطمشی، اکنون اشارهگری به محیط کاربری ارسال میشود که در صورت نیاز قابل بهروزرسانی است. از این قابلیت میتوان برای ادغام متغیرهای محیطی ذخیرهشده در دسته PAM پیش از اجرای دستور استفاده کرد. - Version 1.3 (sudo 1.8.7)
- پشتیبانی
از ورودی
exec_background به
فهرست
command_info
اضافه شد.
ورودیهای max_groups و plugin_dir به فهرست settings اضافه شدند.
توابع
version() وclose() اکنون اختیاری هستند. پیش از این، عدم وجود تابعversion() یاclose() منجر به از کار افتادن برنامه (کرش) میشد. اگر هیچ تابعclose() در افزونه خطمشی تعریف نشده باشد، یک تابعclose() پیشفرض توسط فرانتاندsudoارائه میشود که در صورت عدم امکان اجرای دستور، یک هشدار نمایش میدهد.فرانتاند
sudoاکنون گردانندههای سیگنال (signal handlers) پیشفرضی را برای بهدامانداختن سیگنالهای متداول هنگام اجرای توابع افزونه نصب میکند. - Version 1.4 (sudo 1.8.8)
- ورودی remote_host به فهرست settings اضافه شد.
- Version 1.5 (sudo 1.8.9)
- ورودی preserve_fds به فهرست command_info اضافه شد.
- Version 1.6 (sudo 1.8.11)
- رفتار
سیستم
هنگام
بازگرداندن
خطا توسط
افزونه ثبت
ورودی/خروجی
(-1) تغییر
کرده است.
پیش از این،
فرانتاند
sudoهنگامی که توابعlog_ttyin(،)log_ttyout(،)log_stdin(،)log_stdout() یاlog_stderr() خطایی بازمیگرداندند، هیچ اقدامی انجام نمیداد.رفتار سیستم هنگامی که یک افزونه ثبت ورودی/خروجی مقدار 0 را برمیگرداند تغییر کرده است. پیش از این، خروجی دستور حتی در صورتی که تابع ثبت خروجی مقدار 0 را بازمیگرداند نیز روی ترمینال نمایش داده میشد.
- Version 1.7 (sudo 1.8.12)
- ورودی
plugin_path
به فهرست
settings اضافه
شد.
ورودی debug_flags اکنون با نام مسیر فایل اشکالزدایی آغاز میشود و در صورتی که چندین خط Debug ویژه افزونه در فایل sudo.conf(5) وجود داشته باشد، ممکن است چندین بار تکرار شود.
- Version 1.8 (sudo 1.8.15)
- ورودیهای
sudoedit_checkdir و
sudoedit_follow به
فهرست
command_info
اضافه شدند.
مقدار
پیشفرض
sudoedit_checkdir در sudo 1.8.16
به true تغییر
یافت.
تابع
conversation() در sudo اکنون اشارهگری به یک struct sudo_conv_callback را به عنوان چهارمین آرگومان خود دریافت میکند. تعریف sudo_conv_t برای تطابق بهروزرسانی شده است. افزونه باید مشخص کند که از نسخه 1.8 یا بالاتر API افزونه پشتیبانی میکند تا اشارهگر تابع گفتگویی را دریافت نماید که از این آرگومان پشتیبانی میکند. - Version 1.9 (sudo 1.8.16)
- ورودی execfd به فهرست command_info اضافه شد.
- Version 1.10 (sudo 1.8.19)
- ورودی umask به فهرست user_info اضافه شد. ورودیهای iolog_group ، iolog_mode و iolog_user به فهرست command_info اضافه شدند.
- Version 1.11 (sudo 1.8.20)
- ورودی timeout به فهرست settings اضافه شد.
- Version 1.12 (sudo 1.8.21)
- تابع
change_winsize() به struct io_plugin اضافه شد. - Version 1.13 (sudo 1.8.26)
- تابع
log_suspend() به struct io_plugin اضافه شد. - Version 1.14 (sudo 1.8.29)
- ورودی umask_override به فهرست command_info اضافه شد.
- Version 1.15 (sudo 1.9.0)
- ورودی cwd_optional
به فهرست
command_info
اضافه شد.
تابع
event_alloc() به struct policy_plugin و struct io_plugin اضافه شد.آرگومان errstr به توابع افزونههای خطمشی و ورودی/خروجی افزوده شد که تابع افزونه میتواند از آن برای بازگرداندن رشته خطا استفاده کند. این رشته ممکن است توسط افزونه حسابرسی (audit plugin) برای گزارش شرایط شکست یا خطای تعیینشده توسط سایر افزونهها به کار رود.
تابع
close() اکنون صرفنظر از اینکه دستوری واقعاً اجرا شده است یا خیر، فراخوانی میشود. این امر امکان پاکسازی منابع را برای افزونهها حتی در صورت عدم اجرای دستور فراهم میآورد.مقدار
SUDO_CONV_REPL_MAXاز ۲۵۵ به ۱۰۲۳ بایت افزایش یافت.پشتیبانی از افزونههای حسابرسی (audit) و تایید (approval) اضافه شد.
- Version 1.16 (sudo 1.9.3)
- مقادیر
اولیه
محدودیت
منابع به
فهرست user_info
اضافه شدند.
ورودیهای cmnd_chroot و cmnd_cwd به فهرست settings اضافه شدند.
- Version 1.17 (sudo 1.9.4)
- تابع
event_alloc() به struct audit_plugin و struct approval_plugin اضافه شد. - Version 1.18 (sudo 1.9.9)
- افزونه خطمشی اکنون میتواند مقادیر محدودیت منابع را در فهرست command_info تنظیم کند. ورودیهای intercept و log_subcmds به فهرست command_info اضافه شدند.
- Version 1.19 (sudo 1.9.11)
- ورودیهای intercept_ptrace و intercept_setid به فهرست settings اضافه شدند. ورودیهای apparmor_profile و use_ptrace به فهرست command_info اضافه شدند.
- Version 1.20 (sudo 1.9.12)
- ورودی update_ticket به فهرست settings اضافه شد. ورودی intercept_verify به فهرست command_info اضافه شد.
- Version 1.21 (sudo 1.9.13)
- ورودی sudoedit_nfiles به فهرست command_info اضافه شد.
- Version 1.22 (sudo 1.9.16)
- ورودی ttydev به فهرست user_info اضافه شد.
همچنین ببینید (SEE ALSO)
نویسندگان (AUTHORS)
افراد
بسیاری در
طول سالها
روی sudo
کار
کردهاند؛
این نسخه
عمدتاً
شامل کدهای
نوشتهشده
توسط فرد
زیر است:
برای
فهرست کامل
افرادی که
در sudo
مشارکت
داشتهاند،
پرونده CONTRIBUTORS.md
را در توزیع
sudo (https://www.sudo.ws/about/contributors)
مشاهده
فرمایید.
اشکالات (BUGS)
اگر
معتقدید
اشکالی در
sudo_plugin
یافتهاید،
میتوانید
یک گزارش
اشکال در
پایگاهداده
اشکالات
سدو در https://bugzilla.sudo.ws
ثبت کنید یا
یک issue در
https://github.com/sudo-project/sudo/issues باز
نمایید.
چنانچه
ترجیح
میدهید از
ایمیل
استفاده
کنید،
پیامها
میتوانند
به فهرست
پستی sudo-workers در
https://www.sudo.ws/mailman/listinfo/sudo-workers
(عمومی) یا به
<sudo@sudo.ws> (خصوصی)
ارسال
شوند.
لطفاً آسیبپذیریهای امنیتی را از طریق issueهای عمومی گیتهاب، باگزیلا یا فهرستهای پستی گزارش نکنید. در عوض، آنها را از طریق ایمیل به <Todd.Miller@sudo.ws> گزارش دهید. در صورت تمایل میتوانید پیام خود را با کلید PGP موجود در https://www.sudo.ws/dist/PGPKEYS رمزگذاری کنید.
پشتیبانی (SUPPORT)
پشتیبانی رایگان و محدود از طریق فهرست پستی sudo-users در دسترس است، برای عضویت یا جستجو در آرشیو نشانی https://www.sudo.ws/mailman/listinfo/sudo-users را ببینید.
سلب مسئولیت (DISCLAIMER)
sudo
بهصورت “AS
IS” ارائه
میشود و
هرگونه
ضمانت صریح
یا ضمنی، از
جمله، اما
نه محدود
به،
ضمانتهای
ضمنی
قابلیت
فروش و
تناسب برای
یک هدف خاص
سلب میشود.
برای
جزئیات
کامل،
پرونده LICENSE.md
ارائهشده
همراه با
sudo یا
نشانی https://www.sudo.ws/about/license
را ملاحظه
فرمایید.
| August 14, 2024 | Sudo 1.9.17p2 |