Exemple #1
0
int main(int argc, char **argv)
{
  struct passwd *pw;
  char user[64], password[64], crypted[64];
  char *cp;

  if (argc != 2)
  {
    printf("Usage: passwd <user>\n");
    return 1;
  }

  strcpy(user, argv[1]);
  
  if ((pw = getpwnam(user)) == NULL)
  {
    printf("No such user.\n");
    return 1;
  }

  if (strcmp(pw->pw_passwd, "*"))
  {
    strcpy(password, getpass("Old password:"******"Incorrect password.\n");
      return 1;
    }
  }
  
  strcpy(password, getpass("New password:"******"Re-type new password:"******"New passwords don't match.\n");
    return 1;
  }
  
  strcpy(crypted, crypt(password, SALT));

  if (strcmp(pw->pw_passwd, crypted) == 0)
  {
    printf("Password unchanged.\n");
    return 1;
  }
  
  if (setpwnam(user, crypted))
  {
    printf("Update of passwd file failed.\n");
    return 1;
  }

  printf("Password changed.\n");

  return 0;
}
Exemple #2
0
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: "******"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: "******"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: "******"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);
}