diff -Naru ori/tinylogin-1.4/Makefile tinylogin-1.4/Makefile --- ori/tinylogin-1.4/Makefile 2003-01-03 12:56:33.000000000 +0200 +++ tinylogin-1.4/Makefile 2005-04-11 05:51:44.000000000 +0300 @@ -74,9 +74,15 @@ # If you are running a cross compiler, you may want to set this # to something more interesting, like "powerpc-linux-". CROSS = -CC = $(CROSS)gcc -AR = $(CROSS)ar -STRIPTOOL = $(CROSS)strip +#CC = $(CROSS)gcc +#CC = mipsel-uclibc-gcc +CC = powerpc-linux-uclibc-gcc +#AR = $(CROSS)ar +#AR = mipsel-uclibc-ar +AR = powerpc-linux-uclibc-ar +#STRIPTOOL = $(CROSS)strip +#STRIPTOOL = mipsel-uclibc-strip +STRIPTOOL = powerpc-linux-uclibc-strip # To compile vs uClibc, just use the compiler wrapper built by uClibc... # Everything should compile and work as expected these days... diff -Naru ori/tinylogin-1.4/adduser.c tinylogin-1.4/adduser.c --- ori/tinylogin-1.4/adduser.c 2002-12-12 10:46:03.000000000 +0200 +++ tinylogin-1.4/adduser.c 2005-04-11 05:51:44.000000000 +0300 @@ -60,6 +60,9 @@ #endif +static int my_adduser(const char *filename, struct passwd *p, char *pwd); +extern int my_passwd_main(const char *login, const char *pwd); + /* remix */ /* EDR recoded such that the uid may be passed in *p */ static int passwd_study(const char *filename, struct passwd *p) @@ -135,6 +138,13 @@ error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually", login); } +//royc add +static void my_passwd_wrapper(const char *login, const char *pwd) +{ + my_passwd_main(login, pwd); +} +//royc end + /* putpwent(3) remix */ static int adduser(const char *filename, struct passwd *p) { @@ -215,12 +225,101 @@ if (chmod(p->pw_dir, 02755)) { perror_msg("%s", p->pw_dir); } + /* interactively set passwd */ passwd_wrapper(p->pw_name); return 0; } +static int my_adduser(const char *filename, struct passwd *p, char *pwd) +{ + FILE *passwd; + int r; +#ifdef CONFIG_FEATURE_SHADOWPASSWDS + FILE *shadow; + struct spwd *sp; +#endif + + /* make sure everything is kosher and setup uid && gid */ + passwd = wfopen(filename, "a"); + if (passwd == NULL) { + /* return -1; */ + return 1; + } + fseek(passwd, 0, SEEK_END); + + /* if (passwd_study(filename, p) == 0) { */ + r = passwd_study(filename, p); + if (r) { + if (r == 1) + error_msg("%s: login already in use", p->pw_name); + else if (r == 2) + error_msg("illegal uid or no uids left"); + else if (r == 3) + error_msg("group name %s already in use", p->pw_name); + else + error_msg("generic error."); + /* return -1; */ + return 1; + } + + /* add to passwd */ + if (putpwent(p, passwd) == -1) { + /* return -1; */ + return 1; + } + fclose(passwd); + +#ifdef CONFIG_FEATURE_SHADOWPASSWDS + /* add to shadow if necessary */ + if (shadow_enabled) { + shadow = wfopen(SHADOW_FILE, "a"); + if (shadow == NULL) { + /* return -1; */ + return 1; + } + fseek(shadow, 0, SEEK_END); + sp = pwd_to_spwd(p); + sp->sp_max = 99999; /* debianish */ + sp->sp_warn = 7; + fprintf(shadow, "%s:!:%ld:%ld:%ld:%ld:::\n", + sp->sp_namp, sp->sp_lstchg, sp->sp_min, sp->sp_max, + sp->sp_warn); + fclose(shadow); + } +#endif + + /* add to group */ + /* addgroup should be responsible for dealing w/ gshadow */ + addgroup_wrapper(p->pw_name, p->pw_gid); + + /* Clear the umask for this process so it doesn't + * * screw up the permissions on the mkdir and chown. */ + umask(0); + + /* mkdir */ +// if (mkdir(p->pw_dir, 0755)) { +// perror_msg("%s", p->pw_dir); +// } +// /* Set the owner and group so it is owned by the new user. */ +// if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { +// perror_msg("%s", p->pw_dir); +// } +// /* Now fix up the permissions to 2755. Can't do it before now +// * since chown will clear the setgid bit */ +// if (chmod(p->pw_dir, 02755)) { +// perror_msg("%s", p->pw_dir); +// } + + /* interactively set passwd */ + //royc add + //passwd_wrapper(p->pw_name); + my_passwd_wrapper(p->pw_name, pwd); + //royc end + + return 0; +} /* return current uid (root is always uid == 0, right?) */ static inline uid_t i_am_not_root(void) @@ -239,11 +338,13 @@ * ________________________________________________________________________ */ int adduser_main(int argc, char **argv) { + int set_passwd; int opt; const char *login; const char *gecos; const char *home = NULL; const char *shell; + const char *pwd = NULL; struct passwd pw; @@ -255,7 +356,10 @@ shell = default_shell; /* get args */ - while ((opt = getopt (argc, argv, "h:g:s:")) != -1) { + //royc add + set_passwd = 0; + //royc end + while ((opt = getopt (argc, argv, "h:g:s:p:")) != -1) { switch (opt) { case 'h': home = optarg; @@ -266,6 +370,12 @@ case 's': shell = optarg; break; + //royc add + case 'p': + set_passwd = 1; + pwd = optarg; + break; + //royc end default: show_usage (); break; @@ -302,7 +412,15 @@ pw.pw_shell = (char *)shell; /* grand finale */ - return adduser(PASSWD_FILE, &pw); + if(set_passwd == 1) + { + return my_adduser(PASSWD_FILE, &pw, (char*)pwd); + } + else + { + return adduser(PASSWD_FILE, &pw); + } + } -/* $Id: adduser.c,v 1.37 2002/12/12 08:46:03 andersen Exp $ */ +/* $Id: adduser.c,v 1.1.1.1 2005/04/11 02:51:44 jack Exp $ */ diff -Naru ori/tinylogin-1.4/login.c tinylogin-1.4/login.c --- ori/tinylogin-1.4/login.c 2002-12-03 22:11:18.000000000 +0200 +++ tinylogin-1.4/login.c 2005-04-11 05:51:44.000000000 +0300 @@ -195,8 +195,10 @@ time_t start, now; time ( &start ); - now = start; - while ( difftime ( now, start ) < FAIL_DELAY) { + //now = start; + time( &now ); + //while ( difftime ( now, start ) < FAIL_DELAY) { + while ( (now-start) < FAIL_DELAY) { sleep ( FAIL_DELAY ); time ( &now ); } diff -Naru ori/tinylogin-1.4/passwd.c tinylogin-1.4/passwd.c --- ori/tinylogin-1.4/passwd.c 2002-11-07 04:34:15.000000000 +0200 +++ tinylogin-1.4/passwd.c 2005-04-11 05:51:44.000000000 +0300 @@ -19,7 +19,7 @@ static int create_backup(const char *backup, FILE * fp); static int new_password(const struct passwd *pw, int amroot, int algo); static void set_filesize_limit(); - +static int my_new_password(const struct passwd *pw, const char *pwd, int algo); int get_algo(char *a) { @@ -76,11 +76,11 @@ lock.l_type = F_UNLCK; snprintf(buf, sizeof buf, "%s-", filename); - if (create_backup(buf, fp)) { - fcntl(fileno(fp), F_SETLK, &lock); - fclose(fp); - return 1; - } +// if (create_backup(buf, fp)) { +// fcntl(fileno(fp), F_SETLK, &lock); +// fclose(fp); +// return 1; +// } snprintf(buf, sizeof buf, "%s+", filename); mask = umask(0777); out_fp = fopen(buf, "w"); @@ -150,17 +150,28 @@ int dflg = 0; /* -d - delete password */ const struct passwd *pw; unsigned short ruid; + + //royc add + int set_passwd=0; + const char *newpwd = NULL; + //royc end #ifdef CONFIG_FEATURE_SHADOWPASSWDS const struct spwd *sp; #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ amroot = (getuid() == 0); openlog("passwd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); - while ((flag = getopt(argc, argv, "a:dlu")) != EOF) { + while ((flag = getopt(argc, argv, "a:n:dlu")) != EOF) { switch (flag) { case 'a': algo = get_algo(optarg); break; +//royc add + case 'n': + set_passwd = 1; + newpwd = optarg; + break; +//royc end case 'd': dflg++; break; @@ -217,9 +228,20 @@ } } printf("Changing password for %s\n", name); - if (new_password(pw, amroot, algo)) { - error_msg_and_die( "The password for %s is unchanged.\n", name); + //royc modify + if (set_passwd == 1) + { + if (my_new_password(pw, newpwd, algo)) { + error_msg_and_die( "The password for %s is unchanged.\n", name); + } } + else + { + if (new_password(pw, amroot, algo)) { + error_msg_and_die( "The password for %s is unchanged.\n", name); + } + } + //royc end } else if (lflg) { if (crypt_passwd[0] != '!') { memmove(&crypt_passwd[1], crypt_passwd, @@ -256,7 +278,128 @@ return (0); } +int my_passwd_main(const char *login, const char *pwd) +{ + int amroot; + char *cp; + char *np; + char *name; + char *myname; + //int flag; + int algo = 0; /* -a - password algorithm */ + int lflg = 0; /* -l - lock account */ + int uflg = 0; /* -u - unlock account */ + int dflg = 0; /* -d - delete password */ + const struct passwd *pw; + unsigned short ruid; +#ifdef CONFIG_FEATURE_SHADOWPASSWDS + const struct spwd *sp; +#endif /* CONFIG_FEATURE_SHADOWPASSWDS */ + + amroot = (getuid() == 0); + openlog("passwd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); +// while ((flag = getopt(argc, argv, "a:dlu")) != EOF) { +// switch (flag) { +// case 'a': +// algo = get_algo(optarg); +// break; +// case 'd': +// dflg++; +// break; +// case 'l': +// lflg++; +// break; +// case 'u': +// uflg++; +// break; +// default: +// show_usage(); +// } +// } + ruid = getuid(); + pw = (struct passwd *) getpwuid(ruid); + if (!pw) { + error_msg_and_die("Cannot determine your user name.\n"); + } + myname = (char *) xstrdup(pw->pw_name); +// if (optind < argc) { +// name = argv[optind]; +// } else { +// name = myname; +// } + name = (char*)login; +// if ((lflg || uflg || dflg) && (optind >= argc || !amroot)) { +// show_usage(); +// } + pw = getpwnam(name); + if (!pw) { + error_msg_and_die("Unknown user %s\n", name); + } + if (!amroot && pw->pw_uid != getuid()) { + syslog(LOG_WARNING, "can't change pwd for `%s'", name); + error_msg_and_die("Permission denied.\n"); + } +#ifdef CONFIG_FEATURE_SHADOWPASSWDS + sp = getspnam(name); + if (!sp) { + sp = (struct spwd *) pwd_to_spwd(pw); + } + cp = sp->sp_pwdp; + np = sp->sp_namp; +#else + cp = pw->pw_passwd; + np = name; +#endif /* CONFIG_FEATURE_SHADOWPASSWDS */ + + safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); + + if (!(dflg || lflg || uflg)) { + if (!amroot) { + if (cp[0] == '!') { + syslog(LOG_WARNING, "password locked for `%s'", np); + error_msg_and_die( "The password for `%s' cannot be changed.\n", np); + } + } + printf("Changing password for %s\n", name); + if (my_new_password(pw, pwd, algo)) { + error_msg_and_die( "The password for %s is unchanged.\n", name); + } + } else if (lflg) { + if (crypt_passwd[0] != '!') { + memmove(&crypt_passwd[1], crypt_passwd, + sizeof crypt_passwd - 1); + crypt_passwd[sizeof crypt_passwd - 1] = '\0'; + crypt_passwd[0] = '!'; + } + } else if (uflg) { + if (crypt_passwd[0] == '!') { + memmove(crypt_passwd, &crypt_passwd[1], + sizeof crypt_passwd - 1); + } + } else if (dflg) { + crypt_passwd[0] = '\0'; + } + set_filesize_limit(30000); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + umask(077); + if (setuid(0)) { + syslog(LOG_ERR, "can't setuid(0)"); + error_msg_and_die( "Cannot change ID to root.\n"); + } + if (!update_passwd(pw, crypt_passwd)) { + syslog(LOG_INFO, "password for `%s' changed by user `%s'", name, + myname); + printf("Password changed.\n"); + } else { + syslog(LOG_WARNING, + "an error occurred updating the password file"); + error_msg_and_die("An error occurred updating the password file.\n"); + } + return (0); +} static int create_backup(const char *backup, FILE * fp) { @@ -327,6 +470,20 @@ } +static int my_new_password(const struct passwd *pw, const char *pwd, int algo) +{ + char *cp; + char pass[200]; + + bzero(pass, strlen(pass)); + safe_strncpy(pass, pwd, sizeof(pass)); + + cp = pw_encrypt(pass, crypt_make_salt()); + bzero(pass, sizeof pass); + safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); + return 0; +} + static int new_password(const struct passwd *pw, int amroot, int algo) { char *clear; @@ -346,8 +503,10 @@ syslog(LOG_WARNING, "incorrect password for `%s'", pw->pw_name); time(&start); - now = start; - while (difftime(now, start) < FAIL_DELAY) { + //now = start; + time( &now ); + //while (difftime(now, start) < FAIL_DELAY) { + while ( (now-start) < FAIL_DELAY) { sleep(FAIL_DELAY); time(&now); } @@ -392,7 +551,7 @@ return 1; } bzero(cp, strlen(cp)); - bzero(orig, sizeof(orig)); + bzero(orig, sizeof(orig)); #ifdef CONFIG_FEATURE_SHA1_PASSWORDS if (algo == 2) { @@ -401,8 +560,9 @@ #endif if (algo == 1) { cp = pw_encrypt(pass, "$1$"); - } else + } else { cp = pw_encrypt(pass, crypt_make_salt()); + } bzero(pass, sizeof pass); safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); return 0; diff -Naru ori/tinylogin-1.4/sulogin.c tinylogin-1.4/sulogin.c --- ori/tinylogin-1.4/sulogin.c 2002-06-23 06:09:08.000000000 +0300 +++ tinylogin-1.4/sulogin.c 2005-04-11 05:51:44.000000000 +0300 @@ -164,8 +164,10 @@ break; } time(&start); - now = start; - while (difftime(now, start) < FAIL_DELAY) { + //now = start; + time( &now ); + //while (difftime(now, start) < FAIL_DELAY) { + while ( (now-start) < FAIL_DELAY) { sleep(FAIL_DELAY); time(&now); }