]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - login-utils/passwd.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / login-utils / passwd.c
index f707c05217b9943b2d0014676f1d403a00c1fa9c..6741ee210a3e63d7a99e0c62d465dc02de949406 100644 (file)
@@ -3,26 +3,25 @@
  *
  * 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) 
-
- Hacked by Peter Breitenlohner, peb@mppmu.mpg.de,
- moved Alvaro's changes to setpwnam.c (so they get used
- by chsh and chfn as well). Oct 5, 96.
-
+ *
+ * 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 handlig (what?)
+ *     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 of using the -f
+ *     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
  *     auth.warning. (Of course, the password itself is not logged.)
  */
 
+ /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
+  * - 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 <string.h>
 #include <errno.h>
 #include <sys/resource.h>
-
-#if defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
-#include <crypt.h>
-#endif
-
-#if 0
-#  include "../version.h"
-#else
-char version[] = "admutil 1.18, 15-Oct-95";
-#endif
+#include <stdlib.h>
+#include "my_crypt.h"
+#include "setpwnam.h"
+#include "islocal.h"
+#include "nls.h"
+#include "env.h"
 
 #ifndef _PATH_CHFN
 # define _PATH_CHFN "/usr/bin/chfn"
@@ -81,9 +82,6 @@ char version[] = "admutil 1.18, 15-Oct-95";
 #include <syslog.h>
 #endif /* LOGALL */
 
-extern int is_local(char *);           /* islocal.c */
-extern int setpwnam(struct passwd *);  /* setpwnam.c */
-
 #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)+'.')
 
@@ -106,9 +104,8 @@ pexit(char *str, ...)
  * This would probably be the best place for checking against 
  * dictionaries. :-)
  */
-
-int check_passwd_string(char *passwd, char *string)
-{
+static int
+check_passwd_string(char *passwd, char *string) {
     int r;
     char *p, *q;
 
@@ -154,13 +151,13 @@ int check_passwd_string(char *passwd, char *string)
     return 1;
 }
        
-int check_passwd(char *passwd, char *oldpasswd, char *user, char *gecos)
-{
+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");
+       printf(_("The password must have at least 6 characters, try again.\n"));
        return 0;
     }
        
@@ -173,19 +170,19 @@ int check_passwd(char *passwd, char *oldpasswd, char *user, char *gecos)
     }
        
     if ( (other + digit + ucase + lcase) < 2) {
-       printf("The password must contain characters out of two of the following\n");
-       printf("classes:  upper and lower case letters, digits and non alphanumeric\n");
-       printf("characters. See passwd(1) for more information.\n");
+       printf(_("The password must contain characters out of two of the following\n"));
+       printf(_("classes:  upper and lower case letters, digits and non alphanumeric\n"));
+       printf(_("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");
+       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");
+       printf(_("Please don't use something like your username as password!\n"));
        return 0;
     }
 
@@ -196,14 +193,14 @@ int check_passwd(char *passwd, char *oldpasswd, char *user, char *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");
+                   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");
+               printf(_("Please don't use something like your realname as password!\n"));
                free (g);
                return 0;
            }
@@ -218,17 +215,16 @@ int check_passwd(char *passwd, char *oldpasswd, char *user, char *gecos)
     return 1; /* fine */
 }
 
