दिलचस्प पोस्ट
एचटीएमएल पासवर्ड फ़ील्ड के दिखाए प्रतीकों को बदलना क्या <STYLE> को एक HTML दस्तावेज़ के <HEAD> में होना चाहिए? पूर्णांक के लिए कारक कन्वर्ट पायथन के साथ विस्तार – सुपर () अजगर 3 बनाम अजगर 2 का उपयोग करना Quartz.Net नौकरी संग्रहण क्वेरी JSONP और jQuery के साथ PUT / POST / DELETE का उपयोग करना Punycode को डैश वर्ण के साथ यूनिकोड में परिवर्तित करना सीएसएस में सभी बाल तत्वों को बार-बार चुनें स्विफ्ट में एक शब्दकोश के मानचित्र () को लागू करने का सबसे साफ तरीका क्या है? विशिष्ट माइग्रेशन को कैसे रोलबैक करें? WIX में ग्रिड्स के लिए सिंटैक्स? मैं ServletFilter में ServletResponse से HTTP स्थिति कोड कैसे प्राप्त करूं? एंड्रॉइड: पिछले गतिविधि पर वापस जाएं एंड्रॉइड कैसे MediaScannerConnection scanFile का उपयोग करें सेनर्स और अस्थिर वस्तुओं के साथ शब्दकोश निर्माण। आश्चर्यजनक

एक Windows सेवा से क्रेडेंशियल के साथ एक प्रक्रिया शुरू

मेरे पास एक विंडोज सेवा है जो Mydomain \ userA के रूप में चलता है। मैं मनमाने ढंग से चलने में सक्षम होना चाहता हूं। आम तौर पर, मैं प्रोसेस। स्टार्ट () का उपयोग करता हूं और यह ठीक काम करता है, लेकिन कुछ मामलों में मैं निष्पादन योग्य को एक अलग उपयोगकर्ता (mydomain \ userB) के रूप में चलाने के लिए चाहता हूं।

अगर मैं प्रोसेसस्टार्ट इन्फोकेशन को बदलता हूं तो मैं क्रेडेंशियल्स को शामिल करने की प्रक्रिया शुरू करने के लिए उपयोग करता हूं, मैं त्रुटियों की शुरूआत करता हूं – या तो एक त्रुटि डायलॉग बॉक्स जो कहते हैं, "यह अनुप्रयोग ठीक से आरंभ करने में विफल रहा है (0xc0000142)।" अनुप्रयोग को समाप्त करने के लिए ओके पर क्लिक करें। "प्रवेश निषेध है" Win32Exception अगर मैं सेवा-प्रक्रिया कोड को सेवा में चलाने की बजाए कमांड लाइन से चलाता हूं, तो प्रक्रिया सही क्रेडेंशियल्स का उपयोग करना शुरू कर देती है (मैंने यह प्रक्रिया जो कि whoami.exe को चलाने के लिए और कमांड लाइन आउटपुट को कैप्चर करने के लिए किया है )।

मैंने भी WindowsIdentity.Impersonate () का उपयोग करने के लिए प्रतिरूपण की कोशिश की है, लेकिन यह काम नहीं कर रहा है – जैसा कि मैं समझता हूं, प्रतिरूपण केवल वर्तमान धागा को प्रभावित करता है, और एक नई प्रक्रिया शुरू करने से 'सुरक्षा डिस्क्रिप्टर प्रोसेस' होता है, वर्तमान थ्रेड नहीं

मैं इसे एक अलग परीक्षण डोमेन में चला रहा हूं, इसलिए उपयोगकर्ता ए और यूजर बी दोनों डोमेन एडमिन हैं, और इन दोनों के पास एक डोमेन के रूप में सेवा के रूप में लॉग ऑन है।

वेब के समाधान से एकत्रित समाधान "एक Windows सेवा से क्रेडेंशियल के साथ एक प्रक्रिया शुरू"

