summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-11-24 11:07:32 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-11-24 11:07:32 +0000
commitcfd6979c39434554d21f6e39a102811717b9bc28 (patch)
tree7a4f6e39fda1c34d5a46bf014a9a2b387a92e5e6
parent764d26127618c1293d498ba0b8c9f626be521278 (diff)
downloadcygnal-cfd6979c39434554d21f6e39a102811717b9bc28.tar.gz
cygnal-cfd6979c39434554d21f6e39a102811717b9bc28.tar.bz2
cygnal-cfd6979c39434554d21f6e39a102811717b9bc28.zip
* passwd.c (GetPW): If server is NULL, and the user is not a local
user, try to fetch the DC to use as server. (ChangePW): Get Windows username via extra parameter. (usage): Reduce -d help text to reflect above change. (main): Fix typo in comment. Call GetPW and ChangePW as per the changes above.
-rw-r--r--winsup/utils/ChangeLog9
-rw-r--r--winsup/utils/passwd.c46
2 files changed, 41 insertions, 14 deletions
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index 179a3cc85..cc2fa2820 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,12 @@
+2014-11-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * passwd.c (GetPW): If server is NULL, and the user is not a local
+ user, try to fetch the DC to use as server.
+ (ChangePW): Get Windows username via extra parameter.
+ (usage): Reduce -d help text to reflect above change.
+ (main): Fix typo in comment. Call GetPW and ChangePW as per the
+ changes above.
+
2014-11-12 Corinna Vinschen <corinna@vinschen.de>
* mkgroup.c (usage): Fix language.
diff --git a/winsup/utils/passwd.c b/winsup/utils/passwd.c
index 2046849a1..8a08189fa 100644
--- a/winsup/utils/passwd.c
+++ b/winsup/utils/passwd.c
@@ -17,6 +17,7 @@ details. */
#include <lmerr.h>
#include <lmcons.h>
#include <lmapibuf.h>
+#include <dsgetdc.h>
#include <stdio.h>
#include <stdlib.h>
@@ -115,7 +116,7 @@ EvalRet (int ret, const char *user)
}
PUSER_INFO_3
-GetPW (char *user, int print_win_name, LPCWSTR server)
+GetPW (char *user, int print_win_name, LPWSTR *server)
{
char usr_buf[UNLEN + 1];
WCHAR name[UNLEN + 1];
@@ -124,7 +125,7 @@ GetPW (char *user, int print_win_name, LPCWSTR server)
struct passwd *pw;
char *domain = (char *) alloca (INTERNET_MAX_HOST_NAME_LENGTH + 1);
- /* Try getting a Win32 username in case the user edited /etc/passwd */
+ /* Get the Win32 username and a suitable server. */
if ((pw = getpwnam (user)))
{
cygwin_internal (CW_EXTRACT_DOMAIN_AND_USER, pw, domain, usr_buf);
@@ -138,20 +139,38 @@ GetPW (char *user, int print_win_name, LPCWSTR server)
printf ("Windows username : %s\n", user);
}
}
+ if (!*server)
+ {
+ PDOMAIN_CONTROLLER_INFOW dci;
+ char machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ DWORD mlen = sizeof machine;
+ WCHAR wdom[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+
+ /* If we can't fetch the local machine name, or if the machine name
+ is not the same as the user's domain name, try to fetch the DC via
+ DsGetDcName. Otherwise, just stick to a NULL servername, since
+ that's the same as using the local machine. */
+ if (!GetComputerNameExA (ComputerNameNetBIOS, machine, &mlen)
+ || strcasecmp (domain, machine) != 0)
+ {
+ mbstowcs (wdom, domain, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ if (!DsGetDcNameW (NULL, wdom, NULL, NULL, DS_IS_FLAT_NAME, &dci))
+ *server = dci->DomainControllerName;
+ }
+ }
}
mbstowcs (name, user, UNLEN + 1);
- ret = NetUserGetInfo (server, name, 3, (void *) &ui);
+ ret = NetUserGetInfo (*server, name, 3, (void *) &ui);
return EvalRet (ret, user) ? NULL : ui;
}
int
-ChangePW (const char *user, const char *oldpwd, const char *pwd, int justcheck,
- LPCWSTR server)
+ChangePW (const char *user, PCWSTR name, const char *oldpwd, const char *pwd,
+ int justcheck, LPCWSTR server)
{
- WCHAR name[UNLEN + 1], oldpass[512], pass[512];
+ WCHAR oldpass[512], pass[512];
DWORD ret;
- mbstowcs (name, user, UNLEN + 1);
mbstowcs (pass, pwd, 512);
if (!oldpwd)
{
@@ -281,9 +300,7 @@ usage (FILE * stream, int status)
"\n"
"Other options:\n"
" -d, --logonserver SERVER connect to SERVER (e.g. domain controller).\n"
- " Default server is the local system, unless\n"
- " changing the current user, in which case the\n"
- " default is the content of $LOGONSERVER.\n"
+ " Usually not required.\n"
" -S, --status display password status for USER (locked, expired,\n"
" etc.) plus global system password settings.\n"
" -h, --help output usage information and exit.\n"
@@ -482,7 +499,7 @@ main (int argc, char **argv)
break;
case 'V':
- case 'v': /* Keep this option for historrical reasons,
+ case 'v': /* Keep this option for historical reasons,
but don't advertize it. */
print_version ();
exit (0);
@@ -590,7 +607,7 @@ main (int argc, char **argv)
}
}
- ui = GetPW (user, 1, server);
+ ui = GetPW (user, 1, &server);
if (!ui)
return 1;
@@ -638,7 +655,7 @@ main (int argc, char **argv)
if (!caller_is_admin ())
{
strcpy (oldpwd, getpass ("Old password: "));
- if (ChangePW (user, oldpwd, oldpwd, 1, server))
+ if (ChangePW (user, ui->usri3_name, oldpwd, oldpwd, 1, server))
return 1;
}
@@ -647,7 +664,8 @@ main (int argc, char **argv)
strcpy (newpwd, getpass ("New password: "));
if (strcmp (newpwd, getpass ("Re-enter new password: ")))
eprint (0, "Password is not identical.");
- else if (!ChangePW (user, *oldpwd ? oldpwd : NULL, newpwd, 0, server))
+ else if (!ChangePW (user, ui->usri3_name, *oldpwd ? oldpwd : NULL,
+ newpwd, 0, server))
ret = 1;
if (!ret && cnt < 2)
eprint (0, "Try again.");