-void usage()
-{
-    printf ("Usage: passwd [username [password]]\n");
-    printf("Only root may use the one and two argument forms.\n");
+#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(argc, argv)
-     int argc;
-     char *argv[];
-{
+main(int argc, char *argv[]) {
     struct passwd *pe;
     uid_t gotuid = getuid();
     char *pwdstr = NULL, *cryptstr, *oldstr;
@@ -252,6 +248,11 @@ main(argc, argv)
        {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) {
@@ -269,17 +270,17 @@ main(argc, argv)
            break;
        case 'V':
        case 'v':
-           printf("%s\n", version);
+           printf("%s\n", util_linux_version);
            exit(0);
        default:
-           fprintf(stderr, "Usage: passwd [-foqsvV] [user [password]]\n");
+           fprintf(stderr, _("Usage: passwd [-foqsvV] [user [password]]\n"));
            exit(1);
        } /* switch (c) */
     } /* while */
 
     if (fullname || shell) {
        char *args[100];
-       int i, j;
+       int i, j, errsv;
 
        setuid(getuid()); /* drop special privs. */
        if (fullname)
@@ -292,29 +293,33 @@ main(argc, argv)
 
        args[j] = NULL;
        execv(args[0], args);
-       fprintf(stderr, "Can't exec %s: %s\n", args[0], strerror(errno));
+       errsv = errno;
+       fprintf(stderr, _("Can't exec %s: %s\n"), args[0], strerror(errsv));
        exit(1);
     }
     
     switch (argc - optind) {
     case 0:
-       if ( !(user = getlogin()) ) {
+       /* 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");
+               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");
+           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");
+           printf(_("Only root can change the password for others.\n"));
            exit(1);
        } else {
            user = argv[optind];
@@ -322,33 +327,33 @@ main(argc, argv)
        }
        break;
     default:
-       printf("Too many arguments.\n");
+       printf(_("Too many arguments.\n"));
        exit (1);
     } /* switch */
 
     if(!(pe = getpwnam(user))) {
-       pexit("Can't find username anywhere. Is `%s' really a user?", 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.");
+       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!");
+       puts(_("UID and username does not match, imposter!"));
        exit(1);
     }
     
     if ( !silent )
-       printf( "Changing password for %s\n", user );
+       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: ");
+       oldstr = getpass(_("Enter old password: "));
        if(strncmp(pe->pw_passwd, crypt(oldstr, pe->pw_passwd), 13)) {
-           puts("Illegal password, imposter.");
+           puts(_("Illegal password, imposter."));
            exit(1);
        }
     }
@@ -360,9 +365,9 @@ main(argc, argv)
        /* password not set on command line by root, ask for it ... */
        
       redo_it:
-       pwdstr = getpass("Enter new password: ");
+       pwdstr = getpass(_("Enter new password: "));
        if (pwdstr[0] == '\0') {
-           puts("Password not changed.");
+           puts(_("Password not changed."));
            exit(1);
        }
 
@@ -372,10 +377,10 @@ main(argc, argv)
        
        strncpy(pwdstr1, pwdstr, 9);
        pwdstr1[9] = 0;
-       pwdstr = getpass("Re-type new password: ");
+       pwdstr = getpass(_("Re-type new password: "));
        
        if(strncmp(pwdstr, pwdstr1, 8)) {
-           puts("You misspelled it. Password not changed.");
+           puts(_("You misspelled it. Password not changed."));
            exit(1);
        }
     } /* pwdstr i.e. password set on command line */
@@ -390,28 +395,28 @@ main(argc, argv)
 #ifdef LOGALL
     openlog("passwd", 0, LOG_AUTH);
     if (gotuid)
-       syslog(LOG_NOTICE,"password changed, user %s",user);
+       syslog(LOG_NOTICE,_("password changed, user %s"),user);
     else {
        if ( !strcmp(user, "root") )
-           syslog(LOG_WARNING,"ROOT PASSWORD CHANGED");
+           syslog(LOG_WARNING,_("ROOT PASSWORD CHANGED"));
        else
-           syslog(LOG_NOTICE,"password changed by root, user %s",user);
+           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");
+    printf (_("calling setpwnam to set password.\n"));
 #else
     if (setpwnam( pe ) < 0) {
        perror( "setpwnam" );
-       printf( "Password *NOT* changed.  Try again later.\n" );
+       printf( _("Password *NOT* changed.  Try again later.\n" ));
        exit( 1 );
     }
 #endif
 
     if ( !silent )
-       printf("Password changed.\n");  
+       printf(_("Password changed.\n"));       
     exit(0);
 }