سؤال

أقوم بتشغيل Raspberry pi وأرغب في إنشاء ملف قابل للتنفيذ والذي يجب ببساطة إعادة تشغيله بعد بضع ثوانٍ.(أخطط لتشغيله عبر ssh وتسجيل الخروج قبل إجراء عملية إعادة التشغيل الفعلية)

لقد قمت بإنشاء ملف قابل للتنفيذ باستخدام c++ مع المحتوى:

#include <cstdlib>

int main () {
    system("sleep 5");
    system("reboot");
    return 0;
}

ls -l للملف القابل للتنفيذ الناتج:

---s--x--x 1 root ben 6191 Jan 10 15:42 reboot

كانت خطتي الآن هي استخدام بت setuid مع الجذر كمالك للثنائي بحيث يمكن تنفيذ أمر إعادة التشغيل بواسطة أي مستخدم.

للأسف لا يعمل هذا، وعند تشغيل البرنامج يعطيني:

Failed to issue method call: Access denied
Must be root.

أي تفسير لماذا لا يعمل هذا؟

أعلم أنه قد تكون هناك طرق أسهل للقيام بذلك.يهدف هذا السؤال حقًا إلى فهم سبب عدم نجاح هذه الطريقة.

شكرا لكم مقدما وتحياتي

هل كانت مفيدة؟

المحلول

لقد واجهت مشكلة مماثلة مع setuid bit وبعض الإصدارات من bash.في حالتي كان الحل هو كتابة البرنامج مثل هذا:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  // circumvent busybox ash dropping privileges
  uid_t uid = geteuid();
  setreuid(uid, uid);

  system("do something....");
  return 0;
}

آمل أن يكون هذا سوف يساعدك أيضا.

نصائح أخرى

على الرغم من عدم الإجابة بشكل مباشر على سؤالك، ماذا عن السماح للمستخدمين بالتشغيل shutdown مع sudo؟يمكنك أيضًا تحديد الخيارات المسموح لهم باستخدامها (انظر قسم sudoers(5) صفحة الرجل).أو قم بإنشاء برنامج نصي مجمّع باستخدام الوسائط المناسبة واسمح للمستخدمين بتشغيله.ويمكنه أيضًا التحقق مما إذا كان لديه الحقوق المناسبة ومحاولة إعادة تنفيذ نفسه من خلاله sudo اذا كان ضروري:

#!/bin/sh
if test `id -u` -eq 0; then
    # do your stuff - shutdown, poweroff, whatever
else
    exec sudo $0 "$@"
fi

وفق هذا وثيقة، system() في الواقع يدعو /bin/sh, ، والذي، في بعض التوزيعات، يتجاهل خيار بت Set-UID.

قد تحاول استخدام exec() بدلا من system() والاستدعاء مباشرة /sbin/shutdown?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top