2010-01-19 12 views
5

बनाने का विशेषाधिकार है, मैं प्रोग्रामेटिक रूप से यह निर्धारित करना चाहता हूं कि वर्तमान उपयोगकर्ता (या प्रक्रिया) के पास प्रतीकात्मक लिंक बनाने के लिए पहुंच है या नहीं। विंडोज़ (विस्टा और अधिक) में, कोई SeCreateSymbolicLinkPrivilege के बिना एक प्रतीकात्मक लिंक नहीं बना सकता है और डिफ़ॉल्ट रूप से, यह केवल प्रशासकों को असाइन किया जाता है। यदि कोई इस विशेषाधिकार के बिना एक प्रतीकात्मक लिंक बनाने का प्रयास करता है, तो Windows त्रुटि 1314 (क्लाइंट द्वारा आवश्यक आवश्यक विशेषाधिकार) होता है।निर्धारित करें कि क्या विंडोज प्रक्रिया को प्रतीकात्मक लिंक

इस प्रतिबंध को प्रदर्शित करने के लिए, मैंने प्रारंभिक व्यवस्थापक खाते (यूएसी के माध्यम से प्रतिबंधित) के रूप में लॉग इन किया, विंडोज़ का एक साफ इंस्टॉल बनाया, और घर निर्देशिका में एक सिम्लिंक बनाने में असमर्थ था।

Command Prompt demonstrates mklink fails due to insufficient privilege

प्रशासक के रूप में कमांड प्रॉम्प्ट चल रहे हैं या यूएसी अक्षम करने के बाद, कि आदेश त्रुटि के बिना निष्पादित करता है।

this article के अनुसार, "उपयोगकर्ता की तरफ से निष्पादित हर प्रक्रिया में [एक्सेस] टोकन की एक प्रति है"।

इसलिए मैंने a Python script to query for the permissions बनाया है। सुविधा और वंशावली के लिए, मैं नीचे एक अंश शामिल करता हूं।

स्क्रिप्ट के पीछे विचार सभी विशेषाधिकारों का आकलन करना है और यह निर्धारित करना है कि प्रक्रिया के लिए आवश्यक विशेषाधिकार है या नहीं। दुर्भाग्यवश, मुझे लगता है कि वर्तमान प्रक्रिया में वांछित विशेषाधिकार नहीं है, भले ही यह सिम्लिंक बना सके।

मुझे संदेह है कि समस्या यह है कि वर्तमान उपयोगकर्ता के विशेषाधिकारों में विशेषाधिकार शामिल नहीं है, फिर भी उनकी समूह सदस्यता उस विशेषाधिकार को बर्दाश्त करती है।

संक्षेप में, मैं कैसे निर्धारित कर सकता हूं कि किसी दिए गए प्रक्रिया को प्रतीकात्मक लिंक बनाने के लिए विशेषाधिकार मिलेगा (बिना किसी बनाने के प्रयास किए)? सी या सी ++ या पायथन में एक उदाहरण पसंद किया जाता है, हालांकि विंडोज एपीआई का उपयोग करने वाला कुछ भी उपयुक्त होगा।

def get_process_token(): 
    token = wintypes.HANDLE() 
    TOKEN_ALL_ACCESS = 0xf01ff 
    res = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token) 
    if not res > 0: raise RuntimeError("Couldn't get process token") 
    return token 

def get_privilege_information(): 
    # first call with zero length to determine what size buffer we need 

    return_length = wintypes.DWORD() 
    params = [ 
     get_process_token(), 
     TOKEN_INFORMATION_CLASS.TokenPrivileges, 
     None, 
     0, 
     return_length, 
     ] 

    res = GetTokenInformation(*params) 

    # assume we now have the necessary length in return_length 

    buffer = ctypes.create_string_buffer(return_length.value) 
    params[2] = buffer 
    params[3] = return_length.value 

    res = GetTokenInformation(*params) 
    assert res > 0, "Error in second GetTokenInformation (%d)" % res 

    privileges = ctypes.cast(buffer, ctypes.POINTER(TOKEN_PRIVILEGES)).contents 
    return privileges 

privileges = get_privilege_information() 
print("found {0} privileges".format(privileges.count)) 
map(print, privileges) 
+0

विंडोज के प्रतीकात्मक लिंक हैं? –

+2

