For members of administrator group, Cygwin runs with root access rights.
Cygwin enables the Windows backup and restore privileges which are not
enabled by default.
This is IMO not desirable under all circumstances.
This patch adds a new flag to the Cygwin environment variable.
If 'CYGWIN=noroot' is set, the extra privileges are removed after Cygwin
startup.
This allows to run a Cygwin shell with the same default access rights as
cmd or explorer.
Testcase:
$ cd /cygdrive/c
$ ls -l 'System Volume Information'
----rwx--- 1 root SYSTEM 0 Feb 22 2009 MountPointManagerRemoteDatabase
...
$ CYGWIN=noroot ls -l 'System Volume Information'
ls: cannot open directory System Volume Information: Permission denied
I'm sure there is something missing, so no changelog for now :-)
Christian
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index d4e003f..eff982d 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -33,6 +33,7 @@ details. */
extern bool dos_file_warning;
extern bool ignore_case_with_glob;
extern bool allow_winsymlinks;
+extern bool use_root_privileges;
bool reset_com = false;
static bool envcache = true;
static bool create_upcaseenv = false;
@@ -565,6 +566,23 @@ set_proc_retry (const char *buf)
child_info::retry_count = strtoul (buf, NULL, 0);
}
+static void
+set_root_mode (const char *buf)
+{
+ bool old_state = use_root_privileges;
+
+ if (!buf || !*buf)
+ use_root_privileges = false;
+ else
+ use_root_privileges = true;
+
+ if (use_root_privileges != old_state)
+ {
+ OpenProcessToken (hMainProc, MAXIMUM_ALLOWED, &hProcToken);
+ set_cygwin_privileges (hProcToken);
+ }
+}
+
/* The structure below is used to set up an array which is used to
parse the CYGWIN environment variable or, if enabled, options from
the registry. */
@@ -596,6 +614,7 @@ static struct parse_thing
{"glob", {func: &glob_init}, isfunc, NULL, {{0}, {s: "normal"}}},
{"proc_retry", {func: set_proc_retry}, isfunc, NULL, {{0}, {5}}},
{"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}},
+ {"root", {func: &set_root_mode}, isfunc, NULL, {{s:NULL}, {s:"yes"}}},
{"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}},
{"title", {&display_title}, justset, NULL, {{false}, {true}}},
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
index 63be25c..c567dfd 100644
--- a/winsup/cygwin/sec_helper.cc
+++ b/winsup/cygwin/sec_helper.cc
@@ -406,15 +406,22 @@ out:
return ret;
}
+/* This may be set to false by 'CYGWIN=noroot' or by parent process
+ through fork(). */
+bool use_root_privileges = true;
+
/* This is called very early in process initialization. The code must
- not depend on anything. */
+ not depend on anything.
+ Note: During fork() this is called twice:
+ first with use_root_privileges = always_true,
+ then with use_root_privileges = inherited_from_parent. */
void
set_cygwin_privileges (HANDLE token)
{
- set_privilege (token, SE_RESTORE_PRIVILEGE, true);
- set_privilege (token, SE_BACKUP_PRIVILEGE, true);
+ set_privilege (token, SE_RESTORE_PRIVILEGE, use_root_privileges);
+ set_privilege (token, SE_BACKUP_PRIVILEGE, use_root_privileges);
if (wincap.has_create_global_privilege ())
- set_privilege (token, SE_CREATE_GLOBAL_PRIVILEGE, true);
+ set_privilege (token, SE_CREATE_GLOBAL_PRIVILEGE, use_root_privileges);
}
/* Function to return a common SECURITY_DESCRIPTOR that