जब आप ProcessStartInfo का उपयोग करते हुए एक नई प्रक्रिया शुरू करते हैं, तो प्रक्रिया उसी विंडो स्टेशन और डेस्कटॉप में लॉन्च करने की प्रक्रिया के रूप में शुरू होती है। यदि आप विभिन्न क्रेडेंशियल्स का उपयोग कर रहे हैं तो उपयोगकर्ता सामान्य रूप से, उस डेस्कटॉप में चलाने के लिए पर्याप्त अधिकार नहीं होगा। त्रुटियों को प्रारंभ करने में विफलता का कारण बनता है जब user32.dll नई प्रक्रिया में प्रारंभ करने का प्रयास करता है और नहीं कर सकता

इसके चारों ओर पाने के लिए आपको पहली बार खिड़की स्टेशन और डेस्कटॉप से ​​जुड़े सुरक्षा डिस्क्रिप्टर्स को पुनर्प्राप्त करना होगा और अपने उपयोगकर्ता के लिए डीएसीएल के लिए उचित अनुमतियां जोड़नी चाहिए, फिर नई क्रेडेंशियल के तहत अपनी प्रक्रिया लॉन्च करें।

संपादित करें: यह कैसे और सैंपल कोड कैसे करें पर एक विस्तृत विवरण यहाँ के लिए थोड़ा लंबा था, इसलिए मैंने कोड के साथ एक लेख डाल दिया।

//The following security adjustments are necessary to give the new //process sufficient permission to run in the service's window station //and desktop. This uses classes from the AsproLock library also from //Asprosys. IntPtr hWinSta = GetProcessWindowStation(); WindowStationSecurity ws = new WindowStationSecurity(hWinSta, System.Security.AccessControl.AccessControlSections.Access); ws.AddAccessRule(new WindowStationAccessRule("LaunchProcessUser", WindowStationRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow)); ws.AcceptChanges(); IntPtr hDesk = GetThreadDesktop(GetCurrentThreadId()); DesktopSecurity ds = new DesktopSecurity(hDesk, System.Security.AccessControl.AccessControlSections.Access); ds.AddAccessRule(new DesktopAccessRule("LaunchProcessUser", DesktopRights.AllAccess, System.Security.AccessControl.AccessControlType.Allow)); ds.AcceptChanges(); EventLog.WriteEntry("Launching application.", EventLogEntryType.Information); using (Process process = Process.Start(psi)) { } 

@ स्टीफन मार्टिन द्वारा दिए गए उत्तर के आधार पर

Process क्लास का उपयोग करते हुए एक नई प्रक्रिया लॉन्च करने की Process में एक ही विंडो स्टेशन और डेस्कटॉप में चलती है। यदि आप अलग-अलग क्रेडेंशियल का उपयोग करते हुए नई प्रक्रिया चला रहे हैं, तो नई प्रक्रिया को विंडो स्टेशन और डेस्कटॉप तक पहुंचने की अनुमति नहीं होगी। 0xC0000142 जैसी त्रुटियों में क्या परिणाम है

