summaryrefslogtreecommitdiffstats
path: root/winsup/utils
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-03-23 16:37:49 +0000
committerCorinna Vinschen <corinna@vinschen.de>2009-03-23 16:37:49 +0000
commit0e0f5748e0aaeb910dc074bed7fa3509897e982a (patch)
tree09dcb80e9c73dc235e37107a3e5db9e1ae1ababb /winsup/utils
parent7d2e8c04f21294840159ca8f7393eb713487f8a4 (diff)
downloadcygnal-0e0f5748e0aaeb910dc074bed7fa3509897e982a.tar.gz
cygnal-0e0f5748e0aaeb910dc074bed7fa3509897e982a.tar.bz2
cygnal-0e0f5748e0aaeb910dc074bed7fa3509897e982a.zip
* passwd.c (caller_is_admin): New function to test if calling user
is an administrator by inspecting user token. (main): Drop fetching caller info from logonserver. Only fetch server from environment when trying to change password for own account. Drop admin check entirely in case of doing account maintainance. Otherwise replace check for admin by result of caller_is_admin call.
Diffstat (limited to 'winsup/utils')
-rw-r--r--winsup/utils/ChangeLog10
-rw-r--r--winsup/utils/passwd.c78
2 files changed, 69 insertions, 19 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index 2dc2c2349..31b18e5e0 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,13 @@
+2009-03-23 Corinna Vinschen <corinna@vinschen.de>
+
+ * passwd.c (caller_is_admin): New function to test if calling user
+ is an administrator by inspecting user token.
+ (main): Drop fetching caller info from logonserver. Only fetch
+ server from environment when trying to change password for own
+ account. Drop admin check entirely in case of doing account
+ maintainance. Otherwise replace check for admin by result of
+ caller_is_admin call.
+
2009-03-22 Corinna Vinschen <corinna@vinschen.de>
* passwd.c (main): Always get logonserver from environment and
diff --git a/winsup/utils/passwd.c b/winsup/utils/passwd.c
index 1f04fb63c..3616848ab 100644
--- a/winsup/utils/passwd.c
+++ b/winsup/utils/passwd.c
@@ -303,6 +303,49 @@ usage (FILE * stream, int status)
exit (status);
}
+static int
+caller_is_admin ()
+{
+ static int is_admin = -1;
+ HANDLE token;
+ DWORD size;
+ PTOKEN_GROUPS grps;
+ SID_IDENTIFIER_AUTHORITY nt_auth = {SECURITY_NT_AUTHORITY};
+ PSID admin_grp;
+ DWORD i;
+
+ if (is_admin == -1)
+ {
+ is_admin = 0;
+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_READ, &token))
+ {
+ GetTokenInformation (token, TokenGroups, NULL, 0, &size);
+ grps = (PTOKEN_GROUPS) alloca (size);
+ if (!GetTokenInformation(token, TokenGroups, grps, size, &size)
+ || !AllocateAndInitializeSid (&nt_auth, 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0, &admin_grp))
+ is_admin = 0;
+ else
+ {
+ for (i = 0; i < grps->GroupCount; ++i)
+ if (EqualSid (admin_grp, grps->Groups[i].Sid)
+ && (grps->Groups[i].Attributes
+ & (SE_GROUP_ENABLED | SE_GROUP_USE_FOR_DENY_ONLY))
+ == SE_GROUP_ENABLED)
+ {
+ is_admin = 1;
+ break;
+ }
+ FreeSid (admin_grp);
+ }
+ CloseHandle (token);
+ }
+ }
+ return is_admin;
+}
+
static void
print_version ()
{
@@ -348,8 +391,8 @@ main (int argc, char **argv)
int Popt = 0;
int Sopt = 0;
int Ropt = 0;
- PUSER_INFO_3 ui, li;
- LPWSTR my_server = NULL;
+ PUSER_INFO_3 ui;
+ int myself = 0;
LPWSTR server = NULL;
prog_name = strrchr (argv[0], '/');
@@ -518,16 +561,6 @@ main (int argc, char **argv)
return 0;
}
- if ((logonserver = getenv ("LOGONSERVER")))
- {
- size_t len = mbstowcs (NULL, logonserver, 0);
- if (len > 0 && len != (size_t) -1)
- mbstowcs (my_server = alloca ((len + 1) * sizeof (wchar_t)),
- logonserver, len + 1);
- if (!server)
- server = my_server;
- }
-
if (Larg >= 0 || xarg >= 0 || narg >= 0 || iarg >= 0)
{
if (optind < argc)
@@ -537,9 +570,18 @@ main (int argc, char **argv)
strcpy (user, optind >= argc ? getlogin () : argv[optind]);
- li = GetPW (getlogin (), 0, my_server);
- if (! li)
- return 1;
+ /* Changing password for calling user? Use logonserver for user as well. */
+ if (!server && optind < argc)
+ {
+ myself = 1;
+ if ((logonserver = getenv ("LOGONSERVER")))
+ {
+ size_t len = mbstowcs (NULL, logonserver, 0);
+ if (len > 0 && len != (size_t) -1)
+ mbstowcs (server = alloca ((len + 1) * sizeof (wchar_t)),
+ logonserver, len + 1);
+ }
+ }
ui = GetPW (user, 1, server);
if (! ui)
@@ -549,8 +591,6 @@ main (int argc, char **argv)
{
USER_INFO_1008 uif;
- if (li->usri3_priv != USER_PRIV_ADMIN)
- return eprint (0, "You have no maintenance privileges.");
uif.usri1008_flags = ui->usri3_flags;
if (lopt)
{
@@ -584,14 +624,14 @@ main (int argc, char **argv)
return 0;
}
- if (li->usri3_priv != USER_PRIV_ADMIN && strcmp (getlogin (), user))
+ if (!caller_is_admin () && !myself)
return eprint (0, "You may not change the password for %s.", user);
eprint (0, "Enter the new password (minimum of 5, maximum of 8 characters).");
eprint (0, "Please use a combination of upper and lower case letters and numbers.");
oldpwd[0] = '\0';
- if (li->usri3_priv != USER_PRIV_ADMIN)
+ if (!caller_is_admin ())
{
strcpy (oldpwd, getpass ("Old password: "));
if (ChangePW (user, oldpwd, oldpwd, 1, server))