Do not fail password check if shadow password does not exist - fall back to ordinary one
No binary (build failed)
—
(log yok)
| @@ -37,19 +37,24 @@ | |
| int correct_password(const struct passwd *pw) | |
| { | |
| - | char *unencrypted, *encrypted, *correct; |
| + | char *unencrypted, *encrypted; |
| + | const char *correct; |
| + | #if ENABLE_FEATURE_SHADOWPASSWDS |
| + | /* Using _r function to avoid pulling in static buffers */ |
| + | struct spwd spw; |
| + | struct spwd *result; |
| + | char buffer[256]; |
| + | #endif |
| - | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
| + | correct = pw->pw_passwd; |
| + | #if ENABLE_FEATURE_SHADOWPASSWDS |
| if (LONE_CHAR(pw->pw_passwd, 'x') || LONE_CHAR(pw->pw_passwd, '*')) { | |
| - | struct spwd *sp = getspnam(pw->pw_name); |
| - | |
| - | if (!sp) |
| - | bb_error_msg_and_die("no valid shadow password"); |
| - | |
| - | correct = sp->sp_pwdp; |
| - | } else |
| + | if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) |
| + | bb_error_msg("no valid shadow password, checking ordinary one"); |
| + | else |
| + | correct = spw.sp_pwdp; |
| + | } |
| #endif | |
| - | correct = pw->pw_passwd; |
| if (!correct || correct[0] == '\0') | |
| return 1; | |
| @@ -60,5 +65,5 @@ int correct_password(const struct passwd *pw) | |
| } | |
| encrypted = crypt(unencrypted, correct); | |
| memset(unencrypted, 0, strlen(unencrypted)); | |
| - | return (!strcmp(encrypted, correct)) ? 1 : 0; |
| + | return strcmp(encrypted, correct) == 0; |
| } | |
| @@ -342,15 +342,18 @@ static void username_tab_completion(char *ud, char *with_shash_flg) | |
| } | |
| } else { | |
| /* "~[^/]*" */ | |
| - | setpwent(); |
| + | /* Using _r function to avoid pulling in static buffers */ |
| + | char line_buff[PWD_BUFFER_SIZE]; |
| + | struct passwd pwd; |
| + | struct passwd *result; |
| - | while ((entry = getpwent()) != NULL) { |
| + | setpwent(); |
| + | while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) { |
| /* Null usernames should result in all users as possible completions. */ | |
| - | if ( /*!userlen || */ !strncmp(ud, entry->pw_name, userlen)) { |
| - | add_match(xasprintf("~%s/", entry->pw_name)); |
| + | if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) { |
| + | add_match(xasprintf("~%s/", pwd.pw_name)); |
| } | |
| } | |
| - | |
| endpwent(); | |
| } | |
| } | |
| @@ -121,9 +121,10 @@ int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf, | |
| /**********************************************************************/ | |
| /* For the various fget??ent funcs, return NULL on failure and a | |
| * pointer to the appropriate struct (statically allocated) on success. | |
| - | */ |
| + | * TODO: audit & stop using these in bbox, they pull in static buffers */ |
| /**********************************************************************/ | |
| + | #if 0 |
| struct passwd *fgetpwent(FILE *stream) | |
| { | |
| static char buffer[PWD_BUFFER_SIZE]; | |
| @@ -143,8 +144,10 @@ struct group *fgetgrent(FILE *stream) | |
| fgetgrent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); | |
| return result; | |
| } | |
| + | #endif |
| #if ENABLE_USE_BB_SHADOW | |
| + | #if 0 |
| struct spwd *fgetspent(FILE *stream) | |
| { | |
| static char buffer[PWD_BUFFER_SIZE]; | |
| @@ -154,6 +157,7 @@ struct spwd *fgetspent(FILE *stream) | |
| fgetspent_r(stream, &resultbuf, buffer, sizeof(buffer), &result); | |
| return result; | |
| } | |
| + | #endif |
| int sgetspent_r(const char *string, struct spwd *result_buf, | |
| char *buffer, size_t buflen, struct spwd **result) | |
| @@ -230,7 +234,9 @@ int sgetspent_r(const char *string, struct spwd *result_buf, | |
| #include "pwd_grp_internal.c" | |
| /**********************************************************************/ | |
| + | /* TODO: audit & stop using these in bbox, they pull in static buffers */ |
| + | /* This one has many users */ |
| struct passwd *getpwuid(uid_t uid) | |
| { | |
| static char buffer[PWD_BUFFER_SIZE]; | |
| @@ -241,6 +247,7 @@ struct passwd *getpwuid(uid_t uid) | |
| return result; | |
| } | |
| + | /* This one has many users */ |
| struct group *getgrgid(gid_t gid) | |
| { | |
| static char buffer[GRP_BUFFER_SIZE]; | |
| @@ -286,6 +293,7 @@ struct spwd *getspuid(uid_t uid) | |
| } | |
| #endif | |
| + | /* This one has many users */ |
| struct passwd *getpwnam(const char *name) | |
| { | |
| static char buffer[PWD_BUFFER_SIZE]; | |
| @@ -296,6 +304,7 @@ struct passwd *getpwnam(const char *name) | |
| return result; | |
| } | |
| + | /* This one has many users */ |
| struct group *getgrnam(const char *name) | |
| { | |
| static char buffer[GRP_BUFFER_SIZE]; | |
| @@ -306,7 +315,7 @@ struct group *getgrnam(const char *name) | |
| return result; | |
| } | |
| - | #if ENABLE_USE_BB_SHADOW |
| + | #if 0 //ENABLE_USE_BB_SHADOW |
| struct spwd *getspnam(const char *name) | |
| { | |
| static char buffer[PWD_BUFFER_SIZE]; | |
| @@ -318,6 +327,7 @@ struct spwd *getspnam(const char *name) | |
| } | |
| #endif | |
| + | /* This one doesn't use static buffers */ |
| int getpw(uid_t uid, char *buf) | |
| { | |
| struct passwd resultbuf; | |
| @@ -325,7 +335,7 @@ int getpw(uid_t uid, char *buf) | |
| char buffer[PWD_BUFFER_SIZE]; | |
| if (!buf) { | |
| - | errno=EINVAL; |
| + | errno = EINVAL; |
| } else if (!getpwuid_r(uid, &resultbuf, buffer, sizeof(buffer), &result)) { | |
| if (sprintf(buf, "%s:%s:%lu:%lu:%s:%s:%s\n", | |
| resultbuf.pw_name, resultbuf.pw_passwd, | |
| @@ -497,6 +507,7 @@ int getspent_r(struct spwd *resultbuf, char *buffer, | |
| } | |
| #endif | |
| + | #if 0 |
| struct passwd *getpwent(void) | |
| { | |
| static char line_buff[PWD_BUFFER_SIZE]; | |
| @@ -516,8 +527,9 @@ struct group *getgrent(void) | |
| getgrent_r(&gr, line_buff, sizeof(line_buff), &result); | |
| return result; | |
| } | |
| + | #endif |
| - | #if ENABLE_USE_BB_SHADOW |
| + | #if 0 //ENABLE_USE_BB_SHADOW |
| struct spwd *getspent(void) | |
| { | |
| static char line_buff[PWD_BUFFER_SIZE]; | |
| @@ -15,35 +15,37 @@ | |
| * return 1 on failure */ | |
| static int group_study(struct group *g) | |
| { | |
| + | enum { max = 65000 }; |
| FILE *etc_group; | |
| gid_t desired; | |
| - | |
| - | struct group *grp; |
| - | const int max = 65000; |
| + | /* Using _r function to avoid static buffers pulled in */ |
| + | char buffer[256]; |
| + | struct group grp; |
| + | struct group *result; |
| etc_group = xfopen(bb_path_group_file, "r"); | |
| /* make sure gr_name isn't taken, make sure gid is kosher */ | |
| desired = g->gr_gid; | |
| - | while ((grp = fgetgrent(etc_group))) { |
| - | if ((strcmp(grp->gr_name, g->gr_name)) == 0) { |
| + | while (!fgetgrent_r(etc_group, &grp, buffer, sizeof(buffer), &result)) { |
| + | if ((strcmp(grp.gr_name, g->gr_name)) == 0) { |
| bb_error_msg_and_die("%s: group already in use", g->gr_name); | |
| } | |
| - | if ((desired) && grp->gr_gid == desired) { |
| + | if ((desired) && grp.gr_gid == desired) { |
| bb_error_msg_and_die("%d: gid already in use", | |
| desired); | |
| } | |
| - | if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) { |
| - | g->gr_gid = grp->gr_gid; |
| + | if ((grp.gr_gid > g->gr_gid) && (grp.gr_gid < max)) { |
| + | g->gr_gid = grp.gr_gid; |
| } | |
| } | |
| - | fclose(etc_group); |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | fclose(etc_group); |
| /* gid */ | |
| + | g->gr_gid++; |
| if (desired) { | |
| g->gr_gid = desired; | |
| - | } else { |
| - | g->gr_gid++; |
| } | |
| /* return 1; */ | |
| return 0; | |
| @@ -65,12 +67,16 @@ static int addgroup(char *group, gid_t gid, const char *user) | |
| file = xfopen(bb_path_group_file, "a"); | |
| /* group:passwd:gid:userlist */ | |
| fprintf(file, "%s:%s:%d:%s\n", group, "x", gr.gr_gid, user); | |
| - | fclose(file); |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | fclose(file); |
| #if ENABLE_FEATURE_SHADOWPASSWDS | |
| - | file = xfopen(bb_path_gshadow_file, "a"); |
| - | fprintf(file, "%s:!::\n", group); |
| - | fclose(file); |
| + | file = fopen_or_warn(bb_path_gshadow_file, "a"); |
| + | if (file) { |
| + | fprintf(file, "%s:!::\n", group); |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| + | fclose(file); |
| + | } |
| #endif | |
| /* return 1; */ | |
| @@ -80,10 +86,8 @@ static int addgroup(char *group, gid_t gid, const char *user) | |
| /* | |
| * addgroup will take a login_name as its first parameter. | |
| * | |
| - | * gid |
| - | * |
| - | * can be customized via command-line parameters. |
| - | * ________________________________________________________________________ */ |
| + | * gid can be customized via command-line parameters. |
| + | */ |
| int addgroup_main(int argc, char **argv); | |
| int addgroup_main(int argc, char **argv) | |
| { | |
| @@ -103,6 +107,5 @@ int addgroup_main(int argc, char **argv) | |
| bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | |
| } | |
| - | /* werk */ |
| - | return addgroup(argv[0], gid, (argv[1]) ? argv[1] : ""); |
| + | return addgroup(argv[0], gid, argv[1] ? argv[1] : ""); |
| } | |
| @@ -10,19 +10,21 @@ | |
| #include "busybox.h" | |
| - | #define DONT_SET_PASS (1 << 4) |
| - | #define DONT_MAKE_HOME (1 << 6) |
| + | #define OPT_DONT_SET_PASS (1 << 4) |
| + | #define OPT_DONT_MAKE_HOME (1 << 6) |
| /* remix */ | |
| /* EDR recoded such that the uid may be passed in *p */ | |
| static int passwd_study(const char *filename, struct passwd *p) | |
| { | |
| - | struct passwd *pw; |
| + | enum { min = 500, max = 65000 }; |
| FILE *passwd; | |
| - | |
| - | const int min = 500; |
| - | const int max = 65000; |
| + | /* We are using reentrant fgetpwent_r() in order to avoid |
| + | * pulling in static buffers from libc (think static build here) */ |
| + | char buffer[256]; |
| + | struct passwd pw; |
| + | struct passwd *result; |
| passwd = xfopen(filename, "r"); | |
| @@ -34,14 +36,14 @@ static int passwd_study(const char *filename, struct passwd *p) | |
| * make sure login isn't taken; | |
| * find free uid and gid; | |
| */ | |
| - | while ((pw = fgetpwent(passwd))) { |
| - | if (strcmp(pw->pw_name, p->pw_name) == 0) { |
| + | while (!fgetpwent_r(passwd, &pw, buffer, sizeof(buffer), &result)) { |
| + | if (strcmp(pw.pw_name, p->pw_name) == 0) { |
| /* return 0; */ | |
| return 1; | |
| } | |
| - | if ((pw->pw_uid >= p->pw_uid) && (pw->pw_uid < max) |
| - | && (pw->pw_uid >= min)) { |
| - | p->pw_uid = pw->pw_uid + 1; |
| + | if ((pw.pw_uid >= p->pw_uid) && (pw.pw_uid < max) |
| + | && (pw.pw_uid >= min)) { |
| + | p->pw_uid = pw.pw_uid + 1; |
| } | |
| } | |
| @@ -85,7 +87,7 @@ static void passwd_wrapper(const char *login) | |
| } | |
| /* putpwent(3) remix */ | |
| - | static int adduser(struct passwd *p, unsigned long flags) |
| + | static int adduser(struct passwd *p) |
| { | |
| FILE *file; | |
| int addgroup = !p->pw_gid; | |
| @@ -130,7 +132,7 @@ static int adduser(struct passwd *p, unsigned long flags) | |
| /* Clear the umask for this process so it doesn't | |
| * * screw up the permissions on the mkdir and chown. */ | |
| umask(0); | |
| - | if (!(flags & DONT_MAKE_HOME)) { |
| + | if (!(option_mask32 & OPT_DONT_MAKE_HOME)) { |
| /* Set the owner and group so it is owned by the new user, | |
| then fix up the permissions to 2755. Can't do it before | |
| since chown will clear the setgid bit */ | |
| @@ -141,7 +143,7 @@ static int adduser(struct passwd *p, unsigned long flags) | |
| } | |
| } | |
| - | if (!(flags & DONT_SET_PASS)) { |
| + | if (!(option_mask32 & OPT_DONT_SET_PASS)) { |
| /* interactively set passwd */ | |
| passwd_wrapper(p->pw_name); | |
| } | |
| @@ -163,7 +165,6 @@ int adduser_main(int argc, char **argv) | |
| { | |
| struct passwd pw; | |
| const char *usegroup = NULL; | |
| - | unsigned long flags; |
| /* got root? */ | |
| if (geteuid()) { | |
| @@ -176,7 +177,7 @@ int adduser_main(int argc, char **argv) | |
| /* check for min, max and missing args and exit on error */ | |
| opt_complementary = "-1:?1:?"; | |
| - | flags = getopt32(argc, argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup); |
| + | getopt32(argc, argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup); |
| /* create string for $HOME if not specified already */ | |
| if (!pw.pw_dir) { | |
| @@ -191,5 +192,5 @@ int adduser_main(int argc, char **argv) | |
| pw.pw_gid = usegroup ? xgroup2gid(usegroup) : 0; /* exits on failure */ | |
| /* grand finale */ | |
| - | return adduser(&pw, flags); |
| + | return adduser(&pw); |
| } | |
| @@ -252,6 +252,13 @@ int passwd_main(int argc, char **argv) | |
| struct rlimit rlimit_fsize; | |
| char c; | |
| + | #if ENABLE_FEATURE_SHADOWPASSWDS |
| + | /* Using _r function to avoid pulling in static buffers */ |
| + | struct spwd spw; |
| + | struct spwd *result; |
| + | char buffer[256]; |
| + | #endif |
| + | |
| logmode = LOGMODE_BOTH; | |
| openlog(applet_name, LOG_NOWAIT, LOG_AUTH); | |
| opt = getopt32(argc, argv, "a:lud", &opt_a); | |
| @@ -278,17 +285,14 @@ int passwd_main(int argc, char **argv) | |
| filename = bb_path_passwd_file; | |
| #if ENABLE_FEATURE_SHADOWPASSWDS | |
| - | { |
| - | struct spwd *sp = getspnam(name); |
| - | if (!sp) { |
| - | /* LOGMODE_BOTH */ |
| - | bb_error_msg("no record of %s in %s, using %s", |
| - | name, bb_path_shadow_file, |
| - | bb_path_passwd_file); |
| - | } else { |
| - | filename = bb_path_shadow_file; |
| - | pw->pw_passwd = sp->sp_pwdp; |
| - | } |
| + | if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) { |
| + | /* LOGMODE_BOTH */ |
| + | bb_error_msg("no record of %s in %s, using %s", |
| + | name, bb_path_shadow_file, |
| + | bb_path_passwd_file); |
| + | } else { |
| + | filename = bb_path_shadow_file; |
| + | pw->pw_passwd = spw.sp_pwdp; |
| } | |
| #endif | |
| @@ -43,6 +43,12 @@ int sulogin_main(int argc, char **argv) | |
| const char * const *p; | |
| struct passwd *pwd; | |
| const char *shell; | |
| + | #if ENABLE_FEATURE_SHADOWPASSWDS |
| + | /* Using _r function to avoid pulling in static buffers */ |
| + | char buffer[256]; |
| + | struct spwd spw; |
| + | struct spwd *result; |
| + | #endif |
| logmode = LOGMODE_BOTH; | |
| openlog(applet_name, 0, LOG_AUTH); | |
| @@ -76,13 +82,10 @@ int sulogin_main(int argc, char **argv) | |
| } | |
| #if ENABLE_FEATURE_SHADOWPASSWDS | |
| - | { |
| - | struct spwd *spwd = getspnam(pwd->pw_name); |
| - | if (!spwd) { |
| - | goto auth_error; |
| - | } |
| - | pwd->pw_passwd = spwd->sp_pwdp; |
| + | if (getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result)) { |
| + | goto auth_error; |
| } | |
| + | pwd->pw_passwd = spw.sp_pwdp; |
| #endif | |
| while (1) { | |
| @@ -1,8 +1,19 @@ | |
| #!/bin/sh | |
| - | printf "%9s %11s %9s %9s %s\n" "text+data" text+rodata rwdata bss filename |
| + | t_text=0 |
| + | t_data=0 |
| + | t_bss=0 |
| + | |
| + | printf "%9s %11s %9s %9s %s\n" "text+data" "text+rodata" rwdata bss filename |
| + | |
| find -name '*.o' | grep -v '^\./scripts/' | grep -vF built-in.o \ | |
| | sed 's:^\./::' | xargs "${CROSS_COMPILE}size" | grep '^ *[0-9]' \ | |
| - | | while read text data bss dec hex filename; do |
| + | | { |
| + | while read text data bss dec hex filename; do |
| + | t_text=$((t_text+text)) |
| + | t_data=$((t_data+data)) |
| + | t_bss=$((t_bss+bss)) |
| printf "%9d %11d %9d %9d %s\n" $((text+data)) $text $data $bss "$filename" | |
| - | done | sort -r |
| + | done |
| + | printf "%9d %11d %9d %9d %s\n" $((t_text+t_data)) $t_text $t_data $t_bss "TOTAL" |
| + | } | sort -r |