* passwd.c (longopts): Add --reg-store-pwd option.
(opts): Add -R option. (usage): Add text for -R/--reg-store-pwd option. (main): Fix size of local user and password string arrays. Handle -R option. * utils.sgml: Add text for passwd -R/--reg-store-pwd option.
This commit is contained in:
parent
d4db08d7a6
commit
d865502063
|
@ -1,3 +1,12 @@
|
||||||
|
2008-11-26 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* passwd.c (longopts): Add --reg-store-pwd option.
|
||||||
|
(opts): Add -R option.
|
||||||
|
(usage): Add text for -R/--reg-store-pwd option.
|
||||||
|
(main): Fix size of local user and password string arrays.
|
||||||
|
Handle -R option.
|
||||||
|
* utils.sgml: Add text for passwd -R/--reg-store-pwd option.
|
||||||
|
|
||||||
2008-10-29 Christopher Faylor <me+cygwin@cgf.cx>
|
2008-10-29 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* Makefile.in (ALL_LDFLAGS): Link libgcc statically for everything
|
* Makefile.in (ALL_LDFLAGS): Link libgcc statically for everything
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* passwd.c: Changing passwords and managing account information
|
/* passwd.c: Changing passwords and managing account information
|
||||||
|
|
||||||
Copyright 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
Copyright 1999, 2000, 2001, 2002, 2003, 2008 Red Hat, Inc.
|
||||||
|
|
||||||
Written by Corinna Vinschen <corinna.vinschen@cityweb.de>
|
Written by Corinna Vinschen <corinna.vinschen@cityweb.de>
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ details. */
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#define USER_PRIV_ADMIN 2
|
#define USER_PRIV_ADMIN 2
|
||||||
|
|
||||||
|
@ -50,10 +51,11 @@ static struct option longopts[] =
|
||||||
{"maxage", required_argument, NULL, 'x'},
|
{"maxage", required_argument, NULL, 'x'},
|
||||||
{"length", required_argument, NULL, 'L'},
|
{"length", required_argument, NULL, 'L'},
|
||||||
{"status", no_argument, NULL, 'S'},
|
{"status", no_argument, NULL, 'S'},
|
||||||
|
{ "reg-store-pwd", no_argument, NULL, 'R'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static char opts[] = "cCd:eEhi:ln:pPuvx:L:S";
|
static char opts[] = "cCd:eEhi:ln:pPuvx:L:SR";
|
||||||
|
|
||||||
int
|
int
|
||||||
eprint (int with_name, const char *fmt, ...)
|
eprint (int with_name, const char *fmt, ...)
|
||||||
|
@ -263,6 +265,9 @@ usage (FILE * stream, int status)
|
||||||
" password aging rule.\n"
|
" password aging rule.\n"
|
||||||
" -p, --pwd-not-required no password required for USER.\n"
|
" -p, --pwd-not-required no password required for USER.\n"
|
||||||
" -P, --pwd-required password is required for USER.\n"
|
" -P, --pwd-required password is required for USER.\n"
|
||||||
|
" -R, --reg-store-pwd enter password to store it in the registry for\n"
|
||||||
|
" later usage by services to be able to switch\n"
|
||||||
|
" to this user context with network credentials.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"System operations:\n"
|
"System operations:\n"
|
||||||
" -i, --inactive NUM set NUM of days before inactive accounts are disabled\n"
|
" -i, --inactive NUM set NUM of days before inactive accounts are disabled\n"
|
||||||
|
@ -283,6 +288,15 @@ usage (FILE * stream, int status)
|
||||||
"operate on current user. System operations must not be mixed with user\n"
|
"operate on current user. System operations must not be mixed with user\n"
|
||||||
"operations. Don't specify a USER when triggering a system operation.\n"
|
"operations. Don't specify a USER when triggering a system operation.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"Don't specify a user or any other option together with the -R option.\n"
|
||||||
|
"Non-Admin users can only store their password if cygserver is running and\n"
|
||||||
|
"the CYGWIN environment variable is set to contain the word 'server'.\n"
|
||||||
|
"Note that storing even obfuscated passwords in the registry is not overly\n"
|
||||||
|
"secure. Use this feature only if the machine is adequately locked down.\n"
|
||||||
|
"Don't use this feature if you don't need network access within a remote\n"
|
||||||
|
"session. You can delete your stored password by using `passwd -R' and\n"
|
||||||
|
"specifying an empty password.\n"
|
||||||
|
"\n"
|
||||||
"Report bugs to <cygwin@cygwin.com>\n", prog_name);
|
"Report bugs to <cygwin@cygwin.com>\n", prog_name);
|
||||||
exit (status);
|
exit (status);
|
||||||
}
|
}
|
||||||
|
@ -314,7 +328,7 @@ int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *c;
|
char *c;
|
||||||
char user[64], oldpwd[64], newpwd[64];
|
char user[UNLEN + 1], oldpwd[_PASSWORD_LEN + 1], newpwd[_PASSWORD_LEN + 1];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
int opt, len;
|
int opt, len;
|
||||||
|
@ -331,6 +345,7 @@ main (int argc, char **argv)
|
||||||
int popt = 0;
|
int popt = 0;
|
||||||
int Popt = 0;
|
int Popt = 0;
|
||||||
int Sopt = 0;
|
int Sopt = 0;
|
||||||
|
int Ropt = 0;
|
||||||
PUSER_INFO_3 ui, li;
|
PUSER_INFO_3 ui, li;
|
||||||
LPWSTR server = NULL;
|
LPWSTR server = NULL;
|
||||||
|
|
||||||
|
@ -353,20 +368,20 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt)
|
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
if ((iarg = atoi (optarg)) < 0 || iarg > 999)
|
if ((iarg = atoi (optarg)) < 0 || iarg > 999)
|
||||||
return eprint (1, "Force logout time must be between 0 and 999.");
|
return eprint (1, "Force logout time must be between 0 and 999.");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || uopt || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || uopt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
lopt = 1;
|
lopt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt)
|
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
if ((narg = atoi (optarg)) < 0 || narg > 999)
|
if ((narg = atoi (optarg)) < 0 || narg > 999)
|
||||||
return eprint (1, "Minimum password age must be between 0 and 999.");
|
return eprint (1, "Minimum password age must be between 0 and 999.");
|
||||||
|
@ -376,25 +391,27 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
uopt = 1;
|
uopt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
copt = 1;
|
copt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
Copt = 1;
|
Copt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
{
|
{
|
||||||
|
if (Ropt)
|
||||||
|
usage (stderr, 1);
|
||||||
char *tmpbuf = alloca (strlen (optarg) + 3);
|
char *tmpbuf = alloca (strlen (optarg) + 3);
|
||||||
tmpbuf[0] = '\0';
|
tmpbuf[0] = '\0';
|
||||||
if (*optarg != '\\')
|
if (*optarg != '\\')
|
||||||
|
@ -408,25 +425,25 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
eopt = 1;
|
eopt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
Eopt = 1;
|
Eopt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
popt = 1;
|
popt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt)
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
Popt = 1;
|
Popt = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -437,7 +454,7 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt)
|
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
if ((xarg = atoi (optarg)) < 0 || xarg > 999)
|
if ((xarg = atoi (optarg)) < 0 || xarg > 999)
|
||||||
return eprint (1, "Maximum password age must be between 0 and 999.");
|
return eprint (1, "Maximum password age must be between 0 and 999.");
|
||||||
|
@ -447,7 +464,7 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'L':
|
case 'L':
|
||||||
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt)
|
if (lopt || uopt || copt || Copt || eopt || Eopt || popt || Popt || Sopt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
if ((Larg = atoi (optarg)) < 0 || Larg > LM20_PWLEN)
|
if ((Larg = atoi (optarg)) < 0 || Larg > LM20_PWLEN)
|
||||||
return eprint (1, "Minimum password length must be between "
|
return eprint (1, "Minimum password length must be between "
|
||||||
|
@ -456,15 +473,45 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || uopt
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || uopt
|
||||||
|| copt || Copt || eopt || Eopt || popt || Popt)
|
|| copt || Copt || eopt || Eopt || popt || Popt || Ropt)
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
Sopt = 1;
|
Sopt = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'R':
|
||||||
|
if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || uopt
|
||||||
|
|| copt || Copt || eopt || Eopt || popt || Popt || Sopt
|
||||||
|
|| server)
|
||||||
|
usage (stderr, 1);
|
||||||
|
Ropt = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usage (stderr, 1);
|
usage (stderr, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Ropt)
|
||||||
|
{
|
||||||
|
if (optind < argc)
|
||||||
|
usage (stderr, 1);
|
||||||
|
printf (
|
||||||
|
"This functionality stores a password in the registry for usage by services\n"
|
||||||
|
"which need to change the user context and require network access. Typical\n"
|
||||||
|
"applications are interactive remote logons using sshd, cron task, etc.\n"
|
||||||
|
"This password will always tried first when any privileged application is\n"
|
||||||
|
"about to switch the user context.\n\n"
|
||||||
|
"Note that storing even obfuscated passwords in the registry is not overly\n"
|
||||||
|
"secure. Use this feature only if the machine is adequately locked down.\n"
|
||||||
|
"Don't use this feature if you don't need network access within a remote\n"
|
||||||
|
"session. You can delete your stored password by specifying an empty password.\n\n");
|
||||||
|
strcpy (newpwd, getpass ("Enter your current password: "));
|
||||||
|
if (strcmp (newpwd, getpass ("Re-enter your current password: ")))
|
||||||
|
eprint (0, "Password is not identical.");
|
||||||
|
else if (cygwin_internal (CW_SET_PRIV_KEY, newpwd))
|
||||||
|
return eprint (0, "Storing password failed: %s", strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!server)
|
if (!server)
|
||||||
{
|
{
|
||||||
len = GetEnvironmentVariableW (L"LOGONSERVER", NULL, 0);
|
len = GetEnvironmentVariableW (L"LOGONSERVER", NULL, 0);
|
||||||
|
|
|
@ -899,6 +899,9 @@ User operations:
|
||||||
password aging rule.
|
password aging rule.
|
||||||
-p, --pwd-not-required no password required for USER.
|
-p, --pwd-not-required no password required for USER.
|
||||||
-P, --pwd-required password is required for USER.
|
-P, --pwd-required password is required for USER.
|
||||||
|
-R, --reg-store-pwd enter password to store it in the registry for
|
||||||
|
later usage by services to be able to switch
|
||||||
|
to this user context with network credentials."
|
||||||
|
|
||||||
System operations:
|
System operations:
|
||||||
-i, --inactive NUM set NUM of days before inactive accounts are disabled
|
-i, --inactive NUM set NUM of days before inactive accounts are disabled
|
||||||
|
@ -916,6 +919,15 @@ Other options:
|
||||||
If no option is given, change USER's password. If no user name is given,
|
If no option is given, change USER's password. If no user name is given,
|
||||||
operate on current user. System operations must not be mixed with user
|
operate on current user. System operations must not be mixed with user
|
||||||
operations. Don't specify a USER when triggering a system operation.
|
operations. Don't specify a USER when triggering a system operation.
|
||||||
|
|
||||||
|
Don't specify a user or any other option together with the -R option.
|
||||||
|
Non-Admin users can only store their password if cygserver is running and
|
||||||
|
the CYGWIN environment variable is set to contain the word 'server'.
|
||||||
|
Note that storing even obfuscated passwords in the registry is not overly
|
||||||
|
secure. Use this feature only if the machine is adequately locked down.
|
||||||
|
Don't use this feature if you don't need network access within a remote
|
||||||
|
session. You can delete your stored password by using `passwd -R' and
|
||||||
|
specifying an empty password.
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
<para> <command>passwd</command> changes passwords for user accounts.
|
<para> <command>passwd</command> changes passwords for user accounts.
|
||||||
|
@ -976,6 +988,31 @@ to <emphasis>LEN</emphasis> characters. Allowed values for the minimum
|
||||||
password length are 0 to 14. In any of the above cases, a value of 0
|
password length are 0 to 14. In any of the above cases, a value of 0
|
||||||
means `no restrictions'.</para>
|
means `no restrictions'.</para>
|
||||||
|
|
||||||
|
<para>Users can use the <command>passwd -R</command> to enter
|
||||||
|
a password which then gets stored in a special area of the registry,
|
||||||
|
which is also used by Windows to store passwords of accounts running
|
||||||
|
Windows services. When a privileged Cygwin application calls the
|
||||||
|
<command>set{e}uid(user_id)</command> system call, Cygwin checks if a
|
||||||
|
password for that user has been stored in this registry area. If so, it
|
||||||
|
uses this password to switch to this user account using that password.
|
||||||
|
This allows to logon through, for instance, <command>ssh</command> with
|
||||||
|
public key authentication and to get a full qualified user token with
|
||||||
|
all credentials for network access. However, the method has some
|
||||||
|
drawbacks security-wise. This is explained in more detail in the
|
||||||
|
<xref linkend="ntsec"></xref> section.</para>
|
||||||
|
|
||||||
|
<para>Please note that storing password in that registry area is a
|
||||||
|
privileged operation which only administrative accounts are allowed to
|
||||||
|
do. If normal, non-admin users should be allowed to enter their
|
||||||
|
passwords using <command>passwd -R</command>, it's required to run
|
||||||
|
<command>cygserver</command> as a service under the LocalSystem account
|
||||||
|
and the environment variable CYGWIN
|
||||||
|
(see <xref linkend="using-cygwinenv"></xref>)
|
||||||
|
must be set to contain the "server" setting before running
|
||||||
|
<command>passwd -R</command>. This only affects storing passwords.
|
||||||
|
Using passwords in privileged processes does not require
|
||||||
|
<command>cygserver</command> to run.</para>
|
||||||
|
|
||||||
<para>Limitations: Users may not be able to change their password on
|
<para>Limitations: Users may not be able to change their password on
|
||||||
some systems.</para>
|
some systems.</para>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue