Port over the last of the tinylogin applets
-Erik
This commit is contained in:
parent
0fbff134f4
commit
27f64e1f4e
@ -335,6 +335,9 @@
|
|||||||
#ifdef CONFIG_OD
|
#ifdef CONFIG_OD
|
||||||
APPLET(od, od_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
APPLET(od, od_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_PASSWD
|
||||||
|
APPLET(passwd, passwd_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_PIDOF
|
#ifdef CONFIG_PIDOF
|
||||||
APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
@ -419,6 +422,9 @@
|
|||||||
#ifdef CONFIG_SU
|
#ifdef CONFIG_SU
|
||||||
APPLET(su, su_main, _BB_DIR_BIN, _BB_SUID_ALWAYS)
|
APPLET(su, su_main, _BB_DIR_BIN, _BB_SUID_ALWAYS)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_SULOGIN
|
||||||
|
APPLET(sulogin, sulogin_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_SWAPONOFF
|
#ifdef CONFIG_SWAPONOFF
|
||||||
APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
|
APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
@ -505,6 +511,9 @@
|
|||||||
#ifdef CONFIG_VI
|
#ifdef CONFIG_VI
|
||||||
APPLET(vi, vi_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
APPLET(vi, vi_main, _BB_DIR_BIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_VLOCK
|
||||||
|
APPLET(vlock, vlock_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_WATCHDOG
|
#ifdef CONFIG_WATCHDOG
|
||||||
APPLET(watchdog, watchdog_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
|
APPLET(watchdog, watchdog_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,6 +39,16 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "pwd.h"
|
||||||
|
#include "grp.h"
|
||||||
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
#include "shadow_.h"
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_FEATURE_SHA1_PASSWORDS
|
||||||
|
# include "sha1.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__)
|
#if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__)
|
||||||
/* libc5 doesn't define socklen_t */
|
/* libc5 doesn't define socklen_t */
|
||||||
typedef unsigned int socklen_t;
|
typedef unsigned int socklen_t;
|
||||||
@ -260,6 +270,15 @@ extern const char * const too_few_args;
|
|||||||
extern const char * const name_longer_than_foo;
|
extern const char * const name_longer_than_foo;
|
||||||
extern const char * const unknown;
|
extern const char * const unknown;
|
||||||
extern const char * const can_not_create_raw_socket;
|
extern const char * const can_not_create_raw_socket;
|
||||||
|
extern const char * const nologin_file;
|
||||||
|
extern const char * const passwd_file;
|
||||||
|
extern const char * const shadow_file;
|
||||||
|
extern const char * const gshadow_file;
|
||||||
|
extern const char * const group_file;
|
||||||
|
extern const char * const securetty_file;
|
||||||
|
extern const char * const motd_file;
|
||||||
|
extern const char * const issue_file;
|
||||||
|
extern const char * const _path_login;
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_DEVFS
|
#ifdef CONFIG_FEATURE_DEVFS
|
||||||
# define CURRENT_VC "/dev/vc/0"
|
# define CURRENT_VC "/dev/vc/0"
|
||||||
@ -299,4 +318,15 @@ void reset_ino_dev_hashtable(void);
|
|||||||
extern size_t xstrlen(const char *string);
|
extern size_t xstrlen(const char *string);
|
||||||
#define strlen(x) xstrlen(x)
|
#define strlen(x) xstrlen(x)
|
||||||
|
|
||||||
|
|
||||||
|
#define FAIL_DELAY 3
|
||||||
|
extern void change_identity ( const struct passwd *pw );
|
||||||
|
extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args );
|
||||||
|
extern int restricted_shell ( const char *shell );
|
||||||
|
extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw );
|
||||||
|
extern int correct_password ( const struct passwd *pw );
|
||||||
|
extern char *pw_encrypt(const char *clear, const char *salt);
|
||||||
|
extern struct spwd *pwd_to_spwd(const struct passwd *pw);
|
||||||
|
extern int obscure(const char *old, const char *newval, const struct passwd *pwdp);
|
||||||
|
|
||||||
#endif /* __LIBCONFIG_H__ */
|
#endif /* __LIBCONFIG_H__ */
|
||||||
|
82
include/shadow_.h
Normal file
82
include/shadow_.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1988 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _H_SHADOW
|
||||||
|
#define _H_SHADOW
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_SHADOW
|
||||||
|
#include <shadow.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This information is not derived from AT&T licensed sources. Posted
|
||||||
|
* to the USENET 11/88, and updated 11/90 with information from SVR4.
|
||||||
|
*
|
||||||
|
* $Id: shadow_.h,v 1.1 2002/06/23 04:24:20 andersen Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef long sptime;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shadow password security file structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct spwd {
|
||||||
|
char *sp_namp; /* login name */
|
||||||
|
char *sp_pwdp; /* encrypted password */
|
||||||
|
sptime sp_lstchg; /* date of last change */
|
||||||
|
sptime sp_min; /* minimum number of days between changes */
|
||||||
|
sptime sp_max; /* maximum number of days between changes */
|
||||||
|
sptime sp_warn; /* number of days of warning before password
|
||||||
|
expires */
|
||||||
|
sptime sp_inact; /* number of days after password expires
|
||||||
|
until the account becomes unusable. */
|
||||||
|
sptime sp_expire; /* days since 1/1/70 until account expires */
|
||||||
|
unsigned long sp_flag; /* reserved for future use */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shadow password security file functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h> /* for FILE */
|
||||||
|
|
||||||
|
extern struct spwd *getspent(void);
|
||||||
|
extern struct spwd *sgetspent(const char *);
|
||||||
|
extern struct spwd *fgetspent(FILE *);
|
||||||
|
extern void setspent(void);
|
||||||
|
extern void endspent(void);
|
||||||
|
extern int putspent(const struct spwd *, FILE *);
|
||||||
|
extern struct spwd *getspnam(const char *name);
|
||||||
|
extern struct spwd *pwd_to_spwd(const struct passwd *pw);
|
||||||
|
|
||||||
|
#endif /* USE_LOCAL_SHADOW */
|
||||||
|
|
||||||
|
#endif /* _H_SHADOW */
|
@ -1321,6 +1321,24 @@
|
|||||||
"Write an unambiguous representation, octal bytes by default, of FILE\n"\
|
"Write an unambiguous representation, octal bytes by default, of FILE\n"\
|
||||||
"to standard output. With no FILE, or when FILE is -, read standard input."
|
"to standard output. With no FILE, or when FILE is -, read standard input."
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEATURE_SHA1_PASSWORDS
|
||||||
|
#define PASSWORD_ALG_TYPES(a) a
|
||||||
|
#else
|
||||||
|
#define PASSWORD_ALG_TYPES(a)
|
||||||
|
#endif
|
||||||
|
#define passwd_trivial_usage \
|
||||||
|
"[OPTION] [name]"
|
||||||
|
#define passwd_full_usage \
|
||||||
|
"CChange a user password. If no name is specified,\n" \
|
||||||
|
"changes the password for the current user.\n" \
|
||||||
|
"Options:\n" \
|
||||||
|
"\t-a\tDefine which algorithm shall be used for the password.\n" \
|
||||||
|
"\t\t\t(Choices: des, md5" \
|
||||||
|
CONFIG_FEATURE_SHA1_PASSWORDS(", sha1") \
|
||||||
|
")\n\t-d\tDelete the password for the specified user account.\n" \
|
||||||
|
"\t-l\tLocks (disables) the specified user account.\n" \
|
||||||
|
"\t-u\tUnlocks (re-enables) the specified user account.";
|
||||||
|
|
||||||
#define pidof_trivial_usage \
|
#define pidof_trivial_usage \
|
||||||
"process-name [process-name ...]"
|
"process-name [process-name ...]"
|
||||||
#define pidof_full_usage \
|
#define pidof_full_usage \
|
||||||
@ -1586,6 +1604,15 @@
|
|||||||
"Options:\n" \
|
"Options:\n" \
|
||||||
"\t-p\tPreserve environment"
|
"\t-p\tPreserve environment"
|
||||||
|
|
||||||
|
#define sulogin_trivial_usage \
|
||||||
|
"[OPTION]... [tty-device]"
|
||||||
|
#define sulogin_full_usage \
|
||||||
|
"Single user login\n" \
|
||||||
|
"Options:\n" \
|
||||||
|
"\t-f\tDo not authenticate (user already authenticated)\n" \
|
||||||
|
"\t-h\tName of the remote host for this login.\n" \
|
||||||
|
"\t-p\tPreserve environment."
|
||||||
|
|
||||||
#define swapoff_trivial_usage \
|
#define swapoff_trivial_usage \
|
||||||
"[OPTION] [DEVICE]"
|
"[OPTION] [DEVICE]"
|
||||||
#define swapoff_full_usage \
|
#define swapoff_full_usage \
|
||||||
@ -1956,6 +1983,13 @@
|
|||||||
"Options:\n" \
|
"Options:\n" \
|
||||||
"\t-R\tRead-only- do not write to the file."
|
"\t-R\tRead-only- do not write to the file."
|
||||||
|
|
||||||
|
#define vlock_trivial_usage \
|
||||||
|
"[OPTIONS]"
|
||||||
|
#define vlock_full_usage \
|
||||||
|
"Lock a virtual terminal. A password is required to unlock\n" \
|
||||||
|
"Options:\n" \
|
||||||
|
"\t-a\tLock all VTs"
|
||||||
|
|
||||||
#define watchdog_trivial_usage \
|
#define watchdog_trivial_usage \
|
||||||
"DEV"
|
"DEV"
|
||||||
#define watchdog_full_usage \
|
#define watchdog_full_usage \
|
||||||
|
@ -34,17 +34,21 @@ LIBBB_SRC:= \
|
|||||||
my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \
|
my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \
|
||||||
print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \
|
print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \
|
||||||
safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
|
safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
|
||||||
trim.c unzip.c uncompress.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
|
trim.c unzip.c uncompress.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c \
|
||||||
xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
|
xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
|
||||||
copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
|
copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
|
||||||
dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
|
dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
|
||||||
simplify_path.c inet_common.c inode_hash.c
|
simplify_path.c inet_common.c inode_hash.c obscure.c pwd2spwd.c xfuncs.c \
|
||||||
|
correct_password.c change_identity.c setup_environment.c run_shell.c \
|
||||||
|
pw_encrypt.c restricted_shell.c
|
||||||
LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
|
LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
|
||||||
|
|
||||||
LIBBB_MSRC:=$(LIBBB_DIR)messages.c
|
LIBBB_MSRC:=$(LIBBB_DIR)messages.c
|
||||||
LIBBB_MOBJ:=full_version.o name_too_long.o omitting_directory.o not_a_directory.o \
|
LIBBB_MOBJ:=full_version.o name_too_long.o omitting_directory.o not_a_directory.o \
|
||||||
memory_exhausted.o invalid_date.o invalid_option.o io_error.o dash_dash_help.o \
|
memory_exhausted.o invalid_date.o invalid_option.o io_error.o dash_dash_help.o \
|
||||||
write_error.o too_few_args.o name_longer_than_foo.o unknown.o can_not_create_raw_socket.o
|
write_error.o too_few_args.o name_longer_than_foo.o unknown.o can_not_create_raw_socket.o \
|
||||||
|
shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o securetty_file.o \
|
||||||
|
motd_file.o
|
||||||
LIBBB_MOBJS=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ))
|
LIBBB_MOBJS=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ))
|
||||||
|
|
||||||
libraries-y+=$(LIBBB_DIR)$(LIBBB_AR)
|
libraries-y+=$(LIBBB_DIR)$(LIBBB_AR)
|
||||||
|
54
libbb/change_identity.c
Normal file
54
libbb/change_identity.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Become the user and group(s) specified by PW. */
|
||||||
|
void change_identity ( const struct passwd *pw )
|
||||||
|
{
|
||||||
|
if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 )
|
||||||
|
perror_msg_and_die ( "cannot set groups" );
|
||||||
|
endgrent ( );
|
||||||
|
|
||||||
|
if ( setgid ( pw-> pw_gid ))
|
||||||
|
perror_msg_and_die ( "cannot set group id" );
|
||||||
|
if ( setuid ( pw->pw_uid ))
|
||||||
|
perror_msg_and_die ( "cannot set user id" );
|
||||||
|
}
|
||||||
|
|
78
libbb/correct_password.c
Normal file
78
libbb/correct_password.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <crypt.h>
|
||||||
|
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Ask the user for a password.
|
||||||
|
Return 1 if the user gives the correct password for entry PW,
|
||||||
|
0 if not. Return 1 without asking for a password if run by UID 0
|
||||||
|
or if PW has an empty password. */
|
||||||
|
|
||||||
|
int correct_password ( const struct passwd *pw )
|
||||||
|
{
|
||||||
|
char *unencrypted, *encrypted, *correct;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
|
||||||
|
struct spwd *sp = getspnam ( pw-> pw_name );
|
||||||
|
|
||||||
|
if ( !sp )
|
||||||
|
error_msg_and_die ( "no valid shadow password" );
|
||||||
|
|
||||||
|
correct = sp-> sp_pwdp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
correct = pw-> pw_passwd;
|
||||||
|
|
||||||
|
if ( correct == 0 || correct[0] == '\0' )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
unencrypted = getpass ( "Password: " );
|
||||||
|
if ( !unencrypted )
|
||||||
|
{
|
||||||
|
fputs ( "getpass: cannot open /dev/tty\n", stderr );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
encrypted = crypt ( unencrypted, correct );
|
||||||
|
memset ( unencrypted, 0, xstrlen ( unencrypted ));
|
||||||
|
return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0;
|
||||||
|
}
|
@ -11,6 +11,24 @@
|
|||||||
|
|
||||||
#if __GNU_LIBRARY__ < 5
|
#if __GNU_LIBRARY__ < 5
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some systems already have updwtmp(). Some don't... This is
|
||||||
|
* the updwtmp() implementation from uClibc, Copyright 2002 by
|
||||||
|
* Erik Andersen <andersee@debian.org>
|
||||||
|
*/
|
||||||
|
extern void updwtmp(const char *wtmp_file, const struct utmp *lutmp)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(wtmp_file, O_APPEND | O_WRONLY, 0);
|
||||||
|
if (fd >= 0) {
|
||||||
|
if (lockf(fd, F_LOCK, 0)==0) {
|
||||||
|
write(fd, (const char *) lutmp, sizeof(struct utmp));
|
||||||
|
lockf(fd, F_ULOCK, 0);
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
@ -66,3 +66,39 @@
|
|||||||
#ifdef L_can_not_create_raw_socket
|
#ifdef L_can_not_create_raw_socket
|
||||||
const char * const can_not_create_raw_socket = "can`t create raw socket";
|
const char * const can_not_create_raw_socket = "can`t create raw socket";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_passwd_file
|
||||||
|
#define PASSWD_FILE "/etc/passwd"
|
||||||
|
const char * const passwd_file = PASSWD_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_shadow_file
|
||||||
|
#define SHADOW_FILE "/etc/shadow"
|
||||||
|
const char * const shadow_file = SHADOW_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_group_file
|
||||||
|
#define GROUP_FILE "/etc/group"
|
||||||
|
const char * const group_file = GROUP_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_gshadow_file
|
||||||
|
#define GSHADOW_FILE "/etc/gshadow"
|
||||||
|
const char * const gshadow_file = GSHADOW_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_nologin_file
|
||||||
|
#define NOLOGIN_FILE "/etc/nologin"
|
||||||
|
const char * const nologin_file = NOLOGIN_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_securetty_file
|
||||||
|
#define SECURETTY_FILE "/etc/securetty"
|
||||||
|
const char * const securetty_file = SECURETTY_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef L_motd_file
|
||||||
|
#define MOTD_FILE "/etc/motd"
|
||||||
|
const char * const motd_file = MOTD_FILE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
246
libbb/obscure.c
Normal file
246
libbb/obscure.c
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This version of obscure.c contains modifications to support "cracklib"
|
||||||
|
* by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib
|
||||||
|
* library source code for this function to operate.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* can't be a palindrome - like `R A D A R' or `M A D A M'
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int palindrome(const char *old, const char *newval)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
i = strlen(newval);
|
||||||
|
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
if (newval[i - j - 1] != newval[j])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* more than half of the characters are different ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int similiar(const char *old, const char *newval)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = j = 0; newval[i] && old[i]; i++)
|
||||||
|
if (strchr(newval, old[i]))
|
||||||
|
j++;
|
||||||
|
|
||||||
|
if (i >= j * 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a nice mix of characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int simple(const char *old, const char *newval)
|
||||||
|
{
|
||||||
|
int digits = 0;
|
||||||
|
int uppers = 0;
|
||||||
|
int lowers = 0;
|
||||||
|
int others = 0;
|
||||||
|
int size;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; newval[i]; i++) {
|
||||||
|
if (isdigit(newval[i]))
|
||||||
|
digits++;
|
||||||
|
else if (isupper(newval[i]))
|
||||||
|
uppers++;
|
||||||
|
else if (islower(newval[i]))
|
||||||
|
lowers++;
|
||||||
|
else
|
||||||
|
others++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The scam is this - a password of only one character type
|
||||||
|
* must be 8 letters long. Two types, 7, and so on.
|
||||||
|
*/
|
||||||
|
|
||||||
|
size = 9;
|
||||||
|
if (digits)
|
||||||
|
size--;
|
||||||
|
if (uppers)
|
||||||
|
size--;
|
||||||
|
if (lowers)
|
||||||
|
size--;
|
||||||
|
if (others)
|
||||||
|
size--;
|
||||||
|
|
||||||
|
if (size <= i)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *str_lower(char *string)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = string; *cp; cp++)
|
||||||
|
*cp = tolower(*cp);
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *password_check(const char *old, const char *newval, const struct passwd *pwdp)
|
||||||
|
{
|
||||||
|
char *msg = NULL;
|
||||||
|
char *oldmono, *newmono, *wrapped;
|
||||||
|
|
||||||
|
if (strcmp(newval, old) == 0)
|
||||||
|
return "no change";
|
||||||
|
|
||||||
|
newmono = str_lower(xstrdup(newval));
|
||||||
|
oldmono = str_lower(xstrdup(old));
|
||||||
|
wrapped = (char *) xmalloc(strlen(oldmono) * 2 + 1);
|
||||||
|
strcpy(wrapped, oldmono);
|
||||||
|
strcat(wrapped, oldmono);
|
||||||
|
|
||||||
|
if (palindrome(oldmono, newmono))
|
||||||
|
msg = "a palindrome";
|
||||||
|
|
||||||
|
if (!msg && strcmp(oldmono, newmono) == 0)
|
||||||
|
msg = "case changes only";
|
||||||
|
|
||||||
|
if (!msg && similiar(oldmono, newmono))
|
||||||
|
msg = "too similiar";
|
||||||
|
|
||||||
|
if (!msg && simple(old, newval))
|
||||||
|
msg = "too simple";
|
||||||
|
|
||||||
|
if (!msg && strstr(wrapped, newmono))
|
||||||
|
msg = "rotated";
|
||||||
|
|
||||||
|
bzero(newmono, strlen(newmono));
|
||||||
|
bzero(oldmono, strlen(oldmono));
|
||||||
|
bzero(wrapped, strlen(wrapped));
|
||||||
|
free(newmono);
|
||||||
|
free(oldmono);
|
||||||
|
free(wrapped);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *obscure_msg(const char *old, const char *newval, const struct passwd *pwdp)
|
||||||
|
{
|
||||||
|
int maxlen, oldlen, newlen;
|
||||||
|
char *new1, *old1, *msg;
|
||||||
|
|
||||||
|
oldlen = strlen(old);
|
||||||
|
newlen = strlen(newval);
|
||||||
|
|
||||||
|
#if 0 /* why not check the password when set for the first time? --marekm */
|
||||||
|
if (old[0] == '\0')
|
||||||
|
/* return (1); */
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (newlen < 5)
|
||||||
|
return "too short";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remaining checks are optional.
|
||||||
|
*/
|
||||||
|
/* Not for us -- Sean
|
||||||
|
*if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
|
||||||
|
* return NULL;
|
||||||
|
*/
|
||||||
|
msg = password_check(old, newval, pwdp);
|
||||||
|
if (msg)
|
||||||
|
return msg;
|
||||||
|
|
||||||
|
/* The traditional crypt() truncates passwords to 8 chars. It is
|
||||||
|
possible to circumvent the above checks by choosing an easy
|
||||||
|
8-char password and adding some random characters to it...
|
||||||
|
Example: "password$%^&*123". So check it again, this time
|
||||||
|
truncated to the maximum length. Idea from npasswd. --marekm */
|
||||||
|
|
||||||
|
maxlen = 8;
|
||||||
|
if (oldlen <= maxlen && newlen <= maxlen)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
new1 = (char *) xstrdup(newval);
|
||||||
|
old1 = (char *) xstrdup(old);
|
||||||
|
if (newlen > maxlen)
|
||||||
|
new1[maxlen] = '\0';
|
||||||
|
if (oldlen > maxlen)
|
||||||
|
old1[maxlen] = '\0';
|
||||||
|
|
||||||
|
msg = password_check(old1, new1, pwdp);
|
||||||
|
|
||||||
|
bzero(new1, newlen);
|
||||||
|
bzero(old1, oldlen);
|
||||||
|
free(new1);
|
||||||
|
free(old1);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obscure - see if password is obscure enough.
|
||||||
|
*
|
||||||
|
* The programmer is encouraged to add as much complexity to this
|
||||||
|
* routine as desired. Included are some of my favorite ways to
|
||||||
|
* check passwords.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int obscure(const char *old, const char *newval, const struct passwd *pwdp)
|
||||||
|
{
|
||||||
|
char *msg = obscure_msg(old, newval, pwdp);
|
||||||
|
|
||||||
|
/* if (msg) { */
|
||||||
|
if (msg != NULL) {
|
||||||
|
printf("Bad password: %s.\n", msg);
|
||||||
|
/* return 0; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* return 1; */
|
||||||
|
return 0;
|
||||||
|
}
|
48
libbb/pw_encrypt.c
Normal file
48
libbb/pw_encrypt.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Utility routine.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2002 by Erik Andersen <andersee@debian.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <crypt.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern char *pw_encrypt(const char *clear, const char *salt)
|
||||||
|
{
|
||||||
|
static char cipher[128];
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEATURE_SHA1_PASSWORDS
|
||||||
|
if (strncmp(salt, "$2$", 3) == 0) {
|
||||||
|
return sha1_crypt(clear);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
cp = (char *) crypt(clear, salt);
|
||||||
|
/* if crypt (a nonstandard crypt) returns a string too large,
|
||||||
|
truncate it so we don't overrun buffers and hope there is
|
||||||
|
enough security in what's left */
|
||||||
|
if (strlen(cp) > sizeof(cipher)-1) {
|
||||||
|
cp[sizeof(cipher)-1] = 0;
|
||||||
|
}
|
||||||
|
strcpy(cipher, cp);
|
||||||
|
return cipher;
|
||||||
|
}
|
||||||
|
|
73
libbb/pwd2spwd.c
Normal file
73
libbb/pwd2spwd.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pwd_to_spwd - create entries for new spwd structure
|
||||||
|
*
|
||||||
|
* pwd_to_spwd() creates a new (struct spwd) containing the
|
||||||
|
* information in the pointed-to (struct passwd).
|
||||||
|
*/
|
||||||
|
#define DAY (24L*3600L)
|
||||||
|
#define WEEK (7*DAY)
|
||||||
|
#define SCALE DAY
|
||||||
|
struct spwd *pwd_to_spwd(const struct passwd *pw)
|
||||||
|
{
|
||||||
|
static struct spwd sp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nice, easy parts first. The name and passwd map directly
|
||||||
|
* from the old password structure to the new one.
|
||||||
|
*/
|
||||||
|
sp.sp_namp = pw->pw_name;
|
||||||
|
sp.sp_pwdp = pw->pw_passwd;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defaults used if there is no pw_age information.
|
||||||
|
*/
|
||||||
|
sp.sp_min = 0;
|
||||||
|
sp.sp_max = (10000L * DAY) / SCALE;
|
||||||
|
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These fields have no corresponding information in the password
|
||||||
|
* file. They are set to uninitialized values.
|
||||||
|
*/
|
||||||
|
sp.sp_warn = -1;
|
||||||
|
sp.sp_expire = -1;
|
||||||
|
sp.sp_inact = -1;
|
||||||
|
sp.sp_flag = -1;
|
||||||
|
|
||||||
|
return &sp;
|
||||||
|
}
|
||||||
|
|
57
libbb/restricted_shell.c
Normal file
57
libbb/restricted_shell.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return 1 if SHELL is a restricted shell (one not returned by
|
||||||
|
getusershell), else 0, meaning it is a standard shell. */
|
||||||
|
|
||||||
|
int restricted_shell ( const char *shell )
|
||||||
|
{
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
setusershell ( );
|
||||||
|
while (( line = getusershell ( ))) {
|
||||||
|
if (( *line != '#' ) && ( strcmp ( line, shell ) == 0 ))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
endusershell ( );
|
||||||
|
return line ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
81
libbb/run_shell.c
Normal file
81
libbb/run_shell.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
|
||||||
|
If COMMAND is nonzero, pass it to the shell with the -c option.
|
||||||
|
If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
|
||||||
|
arguments. */
|
||||||
|
|
||||||
|
void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args )
|
||||||
|
{
|
||||||
|
const char **args;
|
||||||
|
int argno = 1;
|
||||||
|
int additional_args_cnt = 0;
|
||||||
|
|
||||||
|
for ( args = additional_args; args && *args; args++ )
|
||||||
|
additional_args_cnt++;
|
||||||
|
|
||||||
|
if ( additional_args )
|
||||||
|
args = (const char **) xmalloc (sizeof (char *) * ( 4 + additional_args_cnt ));
|
||||||
|
else
|
||||||
|
args = (const char **) xmalloc (sizeof (char *) * 4 );
|
||||||
|
|
||||||
|
args [0] = get_last_path_component ( xstrdup ( shell ));
|
||||||
|
|
||||||
|
if ( loginshell ) {
|
||||||
|
char *args0 = xmalloc ( xstrlen ( args [0] ) + 2 );
|
||||||
|
args0 [0] = '-';
|
||||||
|
strcpy ( args0 + 1, args [0] );
|
||||||
|
args [0] = args0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( command ) {
|
||||||
|
args [argno++] = "-c";
|
||||||
|
args [argno++] = command;
|
||||||
|
}
|
||||||
|
if ( additional_args ) {
|
||||||
|
for ( ; *additional_args; ++additional_args )
|
||||||
|
args [argno++] = *additional_args;
|
||||||
|
}
|
||||||
|
args [argno] = 0;
|
||||||
|
execv ( shell, (char **) args );
|
||||||
|
perror_msg_and_die ( "cannot run %s", shell );
|
||||||
|
}
|
||||||
|
|
@ -28,8 +28,6 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "busybox.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -37,98 +35,19 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "libbb.h"
|
||||||
|
|
||||||
#include "pwd.h"
|
|
||||||
#include "grp.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
|
||||||
#include "shadow.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEFAULT_LOGIN_PATH "/bin:/usr/bin"
|
#define DEFAULT_LOGIN_PATH "/bin:/usr/bin"
|
||||||
#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin"
|
#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin"
|
||||||
|
|
||||||
|
|
||||||
static void xsetenv ( const char *key, const char *value )
|
static void xsetenv ( const char *key, const char *value )
|
||||||
{
|
{
|
||||||
if ( setenv ( key, value, 1 ))
|
if ( setenv ( key, value, 1 ))
|
||||||
error_msg_and_die ( "out of memory" );
|
error_msg_and_die ( "out of memory" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Become the user and group(s) specified by PW. */
|
|
||||||
|
|
||||||
void change_identity ( const struct passwd *pw )
|
|
||||||
{
|
|
||||||
if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 )
|
|
||||||
perror_msg_and_die ( "cannot set groups" );
|
|
||||||
endgrent ( );
|
|
||||||
|
|
||||||
if ( setgid ( pw-> pw_gid ))
|
|
||||||
perror_msg_and_die ( "cannot set group id" );
|
|
||||||
if ( setuid ( pw->pw_uid ))
|
|
||||||
perror_msg_and_die ( "cannot set user id" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
|
|
||||||
If COMMAND is nonzero, pass it to the shell with the -c option.
|
|
||||||
If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
|
|
||||||
arguments. */
|
|
||||||
|
|
||||||
void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args )
|
|
||||||
{
|
|
||||||
const char **args;
|
|
||||||
int argno = 1;
|
|
||||||
int additional_args_cnt = 0;
|
|
||||||
|
|
||||||
for ( args = additional_args; args && *args; args++ )
|
|
||||||
additional_args_cnt++;
|
|
||||||
|
|
||||||
if ( additional_args )
|
|
||||||
args = (const char **) xmalloc (sizeof (char *) * ( 4 + additional_args_cnt ));
|
|
||||||
else
|
|
||||||
args = (const char **) xmalloc (sizeof (char *) * 4 );
|
|
||||||
|
|
||||||
args [0] = get_last_path_component ( xstrdup ( shell ));
|
|
||||||
|
|
||||||
if ( loginshell ) {
|
|
||||||
char *args0 = xmalloc ( xstrlen ( args [0] ) + 2 );
|
|
||||||
args0 [0] = '-';
|
|
||||||
strcpy ( args0 + 1, args [0] );
|
|
||||||
args [0] = args0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( command ) {
|
|
||||||
args [argno++] = "-c";
|
|
||||||
args [argno++] = command;
|
|
||||||
}
|
|
||||||
if ( additional_args ) {
|
|
||||||
for ( ; *additional_args; ++additional_args )
|
|
||||||
args [argno++] = *additional_args;
|
|
||||||
}
|
|
||||||
args [argno] = 0;
|
|
||||||
execv ( shell, (char **) args );
|
|
||||||
perror_msg_and_die ( "cannot run %s", shell );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return 1 if SHELL is a restricted shell (one not returned by
|
|
||||||
getusershell), else 0, meaning it is a standard shell. */
|
|
||||||
|
|
||||||
int restricted_shell ( const char *shell )
|
|
||||||
{
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
setusershell ( );
|
|
||||||
while (( line = getusershell ( ))) {
|
|
||||||
if (( *line != '#' ) && ( strcmp ( line, shell ) == 0 ))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
endusershell ( );
|
|
||||||
return line ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update `environ' for the new shell based on PW, with SHELL being
|
|
||||||
the value for the SHELL environment variable. */
|
|
||||||
|
|
||||||
void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw )
|
void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw )
|
||||||
{
|
{
|
||||||
if ( loginshell ) {
|
if ( loginshell ) {
|
||||||
@ -172,38 +91,3 @@ void setup_environment ( const char *shell, int loginshell, int changeenv, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ask the user for a password.
|
|
||||||
Return 1 if the user gives the correct password for entry PW,
|
|
||||||
0 if not. Return 1 without asking for a password if run by UID 0
|
|
||||||
or if PW has an empty password. */
|
|
||||||
|
|
||||||
int correct_password ( const struct passwd *pw )
|
|
||||||
{
|
|
||||||
char *unencrypted, *encrypted, *correct;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
|
||||||
if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) {
|
|
||||||
struct spwd *sp = getspnam ( pw-> pw_name );
|
|
||||||
|
|
||||||
if ( !sp )
|
|
||||||
error_msg_and_die ( "no valid shadow password" );
|
|
||||||
|
|
||||||
correct = sp-> sp_pwdp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
correct = pw-> pw_passwd;
|
|
||||||
|
|
||||||
if ( correct == 0 || correct[0] == '\0' )
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
unencrypted = getpass ( "Password: " );
|
|
||||||
if ( !unencrypted )
|
|
||||||
{
|
|
||||||
fputs ( "getpass: cannot open /dev/tty\n", stderr );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
encrypted = crypt ( unencrypted, correct );
|
|
||||||
memset ( unencrypted, 0, xstrlen ( unencrypted ));
|
|
||||||
return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0;
|
|
||||||
}
|
|
@ -26,9 +26,12 @@ LOGINUTILS-y:=
|
|||||||
LOGINUTILS-$(CONFIG_ADDGROUP) += addgroup.o
|
LOGINUTILS-$(CONFIG_ADDGROUP) += addgroup.o
|
||||||
LOGINUTILS-$(CONFIG_ADDUSER) += adduser.o
|
LOGINUTILS-$(CONFIG_ADDUSER) += adduser.o
|
||||||
LOGINUTILS-$(CONFIG_DELUSER) += deluser.o
|
LOGINUTILS-$(CONFIG_DELUSER) += deluser.o
|
||||||
LOGINUTILS-$(CONFIG_GETTY) += getty.o
|
LOGINUTILS-$(CONFIG_GETTY) += getty.o
|
||||||
LOGINUTILS-$(CONFIG_LOGIN) += login.o tinylogin.o
|
LOGINUTILS-$(CONFIG_LOGIN) += login.o
|
||||||
LOGINUTILS-$(CONFIG_SU) += su.o tinylogin.o
|
LOGINUTILS-$(CONFIG_PASSWD) += passwd.o
|
||||||
|
LOGINUTILS-$(CONFIG_SU) += su.o
|
||||||
|
LOGINUTILS-$(CONFIG_SULOGIN) += sulogin.o
|
||||||
|
LOGINUTILS-$(CONFIG_VLOCK) += vlock.o
|
||||||
|
|
||||||
libraries-y+=$(LOGINUTILS_DIR)$(LOGINUTILS_AR)
|
libraries-y+=$(LOGINUTILS_DIR)$(LOGINUTILS_AR)
|
||||||
|
|
||||||
|
@ -35,9 +35,6 @@
|
|||||||
#include "pwd.h"
|
#include "pwd.h"
|
||||||
#include "grp.h"
|
#include "grp.h"
|
||||||
|
|
||||||
#define GROUP_FILE "/etc/group"
|
|
||||||
#define SHADOW_FILE "/etc/gshadow"
|
|
||||||
|
|
||||||
|
|
||||||
/* structs __________________________ */
|
/* structs __________________________ */
|
||||||
|
|
||||||
@ -92,7 +89,7 @@ static int addgroup(const char *filename, char *group, gid_t gid)
|
|||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
FILE *etc_gshadow;
|
FILE *etc_gshadow;
|
||||||
char *gshadow = SHADOW_FILE;
|
char *gshadow = shadow_file;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct group gr;
|
struct group gr;
|
||||||
@ -162,7 +159,7 @@ int addgroup_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* werk */
|
/* werk */
|
||||||
return addgroup(GROUP_FILE, group, gid);
|
return addgroup(group_file, group, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $Id: addgroup.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */
|
/* $Id: addgroup.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */
|
||||||
|
@ -33,11 +33,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
#include "pwd.h"
|
|
||||||
#include "grp.h"
|
|
||||||
|
|
||||||
#define PASSWD_FILE "/etc/passwd"
|
|
||||||
#define SHADOW_FILE "/etc/shadow"
|
|
||||||
|
|
||||||
|
|
||||||
/* structs __________________________ */
|
/* structs __________________________ */
|
||||||
@ -56,9 +52,6 @@ static const char default_home_prefix[] = "/home";
|
|||||||
static const char default_shell[] = "/bin/sh";
|
static const char default_shell[] = "/bin/sh";
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
|
||||||
#include "shadow.h"
|
|
||||||
|
|
||||||
/* shadow in use? */
|
/* shadow in use? */
|
||||||
static int shadow_enabled = 0;
|
static int shadow_enabled = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -138,47 +131,6 @@ static void passwd_wrapper(const char *login)
|
|||||||
error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually", login);
|
error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually", login);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
|
||||||
/*
|
|
||||||
* pwd_to_spwd - create entries for new spwd structure
|
|
||||||
*
|
|
||||||
* pwd_to_spwd() creates a new (struct spwd) containing the
|
|
||||||
* information in the pointed-to (struct passwd).
|
|
||||||
*/
|
|
||||||
#define DAY (24L*3600L)
|
|
||||||
#define WEEK (7*DAY)
|
|
||||||
#define SCALE DAY
|
|
||||||
static struct spwd *pwd_to_spwd(const struct passwd *pw)
|
|
||||||
{
|
|
||||||
static struct spwd sp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nice, easy parts first. The name and passwd map directly
|
|
||||||
* from the old password structure to the new one.
|
|
||||||
*/
|
|
||||||
sp.sp_namp = pw->pw_name;
|
|
||||||
sp.sp_pwdp = pw->pw_passwd;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Defaults used if there is no pw_age information.
|
|
||||||
*/
|
|
||||||
sp.sp_min = 0;
|
|
||||||
sp.sp_max = (10000L * DAY) / SCALE;
|
|
||||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These fields have no corresponding information in the password
|
|
||||||
* file. They are set to uninitialized values.
|
|
||||||
*/
|
|
||||||
sp.sp_warn = -1;
|
|
||||||
sp.sp_expire = -1;
|
|
||||||
sp.sp_inact = -1;
|
|
||||||
sp.sp_flag = -1;
|
|
||||||
|
|
||||||
return &sp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* putpwent(3) remix */
|
/* putpwent(3) remix */
|
||||||
static int adduser(const char *filename, struct passwd *p)
|
static int adduser(const char *filename, struct passwd *p)
|
||||||
{
|
{
|
||||||
@ -222,7 +174,7 @@ static int adduser(const char *filename, struct passwd *p)
|
|||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
/* add to shadow if necessary */
|
/* add to shadow if necessary */
|
||||||
if (shadow_enabled) {
|
if (shadow_enabled) {
|
||||||
shadow = wfopen(SHADOW_FILE, "a");
|
shadow = wfopen(shadow_file, "a");
|
||||||
if (shadow == NULL) {
|
if (shadow == NULL) {
|
||||||
/* return -1; */
|
/* return -1; */
|
||||||
return 1;
|
return 1;
|
||||||
@ -333,7 +285,7 @@ int adduser_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
/* is /etc/shadow in use? */
|
/* is /etc/shadow in use? */
|
||||||
shadow_enabled = (0 == access(SHADOW_FILE, F_OK));
|
shadow_enabled = (0 == access(shadow_file, F_OK));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* create a passwd struct */
|
/* create a passwd struct */
|
||||||
@ -346,7 +298,7 @@ int adduser_main(int argc, char **argv)
|
|||||||
pw.pw_shell = (char *)shell;
|
pw.pw_shell = (char *)shell;
|
||||||
|
|
||||||
/* grand finale */
|
/* grand finale */
|
||||||
return adduser(PASSWD_FILE, &pw);
|
return adduser(passwd_file, &pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $Id: adduser.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */
|
/* $Id: adduser.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */
|
||||||
|
@ -7,19 +7,22 @@ mainmenu_option next_comment
|
|||||||
comment 'Login/Password Management Utilities'
|
comment 'Login/Password Management Utilities'
|
||||||
|
|
||||||
|
|
||||||
bool 'addgroup' CONFIG_ADDGROUP
|
bool 'addgroup' CONFIG_ADDGROUP
|
||||||
bool 'adduser' CONFIG_ADDUSER
|
bool 'adduser' CONFIG_ADDUSER
|
||||||
bool 'deluser' CONFIG_DELUSER
|
bool 'deluser' CONFIG_DELUSER
|
||||||
bool 'delgroup' CONFIG_DELUSER
|
bool 'delgroup' CONFIG_DELUSER
|
||||||
bool 'getty' CONFIG_GETTY
|
bool 'getty' CONFIG_GETTY
|
||||||
bool 'login' CONFIG_LOGIN
|
bool 'login' CONFIG_LOGIN
|
||||||
if [ "$CONFIG_LOGIN" = "y" ]; then
|
if [ "$CONFIG_LOGIN" = "y" ]; then
|
||||||
bool ' Support for /etc/securetty' CONFIG_FEATURE_SECURETTY
|
bool ' Support for /etc/securetty' CONFIG_FEATURE_SECURETTY
|
||||||
fi
|
fi
|
||||||
bool 'su' CONFIG_SU
|
bool 'passwd' CONFIG_PASSWD
|
||||||
|
bool 'su' CONFIG_SU
|
||||||
if [ "$CONFIG_ADDUSER" = "y" -o "$CONFIG_DELUSER" = "y" -o "$CONFIG_LOGIN" = "y" -o "$CONFIG_SU" = "y" ]; then
|
if [ "$CONFIG_ADDUSER" = "y" -o "$CONFIG_DELUSER" = "y" -o "$CONFIG_LOGIN" = "y" -o "$CONFIG_SU" = "y" ]; then
|
||||||
bool 'Support for shadow passwords' CONFIG_FEATURE_SHADOWPASSWDS
|
bool ' Support for shadow passwords' CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
fi
|
fi
|
||||||
|
bool 'sulogin' CONFIG_SULOGIN
|
||||||
|
bool 'vlock' CONFIG_VLOCK
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
|
@ -28,10 +28,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
#define PASSWD_FILE "/etc/passwd"
|
|
||||||
#define GROUP_FILE "/etc/group"
|
|
||||||
#define SHADOW_FILE "/etc/shadow"
|
|
||||||
#define GSHADOW_FILE "/etc/gshadow"
|
|
||||||
|
|
||||||
|
|
||||||
/* where to start and stop deletion */
|
/* where to start and stop deletion */
|
||||||
@ -123,11 +119,11 @@ int delgroup_main(int argc, char **argv)
|
|||||||
show_usage();
|
show_usage();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
failure = del_line_matching(argv[1], GROUP_FILE);
|
failure = del_line_matching(argv[1], group_file);
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
if (access(GSHADOW_FILE, W_OK) == 0) {
|
if (access(gshadow_file, W_OK) == 0) {
|
||||||
/* EDR the |= works if the error is not 0, so he had it wrong */
|
/* EDR the |= works if the error is not 0, so he had it wrong */
|
||||||
failure |= del_line_matching(argv[1], GSHADOW_FILE);
|
failure |= del_line_matching(argv[1], gshadow_file);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
||||||
/* if (!successful) { */
|
/* if (!successful) { */
|
||||||
@ -149,35 +145,35 @@ int deluser_main(int argc, char **argv)
|
|||||||
show_usage();
|
show_usage();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
failure = del_line_matching(argv[1], PASSWD_FILE);
|
failure = del_line_matching(argv[1], passwd_file);
|
||||||
/* if (!successful) { */
|
/* if (!successful) { */
|
||||||
if (failure) {
|
if (failure) {
|
||||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||||
argv[1], PASSWD_FILE);
|
argv[1], passwd_file);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
failure = del_line_matching(argv[1], SHADOW_FILE);
|
failure = del_line_matching(argv[1], shadow_file);
|
||||||
/* if (!successful) { */
|
/* if (!successful) { */
|
||||||
if (failure) {
|
if (failure) {
|
||||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||||
argv[1], SHADOW_FILE);
|
argv[1], shadow_file);
|
||||||
}
|
}
|
||||||
failure = del_line_matching(argv[1], GSHADOW_FILE);
|
failure = del_line_matching(argv[1], gshadow_file);
|
||||||
/* if (!successful) { */
|
/* if (!successful) { */
|
||||||
if (failure) {
|
if (failure) {
|
||||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||||
argv[1], GSHADOW_FILE);
|
argv[1], gshadow_file);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
||||||
failure = del_line_matching(argv[1], GROUP_FILE);
|
failure = del_line_matching(argv[1], group_file);
|
||||||
/* if (!successful) { */
|
/* if (!successful) { */
|
||||||
if (failure) {
|
if (failure) {
|
||||||
error_msg_and_die("%s: User could not be removed from %s\n",
|
error_msg_and_die("%s: User could not be removed from %s\n",
|
||||||
argv[1], GROUP_FILE);
|
argv[1], group_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return (EXIT_SUCCESS);
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* $Id: deluser.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */
|
/* $Id: deluser.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */
|
||||||
|
@ -14,16 +14,9 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
#include "pwd.h"
|
|
||||||
#include "grp.h"
|
|
||||||
|
|
||||||
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
|
||||||
#include "shadow.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "tinylogin.h"
|
|
||||||
|
|
||||||
// import from utmp.c
|
// import from utmp.c
|
||||||
static void checkutmp(int picky);
|
static void checkutmp(int picky);
|
||||||
@ -35,12 +28,7 @@ extern char *pw_encrypt(const char *clear, const char *salt);
|
|||||||
|
|
||||||
// login defines
|
// login defines
|
||||||
#define TIMEOUT 60
|
#define TIMEOUT 60
|
||||||
#define FAIL_DELAY 3
|
|
||||||
#define EMPTY_USERNAME_COUNT 10
|
#define EMPTY_USERNAME_COUNT 10
|
||||||
#define MOTD_FILE "/etc/motd"
|
|
||||||
#define NOLOGIN_FILE "/etc/nologin"
|
|
||||||
#define SECURETTY_FILE "/etc/securetty"
|
|
||||||
|
|
||||||
#define USERNAME_SIZE 32
|
#define USERNAME_SIZE 32
|
||||||
|
|
||||||
/* Stuff global to this file */
|
/* Stuff global to this file */
|
||||||
@ -81,7 +69,9 @@ extern int login_main(int argc, char **argv)
|
|||||||
int failed;
|
int failed;
|
||||||
int count=0;
|
int count=0;
|
||||||
struct passwd *pw, pw_copy;
|
struct passwd *pw, pw_copy;
|
||||||
|
#ifdef CONFIG_WHEEL_GROUP
|
||||||
|
struct group *grp;
|
||||||
|
#endif
|
||||||
int opt_preserve = 0;
|
int opt_preserve = 0;
|
||||||
int opt_fflag = 0;
|
int opt_fflag = 0;
|
||||||
char *opt_host = 0;
|
char *opt_host = 0;
|
||||||
@ -283,11 +273,11 @@ static int login_prompt ( char *buf_name )
|
|||||||
|
|
||||||
static int check_nologin ( int amroot )
|
static int check_nologin ( int amroot )
|
||||||
{
|
{
|
||||||
if ( access ( NOLOGIN_FILE, F_OK ) == 0 ) {
|
if ( access ( nologin_file, F_OK ) == 0 ) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (( fp = fopen ( NOLOGIN_FILE, "r" ))) {
|
if (( fp = fopen ( nologin_file, "r" ))) {
|
||||||
while (( c = getc ( fp )) != EOF )
|
while (( c = getc ( fp )) != EOF )
|
||||||
putchar (( c == '\n' ) ? '\r' : c );
|
putchar (( c == '\n' ) ? '\r' : c );
|
||||||
|
|
||||||
@ -312,7 +302,7 @@ static int check_tty ( const char *tty )
|
|||||||
int i;
|
int i;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
if (( fp = fopen ( SECURETTY_FILE, "r" ))) {
|
if (( fp = fopen ( securetty_file, "r" ))) {
|
||||||
while ( fgets ( buf, sizeof( buf ) - 1, fp )) {
|
while ( fgets ( buf, sizeof( buf ) - 1, fp )) {
|
||||||
for ( i = xstrlen( buf ) - 1; i >= 0; --i ) {
|
for ( i = xstrlen( buf ) - 1; i >= 0; --i ) {
|
||||||
if ( !isspace ( buf[i] ))
|
if ( !isspace ( buf[i] ))
|
||||||
@ -358,7 +348,7 @@ static void motd ( )
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
if (( fp = fopen ( MOTD_FILE, "r" ))) {
|
if (( fp = fopen ( motd_file, "r" ))) {
|
||||||
while (( c = getc ( fp )) != EOF )
|
while (( c = getc ( fp )) != EOF )
|
||||||
putchar ( c );
|
putchar ( c );
|
||||||
fclose ( fp );
|
fclose ( fp );
|
||||||
@ -429,23 +419,6 @@ static void checkutmp(int picky)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNU_LIBRARY__ < 5
|
|
||||||
/*
|
|
||||||
* Some systems already have updwtmp() and possibly updwtmpx(). Others
|
|
||||||
* don't, so we re-implement these functions if necessary. --marekm
|
|
||||||
*/
|
|
||||||
static void updwtmp(const char *filename, const struct utmp *ut)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = open(filename, O_APPEND | O_WRONLY, 0);
|
|
||||||
if (fd >= 0) {
|
|
||||||
write(fd, (const char *) ut, sizeof(*ut));
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setutmp - put a USER_PROCESS entry in the utmp file
|
* setutmp - put a USER_PROCESS entry in the utmp file
|
||||||
*
|
*
|
||||||
|
408
loginutils/passwd.c
Normal file
408
loginutils/passwd.c
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "busybox.h"
|
||||||
|
|
||||||
|
static char crypt_passwd[128];
|
||||||
|
|
||||||
|
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(int blocks);
|
||||||
|
|
||||||
|
|
||||||
|
int get_algo(char *a)
|
||||||
|
{
|
||||||
|
int x = 0; /* standart: DES */
|
||||||
|
|
||||||
|
if (strcasecmp(a, "md5") == 0)
|
||||||
|
x = 1;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int update_passwd(const struct passwd *pw, char *crypt_pw)
|
||||||
|
{
|
||||||
|
char filename[1024];
|
||||||
|
char buf[1025];
|
||||||
|
char buffer[80];
|
||||||
|
char username[32];
|
||||||
|
char *pw_rest;
|
||||||
|
int has_shadow = 0;
|
||||||
|
int mask;
|
||||||
|
int continued;
|
||||||
|
FILE *fp;
|
||||||
|
FILE *out_fp;
|
||||||
|
struct stat sb;
|
||||||
|
struct flock lock;
|
||||||
|
|
||||||
|
if (access(shadow_file, F_OK) == 0) {
|
||||||
|
has_shadow = 1;
|
||||||
|
}
|
||||||
|
if (has_shadow) {
|
||||||
|
snprintf(filename, sizeof filename, "%s", shadow_file);
|
||||||
|
} else {
|
||||||
|
snprintf(filename, sizeof filename, "%s", passwd_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((fp = fopen(filename, "r+")) == 0) || (fstat(fileno(fp), &sb))) {
|
||||||
|
/* return 0; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock the password file before updating */
|
||||||
|
lock.l_type = F_WRLCK;
|
||||||
|
lock.l_whence = SEEK_SET;
|
||||||
|
lock.l_start = 0;
|
||||||
|
lock.l_len = 0;
|
||||||
|
if (fcntl(fileno(fp), F_SETLK, &lock) < 0) {
|
||||||
|
fprintf(stderr, "%s: %s\n", filename, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
snprintf(buf, sizeof buf, "%s+", filename);
|
||||||
|
mask = umask(0777);
|
||||||
|
out_fp = fopen(buf, "w");
|
||||||
|
umask(mask);
|
||||||
|
if ((!out_fp) || (fchmod(fileno(out_fp), sb.st_mode & 0777))
|
||||||
|
|| (fchown(fileno(out_fp), sb.st_uid, sb.st_gid))) {
|
||||||
|
fcntl(fileno(fp), F_SETLK, &lock);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(out_fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
continued = 0;
|
||||||
|
snprintf(username, sizeof username, "%s:", pw->pw_name);
|
||||||
|
rewind(fp);
|
||||||
|
while (!feof(fp)) {
|
||||||
|
fgets(buffer, sizeof buffer, fp);
|
||||||
|
if (!continued) { // Check to see if we're updating this line.
|
||||||
|
if (strncmp(username, buffer, strlen(username)) == 0) { // we have a match.
|
||||||
|
pw_rest = strchr(buffer, ':');
|
||||||
|
*pw_rest++ = '\0';
|
||||||
|
pw_rest = strchr(pw_rest, ':');
|
||||||
|
fprintf(out_fp, "%s:%s%s", buffer, crypt_pw, pw_rest);
|
||||||
|
} else {
|
||||||
|
fputs(buffer, out_fp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fputs(buffer, out_fp);
|
||||||
|
}
|
||||||
|
if (buffer[strlen(buffer) - 1] == '\n') {
|
||||||
|
continued = 0;
|
||||||
|
} else {
|
||||||
|
continued = 1;
|
||||||
|
}
|
||||||
|
bzero(buffer, sizeof buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fflush(out_fp) || fsync(fileno(out_fp)) || fclose(out_fp)) {
|
||||||
|
unlink(buf);
|
||||||
|
fcntl(fileno(fp), F_SETLK, &lock);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (rename(buf, filename) < 0) {
|
||||||
|
fcntl(fileno(fp), F_SETLK, &lock);
|
||||||
|
fclose(fp);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
fcntl(fileno(fp), F_SETLK, &lock);
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int passwd_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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 (new_password(pw, amroot, 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)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
struct utimbuf ub;
|
||||||
|
FILE *bkfp;
|
||||||
|
int c, mask;
|
||||||
|
|
||||||
|
if (fstat(fileno(fp), &sb))
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
mask = umask(077);
|
||||||
|
bkfp = fopen(backup, "w");
|
||||||
|
umask(mask);
|
||||||
|
if (!bkfp)
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* TODO: faster copy, not one-char-at-a-time. --marekm */
|
||||||
|
rewind(fp);
|
||||||
|
while ((c = getc(fp)) != EOF) {
|
||||||
|
if (putc(c, bkfp) == EOF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c != EOF || fflush(bkfp)) {
|
||||||
|
fclose(bkfp);
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (fclose(bkfp))
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ub.actime = sb.st_atime;
|
||||||
|
ub.modtime = sb.st_mtime;
|
||||||
|
utime(backup, &ub);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int i64c(int i)
|
||||||
|
{
|
||||||
|
if (i <= 0)
|
||||||
|
return ('.');
|
||||||
|
if (i == 1)
|
||||||
|
return ('/');
|
||||||
|
if (i >= 2 && i < 12)
|
||||||
|
return ('0' - 2 + i);
|
||||||
|
if (i >= 12 && i < 38)
|
||||||
|
return ('A' - 12 + i);
|
||||||
|
if (i >= 38 && i < 63)
|
||||||
|
return ('a' - 38 + i);
|
||||||
|
return ('z');
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *crypt_make_salt(void)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
static unsigned long x;
|
||||||
|
static char result[3];
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
x += now + getpid() + clock();
|
||||||
|
result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
|
||||||
|
result[1] = i64c(((x >> 12) ^ x) & 077);
|
||||||
|
result[2] = '\0';
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int new_password(const struct passwd *pw, int amroot, int algo)
|
||||||
|
{
|
||||||
|
char *clear;
|
||||||
|
char *cipher;
|
||||||
|
char *cp;
|
||||||
|
char orig[200];
|
||||||
|
char pass[200];
|
||||||
|
time_t start, now;
|
||||||
|
|
||||||
|
if (!amroot && crypt_passwd[0]) {
|
||||||
|
if (!(clear = getpass("Old password:"))) {
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
cipher = pw_encrypt(clear, crypt_passwd);
|
||||||
|
if (strcmp(cipher, crypt_passwd) != 0) {
|
||||||
|
syslog(LOG_WARNING, "incorrect password for `%s'",
|
||||||
|
pw->pw_name);
|
||||||
|
time(&start);
|
||||||
|
now = start;
|
||||||
|
while (difftime(now, start) < FAIL_DELAY) {
|
||||||
|
sleep(FAIL_DELAY);
|
||||||
|
time(&now);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Incorrect password.\n");
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_strncpy(orig, clear, sizeof(orig));
|
||||||
|
bzero(clear, strlen(clear));
|
||||||
|
bzero(cipher, strlen(cipher));
|
||||||
|
} else {
|
||||||
|
orig[0] = '\0';
|
||||||
|
}
|
||||||
|
if (!
|
||||||
|
(cp =
|
||||||
|
getpass ("Enter the new password (minimum of 5, maximum of 8 characters)\n""
|
||||||
|
Please use a combination of upper and lower case letters and numbers.\nEnter new password: ")))
|
||||||
|
{
|
||||||
|
bzero(orig, sizeof orig);
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_strncpy(pass, cp, sizeof(pass));
|
||||||
|
bzero(cp, strlen(cp));
|
||||||
|
/* if (!obscure(orig, pass, pw)) { */
|
||||||
|
if (obscure(orig, pass, pw)) {
|
||||||
|
if (amroot) {
|
||||||
|
printf("\nWarning: weak password (continuing).\n");
|
||||||
|
} else {
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(cp = getpass("Re-enter new password: "))) {
|
||||||
|
bzero(orig, sizeof orig);
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (strcmp(cp, pass)) {
|
||||||
|
fprintf(stderr, "Passwords do not match.\n");
|
||||||
|
/* return -1; */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bzero(cp, strlen(cp));
|
||||||
|
bzero(orig, sizeof(orig));
|
||||||
|
|
||||||
|
if (algo == 1) {
|
||||||
|
cp = pw_encrypt(pass, "$1$");
|
||||||
|
} else
|
||||||
|
cp = pw_encrypt(pass, crypt_make_salt());
|
||||||
|
bzero(pass, sizeof pass);
|
||||||
|
safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_filesize_limit(int blocks)
|
||||||
|
{
|
||||||
|
struct rlimit rlimit_fsize;
|
||||||
|
|
||||||
|
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
|
||||||
|
setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
/* vi: set sw=4 ts=4: */
|
/* vi: set sw=4 ts=4: */
|
||||||
|
|
||||||
#include "busybox.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -18,10 +16,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "pwd.h"
|
#include "busybox.h"
|
||||||
#include "grp.h"
|
|
||||||
|
|
||||||
#include "tinylogin.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +156,7 @@ int su_main ( int argc, char **argv )
|
|||||||
|
|
||||||
change_identity ( pw );
|
change_identity ( pw );
|
||||||
setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw );
|
setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw );
|
||||||
run_shell ( opt_shell, opt_loginshell, opt_command, opt_args );
|
run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args );
|
||||||
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
184
loginutils/sulogin.c
Normal file
184
loginutils/sulogin.c
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "busybox.h"
|
||||||
|
|
||||||
|
|
||||||
|
// sulogin defines
|
||||||
|
#define SULOGIN_PROMPT "\nGive root password for system maintenance\n" \
|
||||||
|
"(or type Control-D for normal startup):"
|
||||||
|
|
||||||
|
static const char *forbid[] = {
|
||||||
|
"ENV",
|
||||||
|
"BASH_ENV",
|
||||||
|
"HOME",
|
||||||
|
"IFS",
|
||||||
|
"PATH",
|
||||||
|
"SHELL",
|
||||||
|
"LD_LIBRARY_PATH",
|
||||||
|
"LD_PRELOAD",
|
||||||
|
"LD_TRACE_LOADED_OBJECTS",
|
||||||
|
"LD_BIND_NOW",
|
||||||
|
"LD_AOUT_LIBRARY_PATH",
|
||||||
|
"LD_AOUT_PRELOAD",
|
||||||
|
"LD_NOWARN",
|
||||||
|
"LD_KEEPDIR",
|
||||||
|
(char *) 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void catchalarm(int junk)
|
||||||
|
{
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int sulogin_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
char *device = (char *) 0;
|
||||||
|
const char *name = "root";
|
||||||
|
int timeout = 0;
|
||||||
|
static char pass[BUFSIZ];
|
||||||
|
struct termios termio;
|
||||||
|
struct passwd pwent;
|
||||||
|
struct passwd *pwd;
|
||||||
|
time_t start, now;
|
||||||
|
const char **p;
|
||||||
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
struct spwd *spwd = NULL;
|
||||||
|
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
||||||
|
|
||||||
|
tcgetattr(0, &termio);
|
||||||
|
/* set control chars */
|
||||||
|
termio.c_cc[VINTR] = 3; /* C-c */
|
||||||
|
termio.c_cc[VQUIT] = 28; /* C-\ */
|
||||||
|
termio.c_cc[VERASE] = 127; /* C-? */
|
||||||
|
termio.c_cc[VKILL] = 21; /* C-u */
|
||||||
|
termio.c_cc[VEOF] = 4; /* C-d */
|
||||||
|
termio.c_cc[VSTART] = 17; /* C-q */
|
||||||
|
termio.c_cc[VSTOP] = 19; /* C-s */
|
||||||
|
termio.c_cc[VSUSP] = 26; /* C-z */
|
||||||
|
/* use line dicipline 0 */
|
||||||
|
termio.c_line = 0;
|
||||||
|
/* Make it be sane */
|
||||||
|
termio.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
|
||||||
|
termio.c_cflag |= CREAD|HUPCL|CLOCAL;
|
||||||
|
/* input modes */
|
||||||
|
termio.c_iflag = ICRNL | IXON | IXOFF;
|
||||||
|
/* output modes */
|
||||||
|
termio.c_oflag = OPOST | ONLCR;
|
||||||
|
/* local modes */
|
||||||
|
termio.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
|
||||||
|
tcsetattr(0, TCSANOW, &termio);
|
||||||
|
openlog("sulogin", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
|
||||||
|
if (argc > 1) {
|
||||||
|
if (strncmp(argv[1], "-t", 2) == 0) {
|
||||||
|
if (strcmp(argv[1], "-t") == 0) {
|
||||||
|
if (argc > 2) {
|
||||||
|
timeout = atoi(argv[2]);
|
||||||
|
if (argc > 3) {
|
||||||
|
device = argv[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (argc > 2) {
|
||||||
|
device = argv[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
device = argv[1];
|
||||||
|
}
|
||||||
|
if (device) {
|
||||||
|
close(0);
|
||||||
|
close(1);
|
||||||
|
close(2);
|
||||||
|
if (open(device, O_RDWR) >= 0) {
|
||||||
|
dup(0);
|
||||||
|
dup(0);
|
||||||
|
} else {
|
||||||
|
syslog(LOG_WARNING, "cannot open %s\n", device);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (access(passwd_file, 0) == -1) {
|
||||||
|
syslog(LOG_WARNING, "No password file\n");
|
||||||
|
error_msg_and_die("No password file\n");
|
||||||
|
}
|
||||||
|
if (!isatty(0) || !isatty(1) || !isatty(2)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Clear out anything dangerous from the environment */
|
||||||
|
for (p = forbid; *p; p++)
|
||||||
|
unsetenv(*p);
|
||||||
|
|
||||||
|
|
||||||
|
signal(SIGALRM, catchalarm);
|
||||||
|
alarm(timeout);
|
||||||
|
if (!(pwd = getpwnam(name))) {
|
||||||
|
syslog(LOG_WARNING, "No password entry for `root'\n");
|
||||||
|
error_msg_and_die("No password entry for `root'\n");
|
||||||
|
}
|
||||||
|
pwent = *pwd;
|
||||||
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
spwd = NULL;
|
||||||
|
if (pwd && ((strcmp(pwd->pw_passwd, "x") == 0)
|
||||||
|
|| (strcmp(pwd->pw_passwd, "*") == 0))) {
|
||||||
|
endspent();
|
||||||
|
spwd = getspnam(name);
|
||||||
|
if (spwd) {
|
||||||
|
pwent.pw_passwd = spwd->sp_pwdp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
||||||
|
while (1) {
|
||||||
|
cp = getpass(SULOGIN_PROMPT);
|
||||||
|
if (!cp || !*cp) {
|
||||||
|
puts("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
syslog(LOG_INFO, "Normal startup\n");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
} else {
|
||||||
|
safe_strncpy(pass, cp, sizeof(pass));
|
||||||
|
bzero(cp, strlen(cp));
|
||||||
|
}
|
||||||
|
if (strcmp(pw_encrypt(pass, pwent.pw_passwd), pwent.pw_passwd) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
time(&start);
|
||||||
|
now = start;
|
||||||
|
while (difftime(now, start) < FAIL_DELAY) {
|
||||||
|
sleep(FAIL_DELAY);
|
||||||
|
time(&now);
|
||||||
|
}
|
||||||
|
puts("Login incorrect");
|
||||||
|
fflush(stdout);
|
||||||
|
syslog(LOG_WARNING, "Incorrect root password\n");
|
||||||
|
}
|
||||||
|
bzero(pass, strlen(pass));
|
||||||
|
alarm(0);
|
||||||
|
signal(SIGALRM, SIG_DFL);
|
||||||
|
puts("Entering System Maintenance Mode\n");
|
||||||
|
fflush(stdout);
|
||||||
|
syslog(LOG_INFO, "System Maintenance Mode\n");
|
||||||
|
run_shell(pwent.pw_shell, 1, 0, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef BB_LOGINUTILS_SHELL_H
|
|
||||||
#define BB_LOGINUTILS_SHELL_H
|
|
||||||
|
|
||||||
extern void change_identity ( const struct passwd *pw );
|
|
||||||
extern void run_shell ( const char *shell, int loginshell, const char *command, char **additional_args );
|
|
||||||
extern int restricted_shell ( const char *shell );
|
|
||||||
extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw );
|
|
||||||
extern int correct_password ( const struct passwd *pw );
|
|
||||||
|
|
||||||
#endif
|
|
229
loginutils/vlock.c
Normal file
229
loginutils/vlock.c
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* vlock implementation for busybox
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000 by spoon <spoon@ix.netcom.com>
|
||||||
|
* Written by spoon <spon@ix.netcom.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Shoutz to Michael K. Johnson <johnsonm@redhat.com>, author of the
|
||||||
|
* original vlock. I snagged a bunch of his code to write this
|
||||||
|
* minimalistic vlock.
|
||||||
|
*/
|
||||||
|
/* Fixed by Erik Andersen to do passwords the tinylogin way...
|
||||||
|
* It now works with md5, sha1, etc passwords. */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/vt.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include "busybox.h"
|
||||||
|
|
||||||
|
static struct passwd *pw;
|
||||||
|
static struct spwd *spw;
|
||||||
|
static struct vt_mode ovtm;
|
||||||
|
static struct termios oterm;
|
||||||
|
static int vfd;
|
||||||
|
static int o_lock_all = 0;
|
||||||
|
|
||||||
|
/* getspuid - get a shadow entry by uid */
|
||||||
|
struct spwd *getspuid(uid_t uid)
|
||||||
|
{
|
||||||
|
struct spwd *sp;
|
||||||
|
struct passwd *mypw;
|
||||||
|
|
||||||
|
if ((mypw = getpwuid(getuid())) == NULL) {
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
setspent();
|
||||||
|
while ((sp = getspent()) != NULL) {
|
||||||
|
if (strcmp(mypw->pw_name, sp->sp_namp) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
endspent();
|
||||||
|
return (sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void release_vt(int signo)
|
||||||
|
{
|
||||||
|
if (!o_lock_all)
|
||||||
|
ioctl(vfd, VT_RELDISP, 1);
|
||||||
|
else
|
||||||
|
ioctl(vfd, VT_RELDISP, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acquire_vt(int signo)
|
||||||
|
{
|
||||||
|
ioctl(vfd, VT_RELDISP, VT_ACKACQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void restore_terminal(void)
|
||||||
|
{
|
||||||
|
ioctl(vfd, VT_SETMODE, &ovtm);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &oterm);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int vlock_main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
sigset_t sig;
|
||||||
|
struct sigaction sa;
|
||||||
|
struct vt_mode vtm;
|
||||||
|
int times = 0;
|
||||||
|
struct termios term;
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
show_usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
if (strncmp(argv[1], "-a", 2)) {
|
||||||
|
show_usage();
|
||||||
|
} else {
|
||||||
|
o_lock_all = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pw = getpwuid(getuid())) == NULL) {
|
||||||
|
error_msg_and_die("no password for uid %d\n", getuid());
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_FEATURE_SHADOWPASSWDS
|
||||||
|
if ((strcmp(pw->pw_passwd, "x") == 0)
|
||||||
|
|| (strcmp(pw->pw_passwd, "*") == 0)) {
|
||||||
|
|
||||||
|
if ((spw = getspuid(getuid())) == NULL) {
|
||||||
|
error_msg_and_die("could not read shadow password for uid %d: %s\n",
|
||||||
|
getuid(), strerror(errno));
|
||||||
|
}
|
||||||
|
if (spw->sp_pwdp) {
|
||||||
|
pw->pw_passwd = spw->sp_pwdp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FEATURE_SHADOWPASSWDS */
|
||||||
|
if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') {
|
||||||
|
error_msg_and_die("Account disabled for uid %d\n", getuid());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we no longer need root privs */
|
||||||
|
setuid(getuid());
|
||||||
|
setgid(getgid());
|
||||||
|
|
||||||
|
if ((vfd = open("/dev/tty", O_RDWR)) < 0) {
|
||||||
|
error_msg_and_die("/dev/tty");
|
||||||
|
};
|
||||||
|
|
||||||
|
if (ioctl(vfd, VT_GETMODE, &vtm) < 0) {
|
||||||
|
error_msg_and_die("/dev/tty");
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mask a bunch of signals */
|
||||||
|
sigprocmask(SIG_SETMASK, NULL, &sig);
|
||||||
|
sigdelset(&sig, SIGUSR1);
|
||||||
|
sigdelset(&sig, SIGUSR2);
|
||||||
|
sigaddset(&sig, SIGTSTP);
|
||||||
|
sigaddset(&sig, SIGTTIN);
|
||||||
|
sigaddset(&sig, SIGTTOU);
|
||||||
|
sigaddset(&sig, SIGHUP);
|
||||||
|
sigaddset(&sig, SIGCHLD);
|
||||||
|
sigaddset(&sig, SIGQUIT);
|
||||||
|
sigaddset(&sig, SIGINT);
|
||||||
|
|
||||||
|
sigemptyset(&(sa.sa_mask));
|
||||||
|
sa.sa_flags = SA_RESTART;
|
||||||
|
sa.sa_handler = release_vt;
|
||||||
|
sigaction(SIGUSR1, &sa, NULL);
|
||||||
|
sa.sa_handler = acquire_vt;
|
||||||
|
sigaction(SIGUSR2, &sa, NULL);
|
||||||
|
|
||||||
|
/* need to handle some signals so that we don't get killed by them */
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
sigaction(SIGHUP, &sa, NULL);
|
||||||
|
sigaction(SIGQUIT, &sa, NULL);
|
||||||
|
sigaction(SIGINT, &sa, NULL);
|
||||||
|
sigaction(SIGTSTP, &sa, NULL);
|
||||||
|
|
||||||
|
ovtm = vtm;
|
||||||
|
vtm.mode = VT_PROCESS;
|
||||||
|
vtm.relsig = SIGUSR1;
|
||||||
|
vtm.acqsig = SIGUSR2;
|
||||||
|
ioctl(vfd, VT_SETMODE, &vtm);
|
||||||
|
|
||||||
|
tcgetattr(STDIN_FILENO, &oterm);
|
||||||
|
term = oterm;
|
||||||
|
term.c_iflag &= ~BRKINT;
|
||||||
|
term.c_iflag |= IGNBRK;
|
||||||
|
term.c_lflag &= ~ISIG;
|
||||||
|
term.c_lflag &= ~(ECHO | ECHOCTL);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &term);
|
||||||
|
|
||||||
|
do {
|
||||||
|
char *pass, *crypt_pass;
|
||||||
|
char prompt[100];
|
||||||
|
|
||||||
|
if (o_lock_all) {
|
||||||
|
printf("All Virtual Consoles locked.\n");
|
||||||
|
} else {
|
||||||
|
printf("This Virtual Console locked.\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
snprintf(prompt, 100, "%s's password: ", pw->pw_name);
|
||||||
|
|
||||||
|
if ((pass = getpass(prompt)) == NULL) {
|
||||||
|
perror("getpass");
|
||||||
|
restore_terminal();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
crypt_pass = pw_encrypt(pass, pw->pw_passwd);
|
||||||
|
if (strncmp(crypt_pass, pw->pw_passwd, sizeof(crypt_pass)) == 0) {
|
||||||
|
memset(pass, 0, strlen(pass));
|
||||||
|
memset(crypt_pass, 0, strlen(crypt_pass));
|
||||||
|
restore_terminal();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(pass, 0, strlen(pass));
|
||||||
|
memset(crypt_pass, 0, strlen(crypt_pass));
|
||||||
|
|
||||||
|
if (isatty(STDIN_FILENO) == 0) {
|
||||||
|
perror("isatty");
|
||||||
|
restore_terminal();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(++times);
|
||||||
|
printf("Password incorrect.\n");
|
||||||
|
if (times >= 3) {
|
||||||
|
sleep(15);
|
||||||
|
times = 2;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Local Variables:
|
||||||
|
c-file-style: "linux"
|
||||||
|
c-basic-offset: 4
|
||||||
|
tab-width: 4
|
||||||
|
End:
|
||||||
|
*/
|
Loading…
Reference in New Issue
Block a user