title: Determine if Windows process has privilege to create symbolic link
body: <p>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.</p>
  
  <p>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.</p>
  
  <p><img src="https://dl.dropbox.com/u/54081/linked/cant-create-symlink%202.png" alt="Command Prompt demonstrates mklink fails due to insufficient privilege"></p>
  
  <p>After running the Command Prompt as Administrator or disabling UAC, that command executes without error.</p>
  
  <p>According to <a href="http://msdn.microsoft.com/en-us/library/ms721532%28VS.85%29.aspx" rel="nofollow noreferrer">this article</a>, "every process executed on behalf of the user has a copy of the [access] token".</p>
  
  <p>So I've created <a href="https://svn.jaraco.com/jaraco/python/incubator/has-create-symlink-privilege.py" rel="nofollow noreferrer">a Python script to query for the permissions</a>. For convenience and posterity, I include an excerpt below.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <pre><code>def get_process_token():
      token = wintypes.HANDLE()
      TOKEN_ALL_ACCESS = 0xf01ff
      res = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token)
      if not res &gt; 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 &gt; 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)
  </code></pre>