aboutsummaryrefslogtreecommitdiff
path: root/gdb/windows-nat.c
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2003-01-10 20:14:02 +0000
committerCorinna Vinschen <corinna@vinschen.de>2003-01-10 20:14:02 +0000
commit616a9dc4c0906f42e1b35e94f5e2e200f561f1e9 (patch)
tree41d71d16dffc1e33d0ad1702a2da3894e86321b0 /gdb/windows-nat.c
parent3269bcfa1ceb437ea6a0c4cd90c7f28ca2c2454c (diff)
downloadgdb-616a9dc4c0906f42e1b35e94f5e2e200f561f1e9.zip
gdb-616a9dc4c0906f42e1b35e94f5e2e200f561f1e9.tar.gz
gdb-616a9dc4c0906f42e1b35e94f5e2e200f561f1e9.tar.bz2
* win32-nat.c (set_process_privilege): New function.
(child_attach): Call set_process_privilege() to enable the SE_DEBUG_NAME user privilege if available in process token.
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r--gdb/windows-nat.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index f3fb0a7..91d27ae 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1374,6 +1374,83 @@ has_detach_ability (void)
return 0;
}
+/* Try to set or remove a user privilege to the current process. Return -1
+ if that fails, the previous setting of that privilege otherwise.
+
+ This code is copied from the Cygwin source code and rearranged to allow
+ dynamically loading of the needed symbols from advapi32 which is only
+ available on NT/2K/XP. */
+static int
+set_process_privilege (const char *privilege, BOOL enable)
+{
+ static HMODULE advapi32 = NULL;
+ static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
+ static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
+ static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
+ DWORD, PTOKEN_PRIVILEGES, PDWORD);
+
+ HANDLE token_hdl = NULL;
+ LUID restore_priv;
+ TOKEN_PRIVILEGES new_priv, orig_priv;
+ int ret = -1;
+ DWORD size;
+
+ if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
+ return 0;
+
+ if (!advapi32)
+ {
+ if (!(advapi32 = LoadLibrary ("advapi32.dll")))
+ goto out;
+ if (!OpenProcessToken)
+ OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
+ if (!LookupPrivilegeValue)
+ LookupPrivilegeValue = GetProcAddress (advapi32,
+ "LookupPrivilegeValueA");
+ if (!AdjustTokenPrivileges)
+ AdjustTokenPrivileges = GetProcAddress (advapi32,
+ "AdjustTokenPrivileges");
+ if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
+ {
+ advapi32 = NULL;
+ goto out;
+ }
+ }
+
+ if (!OpenProcessToken (GetCurrentProcess (),
+ TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
+ &token_hdl))
+ goto out;
+
+ if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
+ goto out;
+
+ new_priv.PrivilegeCount = 1;
+ new_priv.Privileges[0].Luid = restore_priv;
+ new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
+
+ if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
+ sizeof orig_priv, &orig_priv, &size))
+ goto out;
+#if 0
+ /* Disabled, otherwise every `attach' in an unprivileged user session
+ would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
+ child_attach(). */
+ /* AdjustTokenPrivileges returns TRUE even if the privilege could not
+ be enabled. GetLastError () returns an correct error code, though. */
+ if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
+ goto out;
+#endif
+
+ ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
+
+out:
+ if (token_hdl)
+ CloseHandle (token_hdl);
+
+ return ret;
+}
+
/* Attach to process PID, then initialize for debugging it. */
static void
child_attach (char *args, int from_tty)
@@ -1384,6 +1461,12 @@ child_attach (char *args, int from_tty)
if (!args)
error_no_arg ("process-id to attach");
+ if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
+ {
+ printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
+ printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
+ }
+
pid = strtoul (args, 0, 0);
ok = DebugActiveProcess (pid);
saw_create = 0;