2010-03-11 14 views
14

मैं एक तृतीय पक्ष Windows सेवा है कि CreateProcessAsUser का उपयोग कर स्क्रिप्ट और निष्पादनयोग्य चलाकर कुछ स्वचालन कार्यों को संभालती है() का उपयोग कर रहा से एक यूएसी ऊंचा प्रक्रिया शुरू करने से। मैं यूएसी और जिस तरह की वजह से विंडोज सर्वर 2008 पर समस्याओं LUA ऊंचाई APIs के माध्यम से नियंत्रित किया जाता है में चल रहा हूँ।एक गैर-सहभागी सेवा (Win32/.net/powershell)

सेवा LocalSystem के रूप में चलाता है और "डेस्कटॉप साथ सहभागिता करें" सक्षम नहीं है। प्रक्रियाओं प्रशासक समूह में उपयोगकर्ताओं के रूप में चलाए जा रहे हैं किया जा रहा है, लेकिन नहीं व्यवस्थापक खाते (जो कई यूएसी प्रतिबंध से छूट दी गई है)। जगह में सभी यूएसी डिफ़ॉल्ट सेटिंग्स।

मैं सेवा के लिए मनमानी आदेश या पावरहेल कोड पास कर सकता हूं, लेकिन मैं गैर-उन्नत, गैर-इंटरैक्टिव प्रक्रिया को 'ब्रेक आउट' नहीं कर सकता जो सेवा द्वारा लात मारता है।

इस मुद्दे का क्रूक्स ऐसा लगता है कि एक उन्नत प्रक्रिया शुरू करने के लिए एकमात्र (सार्वजनिक) एपीआई विकल्प 'रनस' क्रिया के साथ ShellExecute() है, लेकिन जहां तक ​​मैं कह सकता हूं कि इसे नहीं कहा जा सकता एक गैर-संवादात्मक सेवा या आपको "इस ऑपरेशन को एक इंटरैक्टिव विंडो स्टेशन की आवश्यकता होती है" जैसी त्रुटियां मिलती हैं।

केवल वैकल्पिक हल मैंने पाया यहाँ उल्लेख किया जाता है: http://www.eggheadcafe.com/software/aspnet/29620442/how-to-proper-use-sendinp.aspx

Vista में, सरकारी दस्तावेज रास्ता एक प्रक्रिया ऊंचे होने का केवल खोल एपीआई ShellExecute (पूर्व) का उपयोग किया जाता है (नहीं CreateProcess या CreateProcessAsUser)। तो आपके आवेदन ShellExecute (पूर्व) कॉल करना होगा एक सहायक SendInput कॉल करने के लिए शुरू करने के लिए ऊपर उठाया। इसके अलावा, कारण सत्र के लिए 0 अलगाव, एक सेवा केवल CreateProcessAsUser या CreateProcessWithLogonW का उपयोग करें ( ShellExecute (पूर्व) का उपयोग नहीं कर सकते हैं) इंटरैक्टिव डेस्कटॉप निर्दिष्ट करने के लिए कर सकते हैं।

.. मुझे लगता है कि विंडोज सेवा से एक उन्नत प्रक्रिया को हल करने का कोई सीधा तरीका नहीं है। हम पहले CreateProcessAsUser या CreateProcessWithLogonW को उपयोगकर्ता सत्र (इंटरैक्टिव डेस्कटॉप) में गैर-उन्नत प्रक्रिया को बढ़ाने के लिए पहले उपयोग कर सकते हैं। फिर गैर-उन्नत प्रक्रिया में, यह वास्तविक कार्य के लिए प्रक्रिया को बढ़ाने के लिए शैलएक्सक्यूट (पूर्व) का उपयोग कर सकता है।

.net/powershell कोड से ऐसा करने के लिए, ऐसा लगता है कि मैं/कुछ विस्तृत पी कर दिया था सामान नेट System.Diagnostics.ProcessStartInfo के बाद से CreateProcessAsUser या CreateProcessWithLogonW कॉल करने के लिए एक नहीं है आह्वान lpDesktop के बराबर है कि मैं "winsta0 \ default" पर सेट कर सकता हूं। और मैं अगर स्थानीय सिस्टम भी CreateProcessAsUser या CreateProcessWithLogonW कॉल करने के लिए अधिकार है पर स्पष्ट नहीं कर रहा हूँ।

मैं भी http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx और Process.Start with different credentials with UAC on

सब उस आधार पर को देखा, मैं इस निष्कर्ष है कि वहाँ यह करने के लिए कोई सीधा रास्ता तक पहुंच गया हूँ। क्या मैं कुछ भूल रहा हूँ? यह वास्तव में ऐसा प्रतीत नहीं होता है कि यह इतना कठिन होना चाहिए। ऐसा लगता है कि यूएसी को गैर-इंटरैक्टिव उपयोग मामलों को संभालने के लिए कभी डिजाइन नहीं किया गया था।

