public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
From: Jon Turney <jon.turney@dronecode.org.uk>
To: cygwin-apps@cygwin.com
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: [PATCH setup 06/11] Enable SeCreateSymbolicLink privilege
Date: Tue, 10 Aug 2021 18:02:23 +0100	[thread overview]
Message-ID: <20210810170228.1690-7-jon.turney@dronecode.org.uk> (raw)
In-Reply-To: <20210810170228.1690-1-jon.turney@dronecode.org.uk>

I'm not sure if SeCreateSymbolicLink privilege can get removed by UAC
filtering, but to make sure to enable it, if we can.

Also report if it's available to log.
---
 win32.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 win32.h  |  2 ++
 2 files changed, 60 insertions(+)

diff --git a/win32.cc b/win32.cc
index 8ee424f..6455384 100644
--- a/win32.cc
+++ b/win32.cc
@@ -280,6 +280,28 @@ NTSecurity::setBackupPrivileges ()
     }
 }
 
+void
+NTSecurity::setSymlinkPrivilege ()
+{
+  LUID symlink;
+  if (!LookupPrivilegeValue (NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &symlink))
+    NoteFailedAPI ("LookupPrivilegeValue");
+
+  PTOKEN_PRIVILEGES new_priv;
+  new_priv = (PTOKEN_PRIVILEGES) alloca (sizeof (TOKEN_PRIVILEGES));
+  new_priv->PrivilegeCount = 1;
+  new_priv->Privileges[0].Luid = symlink;
+  new_priv->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+  if (!AdjustTokenPrivileges (token.theHANDLE (), FALSE, new_priv,
+                              0, NULL, NULL))
+    NoteFailedAPI ("AdjustTokenPrivileges");
+  else if (GetLastError () == ERROR_NOT_ALL_ASSIGNED)
+    Log (LOG_TIMESTAMP) << "User has NO symlink creation right" << endLog;
+  else
+    Log (LOG_TIMESTAMP) << "User has symlink creation right" << endLog;
+}
+
 void
 NTSecurity::resetPrimaryGroup ()
 {
@@ -321,6 +343,9 @@ NTSecurity::setDefaultSecurity (bool isAdmin)
   /* Set backup and restore privileges if available. */
   setBackupPrivileges ();
 
+  /* Set symlink creation privilege, if available. */
+  setSymlinkPrivilege ();
+
   /* If initializing the well-known SIDs didn't work, we're finished here. */
   if (!wellKnownSIDsinitialized ())
     return;
@@ -371,6 +396,39 @@ NTSecurity::isRunAsAdmin ()
   return (is_run_as_admin == TRUE);
 }
 
+bool
+NTSecurity::hasSymlinkCreationRights ()
+{
+  LUID symlink;
+  if (!LookupPrivilegeValue (NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &symlink))
+    {
+      NoteFailedAPI ("LookupPrivilegeValue");
+      return FALSE;
+    }
+
+  DWORD size;
+  GetTokenInformation (token.theHANDLE (), TokenPrivileges, NULL, 0, &size);
+  /* Will fail ERROR_INSUFFICIENT_BUFFER, but updates size */
+
+  TOKEN_PRIVILEGES *privileges = (TOKEN_PRIVILEGES *)alloca(size);
+  if (!GetTokenInformation (token.theHANDLE (), TokenPrivileges, privileges,
+                            size, &size))
+    {
+      NoteFailedAPI ("GetTokenInformation(privileges)");
+      return FALSE;
+    }
+
+  unsigned int i;
+  for (i = 0; i < privileges->PrivilegeCount; i++)
+    {
+      if (memcmp(&privileges->Privileges[i].Luid, &symlink, sizeof(LUID)) == 0)
+        {
+          return (privileges->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED);
+        }
+    }
+
+  return FALSE;
+}
 
 VersionInfo::VersionInfo ()
 {
diff --git a/win32.h b/win32.h
index daebf2e..e498077 100644
--- a/win32.h
+++ b/win32.h
@@ -132,12 +132,14 @@ public:
   void initialiseWellKnownSIDs ();
   void setDefaultSecurity(bool isAdmin);
   bool isRunAsAdmin ();
+  bool hasSymlinkCreationRights ();
 private:
   void NoteFailedAPI (const std::string &);
   bool wellKnownSIDsinitialized () const { return _wellKnownSIDsinitialized; }
   void wellKnownSIDsinitialized (bool b) { _wellKnownSIDsinitialized = b; }
   void setDefaultDACL ();
   void setBackupPrivileges ();
+  void setSymlinkPrivilege ();
 
   SIDWrapper nullSID, everyOneSID, administratorsSID, usersSID,
 	     cr_ownerSID, cr_groupSID;
-- 
2.32.0


  parent reply	other threads:[~2021-08-10 17:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-10 17:02 [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney
2021-08-10 17:02 ` [PATCH setup 01/11] Add support for creating WSL symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 02/11] Add support for creating native symlinks Jon Turney
2021-08-10 17:02 ` [PATCH setup 03/11] Factor out the iteration over archive files to install Jon Turney
2021-08-10 17:02 ` [PATCH setup 04/11] Add seek() method to archive and compress file classes Jon Turney
2021-08-10 17:02 ` [PATCH setup 05/11] Add separate symlink-creation phase when extracting archive Jon Turney
2021-08-10 17:02 ` Jon Turney [this message]
2021-08-11  8:46   ` [PATCH setup 06/11] Enable SeCreateSymbolicLink privilege Corinna Vinschen
2021-09-14 11:53     ` Jon Turney
2021-08-10 17:02 ` [PATCH setup 07/11] Add symlink capabilities to user-agent telemetry Jon Turney
2021-08-10 17:02 ` [PATCH setup 08/11] Factor out StringChoiceOption Jon Turney
2021-08-10 17:02 ` [PATCH setup 09/11] Add a command line option to choose symlink type used Jon Turney
2021-08-10 17:02 ` [PATCH setup 10/11] Propagate --symlink-type setting to post-install scripts Jon Turney
2021-08-10 17:02 ` [PATCH setup 11/11] Default symlink mode from CYGWIN env var Jon Turney
2021-09-14 11:53 ` [PATCH setup 00/11] Add options to choose symlink type (v2) Jon Turney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210810170228.1690-7-jon.turney@dronecode.org.uk \
    --to=jon.turney@dronecode.org.uk \
    --cc=cygwin-apps@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).