summaryrefslogtreecommitdiffstats
path: root/login-utils/passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'login-utils/passwd.c')
-rw-r--r--login-utils/passwd.c425
1 files changed, 0 insertions, 425 deletions
diff --git a/login-utils/passwd.c b/login-utils/passwd.c
deleted file mode 100644
index eb3303899..000000000
--- a/login-utils/passwd.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * passwd.c - change password on an account
- *
- * Initially written for Linux by Peter Orbaek <poe@daimi.aau.dk>
- * Currently maintained at ftp://ftp.daimi.aau.dk/pub/linux/poe/
- *
- * Hacked by Alvaro Martinez Echevarria, alvaro@enano.etsit.upm.es,
- * to allow peaceful coexistence with yp. Nov 94.
- *
- * Hacked to allow root to set passwd from command line.
- * by Arpad Magossanyi (mag@tas.vein.hu)
- */
-
-/*
- * Sun Oct 15 13:18:34 1995 Martin Schulze <joey@finlandia.infodrom.north.de>
- *
- * I have completely rewritten the whole argument handling (what?)
- * to support two things. First I wanted "passwd $user $pw" to
-
- (a very bad idea; command lines are visible to people doing ps
- or running a background job that just collects all command lines)
-
- * work and second I wanted simplicity checks to be done for
- * root, too. Only root can turn this off using the -f
- * switch. Okay, I started with this to support -V version
- * information, but one thing comes to the next. *sigh*
- * In a later step perhaps we'll be able to support shadow
- * passwords. (?)
- *
- * I have also included a DEBUG mode (-DDEBUG) to test the
- * argument handling _without_ any write attempt to
- * /etc/passwd.
- *
- * If you're paranoid about security on your system, you may want
- * to add -DLOGALL to CFLAGS. This will turn on additional syslog
- * logging of every password change. (user changes are logged as
- * auth.notice, but changing root's password is logged as
- * auth.warning. (Of course, the password itself is not logged.)
- */
-
- /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
- * - added Native Language Support
- * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fixed strerr(errno) in gettext calls
- */
-
-/*
- * Usage: passwd [username [password]]
- * Only root may use the one and two argument forms.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <termios.h>
-#include <getopt.h>
-#include <malloc.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <ctype.h>
-#include <time.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/resource.h>
-#include <stdlib.h>
-#include "my_crypt.h"
-#include "setpwnam.h"
-#include "islocal.h"
-#include "xstrncpy.h"
-#include "nls.h"
-#include "env.h"
-
-#ifndef _PATH_CHFN
-# define _PATH_CHFN "/usr/bin/chfn"
-# define _PATH_CHSH "/usr/bin/chsh"
-#endif
-
-#define LOGALL
-
-#ifdef LOGALL
-#include <syslog.h>
-#endif /* LOGALL */
-
-#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
-#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-
-static void
-pexit(char *str, ...)
-{
- va_list vlst;
-
- va_start(vlst, str);
- vfprintf(stderr, str, vlst);
- fprintf(stderr, ": ");
- perror("");
- va_end(vlst);
- exit(1);
-}
-
-/*
- * Do various checks for stupid passwords here...
- *
- * This would probably be the best place for checking against
- * dictionaries. :-)
- */
-static int
-check_passwd_string(char *passwd, char *string) {
- int r;
- char *p, *q;
-
- r = 0;
- /* test for string at the beginning of passwd */
- for (p = passwd, q = string; *q && *p; q++, p++) {
- if(tolower(*p) != tolower(*q)) {
- r++;
- break;
- }
- }
-
- /* test for reverse string at the beginning of passwd */
- for (p = passwd, q = string + strlen(string)-1;
- *p && q >= string; p++, q--) {
- if(tolower(*p) != tolower(*q)) {
- r++;
- break;
- }
- }
-
- /* test for string at the end of passwd */
- for (p = passwd + strlen(passwd)-1, q = string + strlen(string)-1;
- q >= string && p >= passwd; q--, p--) {
- if(tolower(*p) != tolower(*q)) {
- r++;
- break;
- }
- }
-
- /* test for reverse string at the beginning of passwd */
- for (p = passwd + strlen(passwd)-1, q = string;
- p >= passwd && *q; p--, q++) {
- if(tolower(*p) != tolower(*q)) {
- r++;
- break;
- }
- }
-
- if (r != 4) {
- return 0;
- }
- return 1;
-}
-
-static int
-check_passwd(char *passwd, char *oldpasswd, char *user, char *gecos) {
- int ucase, lcase, digit, other;
- char *c, *g, *p;
-
- if ( (strlen(passwd) < 6) ) {
- printf(_("The password must have at least 6 characters, try again.\n"));
- return 0;
- }
-
- other = digit = ucase = lcase = 0;
- for (p = passwd; *p; p++) {
- ucase = ucase || isupper(*p);
- lcase = lcase || islower(*p);
- digit = digit || isdigit(*p);
- other = other || !isalnum(*p);
- }
-
- if ( (other + digit + ucase + lcase) < 2) {
- printf(_("The password must contain characters out of two of "
- "the following\n"
- "classes: upper and lower case letters, digits and "
- "non alphanumeric\n"
- "characters. See passwd(1) for more information.\n"));
- return 0;
- }
-
- if ( oldpasswd[0] && !strncmp(oldpasswd, crypt(passwd, oldpasswd), 13) ) {
- printf(_("You cannot reuse the old password.\n"));
- return 0;
- }
-
- if ( !check_passwd_string(passwd, user) ) {
- printf(_("Please don't use something like your username as password!\n"));
- return 0;
- }
-
- /* check against realname */
- if ( (c = index(gecos, ',')) ) {
- if ( c-gecos && (g = (char *)malloc (c-gecos+1)) ) {
- strncpy (g, gecos, c-gecos);
- g[c-gecos] = 0;
- while ( (c=rindex(g, ' ')) ) {
- if ( !check_passwd_string(passwd, c+1) ) {
- printf(_("Please don't use something like your realname as password!\n"));
- free (g);
- return 0;
- }
- *c = '\0';
- } /* while */
- if ( !check_passwd_string(passwd, g) ) {
- printf(_("Please don't use something like your realname as password!\n"));
- free (g);
- return 0;
- }
- free (g);
- } /* if malloc */
- }
-
- /*
- * if ( !check_password_dict(passwd) ) ...
- */
-
- return 1; /* fine */
-}
-
-#if 0
-static void
-usage(void) {
- printf (_("Usage: passwd [username [password]]\n"));
- printf(_("Only root may use the one and two argument forms.\n"));
-}
-#endif
-
-int
-main(int argc, char *argv[]) {
- struct passwd *pe;
- uid_t gotuid = getuid();
- char *pwdstr = NULL, *cryptstr, *oldstr;
- char pwdstr1[10];
- char *user;
- time_t tm;
- char salt[2];
- int force_passwd = 0;
- int silent = 0;
- int c;
- int opt_index;
- int fullname = 0, shell = 0;
- static const struct option long_options[] =
- {
- {"fullname", no_argument, 0, 'f'},
- {"shell", no_argument, 0, 's'},
- {"force", no_argument, 0, 'o'},
- {"quiet", no_argument, 0, 'q'},
- {"silent", no_argument, 0, 'q'},
- {"version", no_argument, 0, 'v'},
- {0, 0, 0, 0}
- };
-
- sanitize_env();
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- optind = 0;
- while ((c = getopt_long(argc, argv, "foqsvV",
- long_options, &opt_index)) != -1) {
- switch (c) {
- case 'f':
- fullname = 1;
- break;
- case 's':
- shell = 1;
- break;
- case 'o':
- force_passwd = 1;
- break;
- case 'q':
- silent = 1;
- break;
- case 'V':
- case 'v':
- printf("%s\n", util_linux_version);
- exit(0);
- default:
- fprintf(stderr, _("Usage: passwd [-foqsvV] [user [password]]\n"));
- exit(1);
- } /* switch (c) */
- } /* while */
-
- if (fullname || shell) {
- char *args[100];
- int i, j, errsv;
-
- setuid(getuid()); /* drop special privs. */
- if (fullname)
- args[0] = _PATH_CHFN;
- else
- args[0] = _PATH_CHSH;
-
- for (i = optind, j = 1; (i < argc) && (j < 99); i++, j++)
- args[j] = argv[i];
-
- args[j] = NULL;
- execv(args[0], args);
- errsv = errno;
- fprintf(stderr, _("Can't exec %s: %s\n"), args[0], strerror(errsv));
- exit(1);
- }
-
- switch (argc - optind) {
- case 0:
- /* Why use getlogin()? Some systems allow having several
- usernames with the same uid, especially several root accounts.
- One changes the password for the username, not the uid. */
- if ( !(user = getlogin()) || !*user ) {
- if ( !(pe = getpwuid( getuid() )) ) {
- pexit(_("Cannot find login name"));
- } else
- user = pe->pw_name;
- }
- break;
- case 1:
- if(gotuid) {
- printf(_("Only root can change the password for others.\n"));
- exit (1);
- } else
- user = argv[optind];
- break;
- case 2:
- if(gotuid) {
- printf(_("Only root can change the password for others.\n"));
- exit(1);
- } else {
- user = argv[optind];
- pwdstr = argv[optind+1];
- }
- break;
- default:
- printf(_("Too many arguments.\n"));
- exit (1);
- } /* switch */
-
- if(!(pe = getpwnam(user))) {
- pexit(_("Can't find username anywhere. Is `%s' really a user?"), user);
- }
-
- if (!(is_local(user))) {
- puts(_("Sorry, I can only change local passwords. Use yppasswd instead."));
- exit(1);
- }
-
- /* if somebody got into changing utmp... */
- if(gotuid && gotuid != pe->pw_uid) {
- puts(_("UID and username does not match, imposter!"));
- exit(1);
- }
-
- if ( !silent )
- printf( _("Changing password for %s\n"), user );
-
- if ( (gotuid && pe->pw_passwd && pe->pw_passwd[0])
- || (!gotuid && !strcmp(user,"root")) ) {
- oldstr = getpass(_("Enter old password: "));
- if(strncmp(pe->pw_passwd, crypt(oldstr, pe->pw_passwd), 13)) {
- puts(_("Illegal password, imposter."));
- exit(1);
- }
- }
-
- if ( pwdstr ) { /* already set on command line */
- if ( !force_passwd && !check_passwd(pwdstr, pe->pw_passwd, user, pe->pw_gecos) )
- exit (1);
- } else {
- /* password not set on command line by root, ask for it ... */
-
- redo_it:
- pwdstr = getpass(_("Enter new password: "));
- if (pwdstr[0] == '\0') {
- puts(_("Password not changed."));
- exit(1);
- }
-
- if ( (gotuid || (!gotuid && !force_passwd))
- && !check_passwd(pwdstr, pe->pw_passwd, user, pe->pw_gecos) )
- goto redo_it;
-
- xstrncpy(pwdstr1, pwdstr, sizeof(pwdstr1));
- pwdstr = getpass(_("Re-type new password: "));
-
- if(strncmp(pwdstr, pwdstr1, 8)) {
- puts(_("You misspelled it. Password not changed."));
- exit(1);
- }
- } /* pwdstr i.e. password set on command line */
-
- time(&tm); tm ^= getpid();
- salt[0] = bin_to_ascii(tm & 0x3f);
- salt[1] = bin_to_ascii((tm >> 6) & 0x3f);
- cryptstr = crypt(pwdstr, salt);
-
- if (pwdstr[0] == 0) cryptstr = "";
-
-#ifdef LOGALL
- openlog("passwd", 0, LOG_AUTH);
- if (gotuid)
- syslog(LOG_NOTICE,_("password changed, user %s"),user);
- else {
- if ( !strcmp(user, "root") )
- syslog(LOG_WARNING,_("ROOT PASSWORD CHANGED"));
- else
- syslog(LOG_NOTICE,_("password changed by root, user %s"),user);
- }
- closelog();
-#endif /* LOGALL */
-
- pe->pw_passwd = cryptstr;
-#ifdef DEBUG
- printf (_("calling setpwnam to set password.\n"));
-#else
- if (setpwnam( pe ) < 0) {
- perror( "setpwnam" );
- printf( _("Password *NOT* changed. Try again later.\n" ));
- exit( 1 );
- }
-#endif
-
- if ( !silent )
- printf(_("Password changed.\n"));
- exit(0);
-}