एक उपयोगकर्ता को वर्तमान विंडो स्टेशन और डेस्कटॉप तक पहुंच प्रदान करने के लिए निम्नलिखित "कॉम्पैक्ट" स्टैंडअलोन कोड है। इसमें एस्पो-लॉक पुस्तकालय की आवश्यकता नहीं है।

 public static void GrantAccessToWindowStationAndDesktop(string username) { const int WindowStationAllAccess = 0x000f037f; GrantAccess(username, GetProcessWindowStation(), WindowStationAllAccess); const int DesktopRightsAllAccess = 0x000f01ff; GrantAccess(username, GetThreadDesktop(GetCurrentThreadId()), DesktopRightsAllAccess); } private static void GrantAccess(string username, IntPtr handle, int accessMask) { SafeHandle safeHandle = new NoopSafeHandle(handle); GenericSecurity security = new GenericSecurity( false, ResourceType.WindowObject, safeHandle, AccessControlSections.Access); security.AddAccessRule( new GenericAccessRule( new NTAccount(username), accessMask, AccessControlType.Allow)); security.Persist(safeHandle, AccessControlSections.Access); } [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetProcessWindowStation(); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetThreadDesktop(int dwThreadId); [DllImport("kernel32.dll", SetLastError = true)] private static extern int GetCurrentThreadId(); // All the code to manipulate a security object is available in .NET framework, // but its API tries to be type-safe and handle-safe, enforcing a special implementation // (to an otherwise generic WinAPI) for each handle type. This is to make sure // only a correct set of permissions can be set for corresponding object types and // mainly that handles do not leak. // Hence the AccessRule and the NativeObjectSecurity classes are abstract. // This is the simplest possible implementation that yet allows us to make use // of the existing .NET implementation, sparing necessity to // P/Invoke the underlying WinAPI. private class GenericAccessRule : AccessRule { public GenericAccessRule( IdentityReference identity, int accessMask, AccessControlType type) : base(identity, accessMask, false, InheritanceFlags.None, PropagationFlags.None, type) { } } private class GenericSecurity : NativeObjectSecurity { public GenericSecurity( bool isContainer, ResourceType resType, SafeHandle objectHandle, AccessControlSections sectionsRequested) : base(isContainer, resType, objectHandle, sectionsRequested) { } new public void Persist(SafeHandle handle, AccessControlSections includeSections) { base.Persist(handle, includeSections); } new public void AddAccessRule(AccessRule rule) { base.AddAccessRule(rule); } #region NativeObjectSecurity Abstract Method Overrides public override Type AccessRightType { get { throw new NotImplementedException(); } } public override AccessRule AccessRuleFactory( System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) { throw new NotImplementedException(); } public override Type AccessRuleType { get { return typeof(AccessRule); } } public override AuditRule AuditRuleFactory( System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) { throw new NotImplementedException(); } public override Type AuditRuleType { get { return typeof(AuditRule); } } #endregion } // Handles returned by GetProcessWindowStation and GetThreadDesktop should not be closed private class NoopSafeHandle : SafeHandle { public NoopSafeHandle(IntPtr handle) : base(handle, false) { } public override bool IsInvalid { get { return false; } } protected override bool ReleaseHandle() { return true; } } 

यह लक्षण है:
– अपर्याप्त अधिकार;
– एक पुस्तकालय का विफलता लोड;

कुछ प्रवेश निषेध का पता लगाने के लिए Filemon का उपयोग करें या
डिबगर में एप्लिकेशन को चलाने और किसी भी मुद्दे को देखने के लिए WinDbg।

@ स्टीफन मार्टिन और मार्टिन प्रीक्रिल द्वारा दिए गए उत्तर के आधार पर

यह कोड आपको सेवा से भिन्न उपयोगकर्ता क्रेडेंशियल के साथ एक प्रक्रिया चलाने में मदद करता है।
मैंने अब स्रोत कोड को अनुकूलित किया है
अधिकारों को हटाने और सेटिंग अब भी संभव है।

 namespace QlikConnectorPSExecute { #region Usings using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.Security.Principal; #endregion //inspired by: http://stackoverflow.com/questions/677874/starting-a-process-with-credentials-from-a-windows-service public class WindowsGrandAccess : IDisposable { #region DLL-Import // All the code to manipulate a security object is available in .NET framework, // but its API tries to be type-safe and handle-safe, enforcing a special implementation // (to an otherwise generic WinAPI) for each handle type. This is to make sure // only a correct set of permissions can be set for corresponding object types and // mainly that handles do not leak. // Hence the AccessRule and the NativeObjectSecurity classes are abstract. // This is the simplest possible implementation that yet allows us to make use // of the existing .NET implementation, sparing necessity to // P/Invoke the underlying WinAPI. [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetProcessWindowStation(); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetThreadDesktop(int dwThreadId); [DllImport("kernel32.dll", SetLastError = true)] private static extern int GetCurrentThreadId(); #endregion #region Variables && Properties public static int WindowStationAllAccess { get; private set; } = 0x000f037f; public static int DesktopRightsAllAccess { get; private set; } = 0x000f01ff; private GenericSecurity WindowStationSecurity {get; set;} private GenericSecurity DesktopSecurity { get; set; } private int? OldWindowStationMask { get; set; } private int? OldDesktopMask { get; set; } private NTAccount AccountInfo { get; set; } private SafeHandle WsSafeHandle { get; set; } private SafeHandle DSafeHandle { get; set; } #endregion #region Constructor & Dispose public WindowsGrandAccess(NTAccount accountInfo, int windowStationMask, int desktopMask) { if (accountInfo != null) Init(accountInfo, windowStationMask, desktopMask); } public void Dispose() { try { if (AccountInfo == null) return; RestAccessMask(OldWindowStationMask, WindowStationAllAccess, WindowStationSecurity, WsSafeHandle); RestAccessMask(OldDesktopMask, DesktopRightsAllAccess, DesktopSecurity, DSafeHandle); } catch (Exception ex) { throw new Exception($"The object \"{nameof(WindowsGrandAccess)}\" could not be dispose.", ex); } } #endregion #region Methods private void Init(NTAccount accountInfo, int windowStationMask, int desktopMask) { AccountInfo = accountInfo; WsSafeHandle = new NoopSafeHandle(GetProcessWindowStation()); WindowStationSecurity = new GenericSecurity(false, ResourceType.WindowObject, WsSafeHandle, AccessControlSections.Access); DSafeHandle = new NoopSafeHandle(GetThreadDesktop(GetCurrentThreadId())); DesktopSecurity = new GenericSecurity(false, ResourceType.WindowObject, DSafeHandle, AccessControlSections.Access); OldWindowStationMask = ReadAccessMask(WindowStationSecurity, WsSafeHandle, windowStationMask); OldDesktopMask = ReadAccessMask(DesktopSecurity, DSafeHandle, desktopMask); } private AuthorizationRuleCollection GetAccessRules(GenericSecurity security) { return security.GetAccessRules(true, false, typeof(NTAccount)); } private int? ReadAccessMask(GenericSecurity security, SafeHandle safeHandle, int accessMask) { var ruels = GetAccessRules(security); var username = AccountInfo.Value; if (!username.Contains("\\")) username = $"{Environment.MachineName}\\{username}"; var userResult = ruels.Cast<GrantAccessRule>().SingleOrDefault(r => r.IdentityReference.Value.ToLower() == username.ToLower() && accessMask == r.PublicAccessMask); if (userResult == null) { AddGrandAccess(security, accessMask, safeHandle); userResult = ruels.Cast<GrantAccessRule>().SingleOrDefault(r => r.IdentityReference.Value.ToLower() == username.ToLower()); if (userResult != null) return userResult.PublicAccessMask; } else return userResult.PublicAccessMask; return null; } private void AddGrandAccess(GenericSecurity security, int accessMask, SafeHandle safeHandle) { var rule = new GrantAccessRule(AccountInfo, accessMask, AccessControlType.Allow); security.AddAccessRule(rule); security.Persist(safeHandle, AccessControlSections.Access); } private void RemoveGrantAccess(GenericSecurity security, int accessMask, SafeHandle safeHandle) { var rule = new GrantAccessRule(AccountInfo, accessMask, AccessControlType.Allow); security.RemoveAccessRule(rule); security.Persist(safeHandle, AccessControlSections.Access); } private void SetGrandAccess(GenericSecurity security, int accessMask, SafeHandle safeHandle) { var rule = new GrantAccessRule(AccountInfo, accessMask, AccessControlType.Allow); security.SetAccessRule(rule); security.Persist(safeHandle, AccessControlSections.Access); } private void RestAccessMask(int? oldAccessMask, int fullAccessMask, GenericSecurity security, SafeHandle safeHandle) { if (oldAccessMask == null) RemoveGrantAccess(security, fullAccessMask, safeHandle); else if (oldAccessMask != fullAccessMask) { SetGrandAccess(security, oldAccessMask.Value, safeHandle); } } #endregion #region private classes private class GenericSecurity : NativeObjectSecurity { public GenericSecurity( bool isContainer, ResourceType resType, SafeHandle objectHandle, AccessControlSections sectionsRequested) : base(isContainer, resType, objectHandle, sectionsRequested) { } new public void Persist(SafeHandle handle, AccessControlSections includeSections) { base.Persist(handle, includeSections); } new public void AddAccessRule(AccessRule rule) { base.AddAccessRule(rule); } new public bool RemoveAccessRule(AccessRule rule) { return base.RemoveAccessRule(rule); } new public void SetAccessRule(AccessRule rule) { base.SetAccessRule(rule); } new public AuthorizationRuleCollection GetAccessRules(bool includeExplicit, bool includeInherited, Type targetType) { return base.GetAccessRules(includeExplicit, includeInherited, targetType); } public override Type AccessRightType { get { throw new NotImplementedException(); } } public override AccessRule AccessRuleFactory( System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) { return new GrantAccessRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, type); } public override Type AccessRuleType { get { return typeof(AccessRule); } } public override AuditRule AuditRuleFactory( System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) { throw new NotImplementedException(); } public override Type AuditRuleType { get { return typeof(AuditRule); } } } private class GrantAccessRule : AccessRule { public GrantAccessRule(IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) : base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, type) { } public GrantAccessRule(IdentityReference identity, int accessMask, AccessControlType type) : base(identity, accessMask, false, InheritanceFlags.None, PropagationFlags.None, type) { } public int PublicAccessMask { get { return base.AccessMask; } } } // Handles returned by GetProcessWindowStation and GetThreadDesktop should not be closed private class NoopSafeHandle : SafeHandle { public NoopSafeHandle(IntPtr handle) : base(handle, false) {} public override bool IsInvalid { get { return false; } } protected override bool ReleaseHandle() { return true; } } #endregion } } 

नमूना का उपयोग करना

 using (var windowsAccess = new WindowsGrandAccess(accountInfo, WindowsGrandAccess.WindowStationAllAccess, WindowsGrandAccess.DesktopRightsAllAccess)) { ... } 

धन्यवाद।

आप डोमेन, उपयोगकर्ता और पासवर्ड कैसे सेट कर रहे हैं? क्या आप डोमेन को ठीक से पासवर्ड के रूप में निर्धारित कर रहे हैं (यह एक सेक्योरस्ट्रिंग का उपयोग करना चाहिए)

इसके अलावा, क्या आप वर्किंग डायरेक्टरी संपत्ति को निर्धारित कर रहे हैं? उपयोगकर्ता नाम और पासवर्ड का उपयोग करते समय, दस्तावेज़ीकरण बताता है कि आपको वर्किंग डायरेक्टरी संपत्ति सेट करना होगा।

यह हो सकता है कि सेवा द्वारा किसी भी प्रक्रिया को लात मारने के लिए "सेवा के रूप में प्रवेश करें" पुरस्कार भी होना चाहिए।

यदि उपयोगकर्ता आईडी जिसे आप दूसरी प्रक्रिया शुरू करने के लिए उपयोग कर रहे हैं, तो बॉक्स में व्यवस्थापकीय अधिकार नहीं हैं, तो ऐसा हो सकता है।

उपयोगकर्ता सुरक्षा "सेवा के रूप में प्रवेश करें" देने के लिए स्थानीय सुरक्षा नीति को बदलने के लिए एक आसान परीक्षण होगा और फिर से प्रयास करें

संपादित करें: अतिरिक्त जानकारी के बाद ..

इस पर Google पर चराई, ऐसा प्रतीत होता है कि 0xc0000142 एक आवश्यक DLL को प्रारंभ करने में सक्षम नहीं होने से संबंधित है। क्या ऐसा कुछ है जो सेवा खुला है कि पैदा की गई प्रक्रिया की आवश्यकता है? किसी भी स्थिति में, ऐसा लगता है कि उस प्रक्रिया के साथ क्या करना है जिसे हटा दिया गया है, और यह नहीं कि आप यह कैसे कर रहे हैं।

आज मुझे इस समस्या थी, और मैंने इसे समझने की कोशिश करने में कुछ समय बिताया। मैं क्या कर रहा हूं, सेवा को इंटरैक्टिव (सेवाओं की डेस्कटॉप चेकबॉक्स के साथ इंटरैक्ट करने के लिए सेवाओं की अनुमति का उपयोग करके। एमएससी) बनाने के लिए किया गया था। जैसे ही मैंने ऐसा किया, 0xc0000142 त्रुटियां दूर चली गईं।