خدمات متعددة من نفس الملف القابل للتنفيذ

StackOverflow https://stackoverflow.com/questions/113288

  •  02-07-2019
  •  | 
  •  

سؤال

لقد كتبت خدمة صغيرة (Win32 عادي) وأود أن أعرف ما إذا كان من الممكن تشغيل مثيلات متعددة منها عند تسجيل دخول عدة مستخدمين.

في الأساس، لنفترض أن لدينا UserA وUserB لـ UserA، ستسجل الخدمة باسم "domain\UserA" وبالنسبة لـ UserB، سيتم تسجيل دخول الخدمة باسم "domain\UserB" - وهذا من نفس الملف القابل للتنفيذ بالطبع.يمكنني تغيير تسجيل الدخول ديناميكيًا باستخدام وظيفة ChangeServiceConfig()، ولكنها تغيرها على مستوى النظام على ما يبدو، بينما أرغب في أن يكون لكل مستخدم نسخته الخاصة من الخدمة التي تعمل له فقط.

شكرا لكم مقدما على أي مؤشرات.

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

المحلول

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

نصائح أخرى

هل من الممكن أن تقوم الخدمة بإنشاء عمليات فرعية تتبنى بعد ذلك بيانات اعتماد المستخدم (أو تبدأ بها)؟بهذه الطريقة، ستظل مقيدًا بمثيل واحد للخدمة، ولكنها قادرة على القيام بمهامها لكل مستخدم بنفس الطريقة.تقوم خدمة IIRC لجدولة المهام في Windows بهذا.

المفهوم الكامل للخدمة هو أنها تبدأ قبل أن يقوم أي مستخدم بتسجيل الدخول.لذلك، حتى لو كان ذلك ممكنًا، فلن تتمكن من الاختيار بين المستخدم "أ" والمستخدم "ب" عند بدء الخدمة لأنه لم يتم تسجيل دخول أي منهما بعد.


سيكون الاتجاه المحتمل هو تشغيل الخدمة كـ SYSTEM وكل بضع دقائق تحقق مما إذا كان هناك مستخدم قام بتسجيل الدخول، إذا كان هناك - انتحال شخصية هذا المستخدم وقم بهذه الأشياء.

نعم، يبدو هذا قريبًا (أنا أرد على تعليق جريج، لكن التعليقات قصيرة جدًا بحيث لا تتناسب مع ردي).

لا أعرف قائمة المستخدمين مسبقًا، ولكن هناك تطبيق تحكم في واجهة المستخدم الرسومية يمكن استخدامه لإدخال أزواج اسم المستخدم/كلمة المرور لكل مستخدم.لذلك، سيقوم المستخدم "أ" بتسجيل الدخول وتشغيل التطبيق وإدخال بيانات الاعتماد الخاصة به وستستخدم الخدمة ذلك.في نفس الوقت (بعد تسجيل خروج المستخدم "أ"، ولكن الخدمة لا تزال قيد التشغيل باستخدام بيانات اعتماد المستخدم "أ")، يقوم المستخدم "ب" بتسجيل الدخول، ويستخدم التطبيق، وتبدأ نسخة أخرى من الخدمة في التشغيل عند تسجيل دخول المستخدم "ب".وبالتالي، يتم تشغيل خدمات userA وuserB في نفس الوقت.

هل هذا ممكن؟

من المحتمل أنك تتطلع إلى انتحال شخصية المستخدمين.تحقق من بعض المراجع التي وجدتها من خلال بحث سريع على Google هنا:

يبدو الأمر كما لو أن لديك بالفعل متطلبين مختلفين ومتضاربين فيما يتعلق بالتوقيت والهوية.

  1. تشغيل مثل كل مستخدم قام بتسجيل الدخول
  2. تشغيل تلقائي حتى لو لم يتم تسجيل دخول أي مستخدم.

لا توجد طريقة للقيام بذلك بشكل تافه، وبدلاً من ذلك فكر في تغليف برنامجك في خدمة؛سيتم تشغيل البرنامج بشكل طبيعي عند بدء التشغيل لكل مستخدم (إما من خلال مجلد بدء التشغيل أو جدولة المهام)، و فضلاً عن ذلك إنشاء خدمة لتشغيل تطبيقك كمستخدم للنظام (أو أي مستخدم آخر تحدده).
نظرًا لأنك تحتاج أيضًا (ذكرت ذلك في التعليقات) إلى استمرار تشغيل التطبيق كمستخدم نهائي حتى بعد تسجيل الخروج، فيمكنك جعل الخدمة تدير هذه العملية نيابةً عنك.

ومع ذلك، قد لا تكون هذه هي الفكرة الأفضل، نظرًا لأن المستخدم لا يزال قيد تسجيل الدخول بشكل فعال.يمكن أن يكون لهذا آثار جانبية عديدة، بما في ذلك الأمان والأداء (قام عدد كبير جدًا من المستخدمين بتسجيل الدخول مرة واحدة...) وما إلى ذلك.

يمكنك إنشاء تطبيق خدمة وتطبيق غير خدمي (عادي) وجعلهما يتواصلان من خلال IPC (ملف معين، أنابيب، MailSolts ...سمها ما شئت).

بهذه الطريقة يمكنك حل جميع المشاكل.

ملحوظة:يمكن أن يتصرف نفس التطبيق بشكل مختلف - عندما يبدأ كعملية وعندما يبدأ بواسطة المستخدم، ولكن في النهاية هو نفس الشيء، فلا يزال لديك تطبيقان (بغض النظر عما إذا كان لديك تطبيق واحد فقط قابل للتنفيذ).

