Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 578373
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T14:15:12+00:00 2026-05-13T14:15:12+00:00

I want to programmatically determine if the current user (or process) has access to

  • 0

I want to programmatically determine if the current user (or process) has access to create symbolic links. In Windows (Vista and greater), one cannot create a symbolic link without the SeCreateSymbolicLinkPrivilege and by default, this is only assigned to administrators. If one attempts to create a symbolic link without this privilege, a Windows error 1314 (A required privilege is not held by the client) occurs.

To demonstrate this restriction, I created a clean install of Windows, logged in as the initial Administrator account (restricted through UAC), and was unable to create a symlink in the home directory.

Command Prompt demonstrates mklink fails due to insufficient privilege

After running the Command Prompt as Administrator or disabling UAC, that command executes without error.

According to this article, “every process executed on behalf of the user has a copy of the [access] token”.

So I’ve created a Python script to query for the permissions. For convenience and posterity, I include an excerpt below.

The idea behind the script is to enumerate all privileges and determine if the process has the required privilege. Unfortunately, I find that the current process does not in fact have the desired privilege, even when it can create symlinks.

I suspect the problem is that even though the current user’s privileges does not explicitly include the privilege, his group membership does afford that privilege.

In short, how can I determine if a given process will have privilege to create symbolic links (without attempting to create one)? An example in C or C++ or Python is preferred, though anything utilizing the Windows API will be suitable.

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)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T14:15:12+00:00Added an answer on May 13, 2026 at 2:15 pm

    I found a solution. The following Python code is a fully-functional script under Python 2.6 or 3.1 that demonstrates how one might determine privilege to create symlinks. Running this under the Administrator account responds with success, and running it under the Guest account responds with failure.

    Note, the first 3/4 of the script is mostly API definitions. The novel work begins with 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()
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 416k
  • Answers 416k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer if you write return (code == myCode); you will save… May 15, 2026 at 9:18 am
  • Editorial Team
    Editorial Team added an answer Thanks to http://devgirl.wordpress.com/ for this solution! I think it is… May 15, 2026 at 9:18 am
  • Editorial Team
    Editorial Team added an answer $('<a href="http://'+url+'"></a>').html(url).appendTo('#link_'+id); ? You left the closing bracket of your… May 15, 2026 at 9:18 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.