और यदि कोई माइक्रोसॉफ्ट लोग इसे पढ़ना समाप्त कर देते हैं, तो मैंने देखा कि शैलएक्सक्यूट आंतरिक रूप से ऊंचाई को संभालने का तरीका एप्लिकेशन सूचना सेवा (एआईएस) को बुलाकर है। कुछ Win32 या .NET API के माध्यम से एआईएस को एक ही कॉल क्यों उपलब्ध नहीं है? http://msdn.microsoft.com/en-us/library/bb756945.aspx

क्षमा करें कि थोड़ा सा भाग गया। किसी भी विचार के लिए धन्यवाद।

+0

बल्कि यह बताते हुए कि सर्वर कोर यूएसी का समर्थन नहीं करता है। मेरे मूल्यांकन की पुष्टि करने के लिए लगता है। http://blogs.technet.com/server_core/archive/2009/01/19/user-account-control-uac-and-server-core.aspx –

+0

मेरी पोस्ट यहां देखें जो बताती है कि, विशेष रूप से लिंक्ड टोकन को कैसे देखें खंड: http://brianbondy.com/blog/id/100/understanding-windows-at-a-deeper-level-sessions-window-stations-and-desktops –

उत्तर

16

सत्र शून्य अलगाव तोड़ने का "आधिकारिक" तरीका टर्मिनल सेवाओं एपीआई और CreateProcessAsUser() के संयोजन का उपयोग उपयोगकर्ता के सत्र में प्रक्रिया शुरू करने के लिए करना है। मेरी पुरानी नौकरी पर, हमने बस यही किया, क्योंकि हमें डाउनलोड किए गए अपडेट को इंस्टॉल करने से पहले किसी सेवा से उपयोगकर्ता को एक संवाद प्रदर्शित करने की आवश्यकता थी, इसलिए मुझे पता है कि यह WinXP, Win2K3, Vista और Win7 पर कम से कम काम करता है, लेकिन मैं उम्मीद नहीं है कि विन 2 के 8 बहुत अलग होगा। (बहुत महत्वपूर्ण है, इंटरैक्टिव सत्र सत्र 1 के रूप में नहीं हमेशा की तरह, यहां तक ​​कि ग्राहक सिस्टम पर)

  1. कॉल WTSGetActiveConsoleSessionId() सक्रिय कंसोल सत्र id पाने के लिए: मूल रूप से, प्रक्रिया इस प्रकार है। यह एपीआई एक -1 भी वापस कर देगा यदि इंटरैक्टिव सत्र में लॉग इन कोई सक्रिय उपयोगकर्ता नहीं है (यानी, स्थानीय रूप से भौतिक मशीन में लॉग इन किया गया है, आरडीपी का उपयोग करने के विपरीत)।
  2. पिछले एपीआई कॉल से सत्र आईडी को WTSQueryUserToken() पर एक खुले टोकन प्राप्त करने के लिए पास करें जो उपयोगकर्ता को कंसोल में लॉग इन करता है।
  3. प्रतिरूपण टोकन (WTSQueryUserToken से) को प्राथमिक टोकन में बदलने के लिए DuplicateTokenEx() पर कॉल करें।
  4. प्रक्रिया के लिए एक नया वातावरण बनाने के लिए CreateEnvironmentBlock() पर कॉल करें (वैकल्पिक, लेकिन यदि आप नहीं करते हैं, तो प्रक्रिया में एक नहीं होगा)।
  5. निष्पादन योग्य के लिए कमांड लाइन के साथ चरण # 3 से प्राथमिक टोकन को CreateProccessAsUser() पर कॉल करें। यदि आपने चरण # 4 से पर्यावरण ब्लॉक बनाया है, तो आपको CREATE_UNICODE_ENVIRONMENT ध्वज को हमेशा (हमेशा) पास करना होगा। यह मूर्खतापूर्ण प्रतीत हो सकता है, लेकिन यदि आप नहीं करते हैं तो एपीआई बहुत खराब हो जाती है (ERROR_INVALID_PARAMTER के साथ)।
  6. यदि आपने पर्यावरण ब्लॉक बनाया है, तो आपको DestroyEnvironmentBlock पर कॉल करने की आवश्यकता है, अन्यथा आप मेमोरी लीक उत्पन्न करेंगे। प्रक्रिया को लॉन्च होने पर पर्यावरण ब्लॉक की एक अलग प्रति दी जाती है, इसलिए आप केवल स्थानीय डेटा को नष्ट कर रहे हैं।