التشغيل بحسابات مختلفة أمر ممكن.في الواقع، هذا أمر شائع.راجع ملف svchost.exe، الذي ينفذ مجموعة من خدمات نظام التشغيل.

أنا لا أفهم كيف يمكنك تحديد الحسابات.في الشركات الكبيرة، يتم إعداد العديد من أجهزة الكمبيوتر بحيث يتمكن جميع الموظفين الذين يزيد عددهم عن 100.000 موظف من استخدامها.لا تريد تشغيل خدمتك كمستخدمين مسجلين الدخول، ولا يمكنك تشغيلها لجميع المستخدمين البالغ عددهم 100.000.لذا، ما هي الحسابات التي يجب أن أسألها؟

لا يمكن تنفيذ عملية Windows إلا بامتيازات مستخدم واحد في كل مرة.وهذا ينطبق على الخدمات والعمليات الأخرى.مع الامتيازات الكافية، من الممكن "التبديل" بين مستخدمين مختلفين باستخدام الانتحال.النمط الأكثر شيوعًا لما تحاول القيام به هو أن يكون لديك مثيل واحد من الخدمة المميزة التي تسجل أحداث تسجيل الدخول/الخروج وتنشئ عمليات فرعية وفقًا لذلك، كل واحدة منها تنتحل شخصية المستخدم الذي قام بتسجيل الدخول.سيقوم النمط أيضًا بتبسيط واجهة المستخدم حيث يتم تشغيل كل عملية على سطح مكتب كل مستخدم منفصل، كما لو كان تطبيقًا عاديًا.

إذا احتفظت برمز الخدمة المميزة بسيطًا قدر الإمكان، فإن هذا النمط له فائدة إضافية تتمثل في تقليل سطح الهجوم الخاص بالرمز الخاص بك.إذا وجد المستخدم مشكلة أمنية في جانب "التشغيل كمستخدم" من الخدمة الخاصة بك، فهذه ليست مشكلة، بينما قد تؤدي مشكلات الأمان في الخدمات المميزة إلى تصعيد الامتيازات.في الواقع، قبل نظام التشغيل Vista، كانت الخدمات المميزة التي تنفذ حلقة معالجة رسائل Windows عرضة لنوع من الهجوم يسمى هجمات تحطيم, ، والذي يجب أن تكون على دراية به نظرًا لما تحاول القيام به.

تريد تشغيل هذا طوال الوقت، لذلك تريد الخدمة.

تريد شيئًا يتتبع كل مستخدم، لذلك تريد تطبيقًا يتم تشغيله في جلسة المستخدم ويتواصل مع الخدمة (باستخدام الأنابيب المسماة أو DCOM أو أي شيء يناسب متطلباتك).

لا تحتاج إلى مثيلات متعددة لخدمتك.من وصف مشكلتك، يبدو أن ما تحتاجه هو خدمة واحدة يمكنها انتحال هوية المستخدمين وتنفيذ المهام نيابة عنهم.

يمكنك القيام بذلك عن طريق تطبيق كائن COM مستضاف في الخدمة.سيقوم تطبيق العميل الخاص بك (الذي يقوم بتشغيله المستخدم النهائي) باستدعاء CoCreateInstanceEx على CLSID الخاص بك.قد يؤدي هذا إلى إنشاء مثيل جديد لكائن COM الخاص بك في خدمتك.بعد ذلك يمكن للتطبيق استخدام طريقة على إحدى واجهاتك لتمرير بيانات اعتماد المستخدم المجمعة إلى كائن COM (على الرغم من أنني سأكون حذرًا من جمع بيانات الاعتماد وبدلاً من ذلك أرى ما إذا كان بإمكاني تمرير رمز المستخدم المميز بدلاً من ذلك).يمكن لكائن COM الذي يعمل في سياق الخدمة بعد ذلك استدعاء LogonUser() لتسجيل الدخول وانتحال شخصيته، حتى يتمكن من القيام بأي شيء نيابة عنها (مثل العثور على مجلد بيانات التطبيق المحلي للمستخدم :-)).تحتوي الإجابات الأخرى على روابط جيدة لانتحال هوية المستخدمين باستخدام بيانات الاعتماد أو الرمز المميز.

إذا كنت تشعر بالراحة مع COM، فأنا أقترح عليك إنشاء الكائنات الخاصة بك على أنها متعددة الخيوط (تعيش في MTA)، بحيث لا يتم إجراء تسلسل لتنفيذها بواسطة COM.إذا لم يكن الأمر كذلك، فسيكون النموذج الافتراضي ذو الخيوط الفردية جيدًا بما يكفي بالنسبة لك.

يمكن لمعالج Visual Studio ATL إنشاء هيكل كائن COM الموجود في الخدمة.يمكنك أيضًا القراءة حول تنفيذ خدمة Windows باستخدام ATL هنا: http://msdn.microsoft.com/en-us/library/74y2334x(VS.80).aspx

إذا كنت لا تعرف COM على الإطلاق، فيمكنك استخدام قنوات اتصال أخرى لتمرير بيانات الاعتماد إلى الخدمة الخاصة بك.

على أية حال، بمجرد حصول خدمتك على بيانات الاعتماد، يجب تنفيذ جميع الأعمال نيابة عن المستخدم على سلسلة محادثات في الخلفية، حتى لا يتم حظر التطبيق الذي يعمل كمستخدم.

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