आप किस प्रकार का प्रतीकात्मक लिंक बनाने की कोशिश कर रहे हैं? विभिन्न चीजों का एक गुच्छा है जिसे विंडोज़ में प्रतीकात्मक लिंक माना जा सकता है - फाइल सिस्टम जंक्शन अंक, फाइल सिस्टम हार्ड लिंक, ऑब्जेक्ट मैनेजर प्रतीकात्मक लिंक इत्यादि। मुझे विश्वास है कि आपको ऑब्जेक्ट मैनेजर प्रतीकात्मक लिंक बनाने के लिए केवल SeCreateSymbolicLink विशेषाधिकार की आवश्यकता है। –

+0

मैं फाइल सिस्टम जंक्शन-पॉइंट-आधारित प्रतीकात्मक लिंक बनाने की कोशिश कर रहा हूं, जैसे CreateSymbolicLink द्वारा बनाए गए। –

उत्तर

4

मुझे एक समाधान मिला। निम्न पायथन कोड पायथन 2.6 या 3.1 के तहत एक पूर्ण-कार्यात्मक स्क्रिप्ट है जो दर्शाता है कि कोई सिम्लिंक बनाने के विशेषाधिकार को कैसे निर्धारित कर सकता है। प्रशासक खाते के तहत इसे चलाने से सफलता मिलती है, और अतिथि खाते के तहत इसे चलाने में विफलता के साथ प्रतिक्रिया होती है।

नोट, स्क्रिप्ट का पहला 3/4 ज्यादातर एपीआई परिभाषा है। उपन्यास कार्य get_process_token() के साथ शुरू होता है।

from __future__ import print_function 
import ctypes 
from ctypes import wintypes 

GetCurrentProcess = ctypes.windll.kernel32.GetCurrentProcess 
GetCurrentProcess.restype = wintypes.HANDLE 
OpenProcessToken = ctypes.windll.advapi32.OpenProcessToken 
OpenProcessToken.argtypes = (wintypes.HANDLE, wintypes.DWORD, ctypes.POINTER(wintypes.HANDLE)) 
OpenProcessToken.restype = wintypes.BOOL 

class LUID(ctypes.Structure): 
    _fields_ = [ 
     ('low_part', wintypes.DWORD), 
     ('high_part', wintypes.LONG), 
     ] 

    def __eq__(self, other): 
     return (
      self.high_part == other.high_part and 
      self.low_part == other.low_part 
      ) 

    def __ne__(self, other): 
     return not (self==other) 

LookupPrivilegeValue = ctypes.windll.advapi32.LookupPrivilegeValueW 
LookupPrivilegeValue.argtypes = (
    wintypes.LPWSTR, # system name 
    wintypes.LPWSTR, # name 
    ctypes.POINTER(LUID), 
    ) 
LookupPrivilegeValue.restype = wintypes.BOOL 

class TOKEN_INFORMATION_CLASS: 
    TokenUser = 1 
    TokenGroups = 2 
    TokenPrivileges = 3 
    # ... see http://msdn.microsoft.com/en-us/library/aa379626%28VS.85%29.aspx 

SE_PRIVILEGE_ENABLED_BY_DEFAULT = (0x00000001) 
SE_PRIVILEGE_ENABLED   = (0x00000002) 
SE_PRIVILEGE_REMOVED   = (0x00000004) 
SE_PRIVILEGE_USED_FOR_ACCESS = (0x80000000) 

class LUID_AND_ATTRIBUTES(ctypes.Structure): 
    _fields_ = [ 
     ('LUID', LUID), 
     ('attributes', wintypes.DWORD), 
     ] 

    def is_enabled(self): 
     return bool(self.attributes & SE_PRIVILEGE_ENABLED) 

    def enable(self): 
     self.attributes |= SE_PRIVILEGE_ENABLED 

    def get_name(self): 
     size = wintypes.DWORD(10240) 
     buf = ctypes.create_unicode_buffer(size.value) 
     res = LookupPrivilegeName(None, self.LUID, buf, size) 
     if res == 0: raise RuntimeError 
     return buf[:size.value] 

    def __str__(self): 
     res = self.get_name() 
     if self.is_enabled(): res += ' (enabled)' 
     return res 

LookupPrivilegeName = ctypes.windll.advapi32.LookupPrivilegeNameW 
LookupPrivilegeName.argtypes = (
    wintypes.LPWSTR, # lpSystemName 
    ctypes.POINTER(LUID), # lpLuid 
    wintypes.LPWSTR, # lpName 
    ctypes.POINTER(wintypes.DWORD), #cchName 
    ) 
LookupPrivilegeName.restype = wintypes.BOOL 

class TOKEN_PRIVILEGES(ctypes.Structure): 
    _fields_ = [ 
     ('count', wintypes.DWORD), 
     ('privileges', LUID_AND_ATTRIBUTES*0), 
     ] 

    def get_array(self): 
     array_type = LUID_AND_ATTRIBUTES*self.count 
     privileges = ctypes.cast(self.privileges, ctypes.POINTER(array_type)).contents 
     return privileges 

    def __iter__(self): 
     return iter(self.get_array()) 