और voila! विंडोज कुछ आंतरिक जादू करता है, और आप एप्लिकेशन लॉन्च देखते हैं। हालांकि, हालांकि यह एक सेवा से लॉन्च और इंटरैक्टिव प्रक्रिया करेगा, मुझे यकीन नहीं है कि यह यूएसी को बाईपास करेगा (लेकिन मुझे उस पर उद्धरण न दें)। दूसरे शब्दों में, यह एक उन्नत प्रक्रिया के रूप में लॉन्च नहीं हो सकता है जब तक रजिस्ट्री या आंतरिक मैनिफेस्ट ऐसा करने के लिए कहता है, और फिर भी, आपको अभी भी एक यूएसी प्रॉम्प्ट मिल जाएगा। यदि चरण # 3 से प्राप्त टोकन एक प्रतिबंधित टोकन है, तो आप ऊंचे (पूर्ण) टोकन को पुनर्स्थापित करने के लिए AdjustTokenPrivileges() का उपयोग करने में सक्षम हो सकते हैं, लेकिन मुझे उस पर उद्धरण न दें। हालांकि, जैसा कि एमएसडीएन दस्तावेज़ों में बताया गया है, कृपया ध्यान दें कि उन टोकन पर विशेषाधिकार "जोड़ना" संभव नहीं है, जिनके पास पहले से नहीं है (उदाहरण के लिए आप AdjustTokenPrivileges का उपयोग करके एक प्रतिबंधित उपयोगकर्ता टोकन को व्यवस्थापक में नहीं बदल सकते हैं; अंतर्निहित उपयोगकर्ता के साथ शुरू करने के लिए एक व्यवस्थापक होना होगा)।

यह Win2K आगे से यह सब करने के लिए तकनीकी रूप से संभव है। हालांकि, यह WinXP के साथ वास्तव में केवल व्यवहार्य है, क्योंकि Win2K में WTSGetActiveConsoleSessionId() और WTSQueryUserToken() एपीआई (Win12K Pro के लिए WTSEnumerateProcesses() के साथ) की कमी है। आप सत्र आईडी के रूप में हार्ड कोड 0 कर सकते हैं (क्योंकि यह हमेशा Win2K में होता है), और मुझे लगता है कि आप चल रहे प्रक्रियाओं को गिनती करके और उनके टोकन में से एक को डुप्लिकेट करके उपयोगकर्ता टोकन प्राप्त करने में सक्षम हो सकते हैं (यह एक होना चाहिए इंटरैक्टिव एसआईडी उपस्थित)।भले ही CreateProcessAsUser() एक इंटरैक्टिव उपयोगकर्ता टोकन पारित करने के समान व्यवहार करेगा, भले ही आप सेवा सेटिंग्स से "डेस्कटॉप के साथ इंटरैक्ट" का चयन न करें। यह वैसे भी सेवा से सीधे लॉन्च करने से भी अधिक सुरक्षित है, क्योंकि प्रक्रिया ईश्वरीय LocalSystem एक्सेस टोकन का वारिस नहीं करेगी।

अब, मुझे नहीं पता कि आपका तीसरा पक्ष ऐप स्क्रिप्ट/प्रक्रिया चलाते समय इनमें से कोई भी करता है, लेकिन यदि आप इसे किसी सेवा से करना चाहते हैं, तो यह है (और Vista या Win7 के साथ, यह है सत्र 0 अलगाव को दूर करने का एकमात्र तरीका)।

+3

'डुप्लिकेट टोकनएक्स' को कॉल करने की कोई आवश्यकता नहीं है। 'CreateProcessAsUser'' WTSQueryUserToken' से प्राप्त टोकन के साथ प्रक्रिया को चलाएगा। आपका उत्तर काफी विस्तृत है, लेकिन जवाब नहीं देता है "सेवा से उन्नत प्रक्रिया कैसे शुरू करें? (यूएसी सक्षम)" – Ajay

+1

वास्तव में यह नहीं है। यह आपको एक प्रतिबंधित टोकन के साथ छोड़ देगा। – Joshua

+0

कुछ बातें ध्यान देने योग्य हैं: 1) जैसा कि @Ajay का उल्लेख है 'WTSQueryUserToken' पहले से ही एक प्राथमिक टोकन देता है, इसलिए आप चरण 3 छोड़ सकते हैं। 2) यूएसी सक्षम होने के साथ आपको वास्तव में चरण 2 के बाद तथाकथित लिंक टोकन प्राप्त करने की आवश्यकता है , जिसे आप 'टोकन लिंक्ड टोकन 'सूचना वर्ग के साथ' GetTokenInformation' 'पर कॉल करके करते हैं, लेकिन केवल तभी' टोकन एलिवेशन टाइप 'से पूछताछ करने पर कहा जाता है कि ऊंचाई सीमित है। 3) यदि आप पर्यावरण ब्लॉक नहीं बनाते हैं तो नई प्रक्रिया में निर्माण प्रक्रिया का माहौल होगा, जो आपकी सेवा है –

1

आपके उपयोग के मामले के आधार पर, आप जो भी कर सकते हैं वह कर सकते हैं। मैं सक्रिय सत्र के लिए winlogon प्रक्रिया का शिकार और इसके टोकन चोरी। यदि कोई सक्रिय सत्र नहीं है (API वापस लौटाया गया है), तो 1 का उपयोग करें यदि WINVER> = 6 अन्यथा 0. सक्रिय सत्र पर सिस्टम में इसका परिणाम होता है।