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, ))
+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, ))
+{
+ NoteFailedAPI ("LookupPrivilegeValue");
+ return FALSE;
+}
+
+ DWORD size;
+ GetTokenInformation (token.theHANDLE (), TokenPrivileges, NULL, 0, );
+ /* Will fail ERROR_INSUFFICIENT_BUFFER, but updates size */
+
+ TOKEN_PRIVILEGES *privileges = (TOKEN_PRIVILEGES *)alloca(size);
+ if (!GetTokenInformation (token.theHANDLE (), TokenPrivileges, privileges,
+size, ))
+{
+ NoteFailedAPI ("GetTokenInformation(privileges)");
+ return FALSE;
+}
+
+ unsigned int i;
+ for (i = 0; i < privileges->PrivilegeCount; i++)
+{
+ if (memcmp(>Privileges[i].Luid, , 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