PTOKEN_PRIVILEGES = ctypes.POINTER(TOKEN_PRIVILEGES) 

GetTokenInformation = ctypes.windll.advapi32.GetTokenInformation 
GetTokenInformation.argtypes = [ 
    wintypes.HANDLE, # TokenHandle 
    ctypes.c_uint, # TOKEN_INFORMATION_CLASS value 
    ctypes.c_void_p, # TokenInformation 
    wintypes.DWORD, # TokenInformationLength 
    ctypes.POINTER(wintypes.DWORD), # ReturnLength 
    ] 
GetTokenInformation.restype = wintypes.BOOL 

# http://msdn.microsoft.com/en-us/library/aa375202%28VS.85%29.aspx 
AdjustTokenPrivileges = ctypes.windll.advapi32.AdjustTokenPrivileges 
AdjustTokenPrivileges.restype = wintypes.BOOL 
AdjustTokenPrivileges.argtypes = [ 
    wintypes.HANDLE,    # TokenHandle 
    wintypes.BOOL,     # DisableAllPrivileges 
    PTOKEN_PRIVILEGES,    # NewState (optional) 
    wintypes.DWORD,     # BufferLength of PreviousState 
    PTOKEN_PRIVILEGES,    # PreviousState (out, optional) 
    ctypes.POINTER(wintypes.DWORD), # ReturnLength 
    ] 

def get_process_token(): 
    """ 
    Get the current process token 
    """ 
    token = wintypes.HANDLE() 
    TOKEN_ALL_ACCESS = 0xf01ff 
    res = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token) 
    if not res > 0: raise RuntimeError("Couldn't get process token") 
    return token 

def get_symlink_luid(): 
    """ 
    Get the LUID for the SeCreateSymbolicLinkPrivilege 
    """ 
    symlink_luid = LUID() 
    res = LookupPrivilegeValue(None, "SeCreateSymbolicLinkPrivilege", symlink_luid) 
    if not res > 0: raise RuntimeError("Couldn't lookup privilege value") 
    return symlink_luid 

def get_privilege_information(): 
    """ 
    Get all privileges associated with the current process. 
    """ 
    # first call with zero length to determine what size buffer we need 

    return_length = wintypes.DWORD() 
    params = [ 
     get_process_token(), 
     TOKEN_INFORMATION_CLASS.TokenPrivileges, 
     None, 
     0, 
     return_length, 
     ] 

    res = GetTokenInformation(*params) 

    # assume we now have the necessary length in return_length 

    buffer = ctypes.create_string_buffer(return_length.value) 
    params[2] = buffer 
    params[3] = return_length.value 

    res = GetTokenInformation(*params) 
    assert res > 0, "Error in second GetTokenInformation (%d)" % res 

    privileges = ctypes.cast(buffer, ctypes.POINTER(TOKEN_PRIVILEGES)).contents 
    return privileges 

def report_privilege_information(): 
    """ 
    Report all privilege information assigned to the current process. 
    """ 
    privileges = get_privilege_information() 
    print("found {0} privileges".format(privileges.count)) 
    tuple(map(print, privileges)) 

def enable_symlink_privilege(): 
    """ 
    Try to assign the symlink privilege to the current process token. 
    Return True if the assignment is successful. 
    """ 
    # create a space in memory for a TOKEN_PRIVILEGES structure 
    # with one element 
    size = ctypes.sizeof(TOKEN_PRIVILEGES) 
    size += ctypes.sizeof(LUID_AND_ATTRIBUTES) 
    buffer = ctypes.create_string_buffer(size) 
    tp = ctypes.cast(buffer, ctypes.POINTER(TOKEN_PRIVILEGES)).contents 
    tp.count = 1 
    tp.get_array()[0].enable() 
    tp.get_array()[0].LUID = get_symlink_luid() 
    token = get_process_token() 
    res = AdjustTokenPrivileges(token, False, tp, 0, None, None) 
    if res == 0: 
     raise RuntimeError("Error in AdjustTokenPrivileges") 

    ERROR_NOT_ALL_ASSIGNED = 1300 
    return ctypes.windll.kernel32.GetLastError() != ERROR_NOT_ALL_ASSIGNED 

def main(): 
    assigned = enable_symlink_privilege() 
    msg = ['failure', 'success'][assigned] 

    print("Symlink privilege assignment completed with {0}".format(msg)) 

if __name__ == '__main__': main() 
संबंधित मुद्दे