diff options
author | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-06-23 04:24:25 +0000 |
---|---|---|
committer | andersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-06-23 04:24:25 +0000 |
commit | a99f567fcd02370d96d496993ec01f3ae57eec1b (patch) | |
tree | 632fbb26b13ad67f6efa335c33a22551b2707930 | |
parent | 7266ca05a5470f5998adf16f30a34e490461ac44 (diff) | |
download | busybox-w32-a99f567fcd02370d96d496993ec01f3ae57eec1b.tar.gz busybox-w32-a99f567fcd02370d96d496993ec01f3ae57eec1b.tar.bz2 busybox-w32-a99f567fcd02370d96d496993ec01f3ae57eec1b.zip |
Port over the last of the tinylogin applets
-Erik
git-svn-id: svn://busybox.net/trunk/busybox@4961 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r-- | include/applets.h | 9 | ||||
-rw-r--r-- | include/libbb.h | 30 | ||||
-rw-r--r-- | include/shadow_.h | 82 | ||||
-rw-r--r-- | include/usage.h | 34 | ||||
-rw-r--r-- | libbb/Makefile.in | 10 | ||||
-rw-r--r-- | libbb/change_identity.c | 54 | ||||
-rw-r--r-- | libbb/correct_password.c | 78 | ||||
-rw-r--r-- | libbb/libc5.c | 18 | ||||
-rw-r--r-- | libbb/messages.c | 36 | ||||
-rw-r--r-- | libbb/obscure.c | 246 | ||||
-rw-r--r-- | libbb/pw_encrypt.c | 48 | ||||
-rw-r--r-- | libbb/pwd2spwd.c | 73 | ||||
-rw-r--r-- | libbb/restricted_shell.c | 57 | ||||
-rw-r--r-- | libbb/run_shell.c | 81 | ||||
-rw-r--r-- | libbb/setup_environment.c (renamed from loginutils/tinylogin.c) | 122 | ||||
-rw-r--r-- | loginutils/Makefile.in | 9 | ||||
-rw-r--r-- | loginutils/addgroup.c | 9 | ||||
-rw-r--r-- | loginutils/adduser.c | 56 | ||||
-rw-r--r-- | loginutils/config.in | 17 | ||||
-rw-r--r-- | loginutils/deluser.c | 28 | ||||
-rw-r--r-- | loginutils/login.c | 43 | ||||
-rw-r--r-- | loginutils/passwd.c | 408 | ||||
-rw-r--r-- | loginutils/su.c | 9 | ||||
-rw-r--r-- | loginutils/sulogin.c | 184 | ||||
-rw-r--r-- | loginutils/tinylogin.h | 10 | ||||
-rw-r--r-- | loginutils/vlock.c | 229 |
26 files changed, 1722 insertions, 258 deletions
diff --git a/include/applets.h b/include/applets.h index 3a8c731a5..c2d7acf4b 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -335,6 +335,9 @@ | |||
335 | #ifdef CONFIG_OD | 335 | #ifdef CONFIG_OD |
336 | APPLET(od, od_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) | 336 | APPLET(od, od_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) |
337 | #endif | 337 | #endif |
338 | #ifdef CONFIG_PASSWD | ||
339 | APPLET(passwd, passwd_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS) | ||
340 | #endif | ||
338 | #ifdef CONFIG_PIDOF | 341 | #ifdef CONFIG_PIDOF |
339 | APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER) | 342 | APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER) |
340 | #endif | 343 | #endif |
@@ -419,6 +422,9 @@ | |||
419 | #ifdef CONFIG_SU | 422 | #ifdef CONFIG_SU |
420 | APPLET(su, su_main, _BB_DIR_BIN, _BB_SUID_ALWAYS) | 423 | APPLET(su, su_main, _BB_DIR_BIN, _BB_SUID_ALWAYS) |
421 | #endif | 424 | #endif |
425 | #ifdef CONFIG_SULOGIN | ||
426 | APPLET(sulogin, sulogin_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | ||
427 | #endif | ||
422 | #ifdef CONFIG_SWAPONOFF | 428 | #ifdef CONFIG_SWAPONOFF |
423 | APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | 429 | APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER) |
424 | #endif | 430 | #endif |
@@ -505,6 +511,9 @@ | |||
505 | #ifdef CONFIG_VI | 511 | #ifdef CONFIG_VI |
506 | APPLET(vi, vi_main, _BB_DIR_BIN, _BB_SUID_NEVER) | 512 | APPLET(vi, vi_main, _BB_DIR_BIN, _BB_SUID_NEVER) |
507 | #endif | 513 | #endif |
514 | #ifdef CONFIG_VLOCK | ||
515 | APPLET(vlock, vlock_main, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS) | ||
516 | #endif | ||
508 | #ifdef CONFIG_WATCHDOG | 517 | #ifdef CONFIG_WATCHDOG |
509 | APPLET(watchdog, watchdog_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | 518 | APPLET(watchdog, watchdog_main, _BB_DIR_SBIN, _BB_SUID_NEVER) |
510 | #endif | 519 | #endif |
diff --git a/include/libbb.h b/include/libbb.h index 0b2411fcd..2b9fd5fd6 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -39,6 +39,16 @@ | |||
39 | 39 | ||
40 | #include "config.h" | 40 | #include "config.h" |
41 | 41 | ||
42 | #include "pwd.h" | ||
43 | #include "grp.h" | ||
44 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
45 | #include "shadow_.h" | ||
46 | #endif | ||
47 | #ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
48 | # include "sha1.h" | ||
49 | #endif | ||
50 | |||
51 | |||
42 | #if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__) | 52 | #if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__) |
43 | /* libc5 doesn't define socklen_t */ | 53 | /* libc5 doesn't define socklen_t */ |
44 | typedef unsigned int socklen_t; | 54 | typedef unsigned int socklen_t; |
@@ -260,6 +270,15 @@ extern const char * const too_few_args; | |||
260 | extern const char * const name_longer_than_foo; | 270 | extern const char * const name_longer_than_foo; |
261 | extern const char * const unknown; | 271 | extern const char * const unknown; |
262 | extern const char * const can_not_create_raw_socket; | 272 | extern const char * const can_not_create_raw_socket; |
273 | extern const char * const nologin_file; | ||
274 | extern const char * const passwd_file; | ||
275 | extern const char * const shadow_file; | ||
276 | extern const char * const gshadow_file; | ||
277 | extern const char * const group_file; | ||
278 | extern const char * const securetty_file; | ||
279 | extern const char * const motd_file; | ||
280 | extern const char * const issue_file; | ||
281 | extern const char * const _path_login; | ||
263 | 282 | ||
264 | #ifdef CONFIG_FEATURE_DEVFS | 283 | #ifdef CONFIG_FEATURE_DEVFS |
265 | # define CURRENT_VC "/dev/vc/0" | 284 | # define CURRENT_VC "/dev/vc/0" |
@@ -299,4 +318,15 @@ void reset_ino_dev_hashtable(void); | |||
299 | extern size_t xstrlen(const char *string); | 318 | extern size_t xstrlen(const char *string); |
300 | #define strlen(x) xstrlen(x) | 319 | #define strlen(x) xstrlen(x) |
301 | 320 | ||
321 | |||
322 | #define FAIL_DELAY 3 | ||
323 | extern void change_identity ( const struct passwd *pw ); | ||
324 | extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args ); | ||
325 | extern int restricted_shell ( const char *shell ); | ||
326 | extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ); | ||
327 | extern int correct_password ( const struct passwd *pw ); | ||
328 | extern char *pw_encrypt(const char *clear, const char *salt); | ||
329 | extern struct spwd *pwd_to_spwd(const struct passwd *pw); | ||
330 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp); | ||
331 | |||
302 | #endif /* __LIBCONFIG_H__ */ | 332 | #endif /* __LIBCONFIG_H__ */ |
diff --git a/include/shadow_.h b/include/shadow_.h new file mode 100644 index 000000000..a677d5262 --- /dev/null +++ b/include/shadow_.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * Copyright 1988 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * 2. Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
14 | * may be used to endorse or promote products derived from this software | ||
15 | * without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
20 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
27 | * SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | #ifndef _H_SHADOW | ||
31 | #define _H_SHADOW | ||
32 | |||
33 | |||
34 | #ifdef USE_SYSTEM_SHADOW | ||
35 | #include <shadow.h> | ||
36 | #else | ||
37 | |||
38 | /* | ||
39 | * This information is not derived from AT&T licensed sources. Posted | ||
40 | * to the USENET 11/88, and updated 11/90 with information from SVR4. | ||
41 | * | ||
42 | * $Id: shadow_.h,v 1.1 2002/06/23 04:24:20 andersen Exp $ | ||
43 | */ | ||
44 | |||
45 | typedef long sptime; | ||
46 | |||
47 | /* | ||
48 | * Shadow password security file structure. | ||
49 | */ | ||
50 | |||
51 | struct spwd { | ||
52 | char *sp_namp; /* login name */ | ||
53 | char *sp_pwdp; /* encrypted password */ | ||
54 | sptime sp_lstchg; /* date of last change */ | ||
55 | sptime sp_min; /* minimum number of days between changes */ | ||
56 | sptime sp_max; /* maximum number of days between changes */ | ||
57 | sptime sp_warn; /* number of days of warning before password | ||
58 | expires */ | ||
59 | sptime sp_inact; /* number of days after password expires | ||
60 | until the account becomes unusable. */ | ||
61 | sptime sp_expire; /* days since 1/1/70 until account expires */ | ||
62 | unsigned long sp_flag; /* reserved for future use */ | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * Shadow password security file functions. | ||
67 | */ | ||
68 | |||
69 | #include <stdio.h> /* for FILE */ | ||
70 | |||
71 | extern struct spwd *getspent(void); | ||
72 | extern struct spwd *sgetspent(const char *); | ||
73 | extern struct spwd *fgetspent(FILE *); | ||
74 | extern void setspent(void); | ||
75 | extern void endspent(void); | ||
76 | extern int putspent(const struct spwd *, FILE *); | ||
77 | extern struct spwd *getspnam(const char *name); | ||
78 | extern struct spwd *pwd_to_spwd(const struct passwd *pw); | ||
79 | |||
80 | #endif /* USE_LOCAL_SHADOW */ | ||
81 | |||
82 | #endif /* _H_SHADOW */ | ||
diff --git a/include/usage.h b/include/usage.h index 08ee00d77..18593fb1d 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -1321,6 +1321,24 @@ | |||
1321 | "Write an unambiguous representation, octal bytes by default, of FILE\n"\ | 1321 | "Write an unambiguous representation, octal bytes by default, of FILE\n"\ |
1322 | "to standard output. With no FILE, or when FILE is -, read standard input." | 1322 | "to standard output. With no FILE, or when FILE is -, read standard input." |
1323 | 1323 | ||
1324 | #ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
1325 | #define PASSWORD_ALG_TYPES(a) a | ||
1326 | #else | ||
1327 | #define PASSWORD_ALG_TYPES(a) | ||
1328 | #endif | ||
1329 | #define passwd_trivial_usage \ | ||
1330 | "[OPTION] [name]" | ||
1331 | #define passwd_full_usage \ | ||
1332 | "CChange a user password. If no name is specified,\n" \ | ||
1333 | "changes the password for the current user.\n" \ | ||
1334 | "Options:\n" \ | ||
1335 | "\t-a\tDefine which algorithm shall be used for the password.\n" \ | ||
1336 | "\t\t\t(Choices: des, md5" \ | ||
1337 | CONFIG_FEATURE_SHA1_PASSWORDS(", sha1") \ | ||
1338 | ")\n\t-d\tDelete the password for the specified user account.\n" \ | ||
1339 | "\t-l\tLocks (disables) the specified user account.\n" \ | ||
1340 | "\t-u\tUnlocks (re-enables) the specified user account."; | ||
1341 | |||
1324 | #define pidof_trivial_usage \ | 1342 | #define pidof_trivial_usage \ |
1325 | "process-name [process-name ...]" | 1343 | "process-name [process-name ...]" |
1326 | #define pidof_full_usage \ | 1344 | #define pidof_full_usage \ |
@@ -1586,6 +1604,15 @@ | |||
1586 | "Options:\n" \ | 1604 | "Options:\n" \ |
1587 | "\t-p\tPreserve environment" | 1605 | "\t-p\tPreserve environment" |
1588 | 1606 | ||
1607 | #define sulogin_trivial_usage \ | ||
1608 | "[OPTION]... [tty-device]" | ||
1609 | #define sulogin_full_usage \ | ||
1610 | "Single user login\n" \ | ||
1611 | "Options:\n" \ | ||
1612 | "\t-f\tDo not authenticate (user already authenticated)\n" \ | ||
1613 | "\t-h\tName of the remote host for this login.\n" \ | ||
1614 | "\t-p\tPreserve environment." | ||
1615 | |||
1589 | #define swapoff_trivial_usage \ | 1616 | #define swapoff_trivial_usage \ |
1590 | "[OPTION] [DEVICE]" | 1617 | "[OPTION] [DEVICE]" |
1591 | #define swapoff_full_usage \ | 1618 | #define swapoff_full_usage \ |
@@ -1956,6 +1983,13 @@ | |||
1956 | "Options:\n" \ | 1983 | "Options:\n" \ |
1957 | "\t-R\tRead-only- do not write to the file." | 1984 | "\t-R\tRead-only- do not write to the file." |
1958 | 1985 | ||
1986 | #define vlock_trivial_usage \ | ||
1987 | "[OPTIONS]" | ||
1988 | #define vlock_full_usage \ | ||
1989 | "Lock a virtual terminal. A password is required to unlock\n" \ | ||
1990 | "Options:\n" \ | ||
1991 | "\t-a\tLock all VTs" | ||
1992 | |||
1959 | #define watchdog_trivial_usage \ | 1993 | #define watchdog_trivial_usage \ |
1960 | "DEV" | 1994 | "DEV" |
1961 | #define watchdog_full_usage \ | 1995 | #define watchdog_full_usage \ |
diff --git a/libbb/Makefile.in b/libbb/Makefile.in index c6493bfa6..2af70f8c7 100644 --- a/libbb/Makefile.in +++ b/libbb/Makefile.in | |||
@@ -34,17 +34,21 @@ LIBBB_SRC:= \ | |||
34 | my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \ | 34 | my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \ |
35 | print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \ | 35 | print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \ |
36 | safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \ | 36 | safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \ |
37 | trim.c unzip.c uncompress.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \ | 37 | trim.c unzip.c uncompress.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c \ |
38 | xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \ | 38 | xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \ |
39 | copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \ | 39 | copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \ |
40 | dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \ | 40 | dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \ |
41 | simplify_path.c inet_common.c inode_hash.c | 41 | simplify_path.c inet_common.c inode_hash.c obscure.c pwd2spwd.c xfuncs.c \ |
42 | correct_password.c change_identity.c setup_environment.c run_shell.c \ | ||
43 | pw_encrypt.c restricted_shell.c | ||
42 | LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC)) | 44 | LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC)) |
43 | 45 | ||
44 | LIBBB_MSRC:=$(LIBBB_DIR)messages.c | 46 | LIBBB_MSRC:=$(LIBBB_DIR)messages.c |
45 | LIBBB_MOBJ:=full_version.o name_too_long.o omitting_directory.o not_a_directory.o \ | 47 | LIBBB_MOBJ:=full_version.o name_too_long.o omitting_directory.o not_a_directory.o \ |
46 | memory_exhausted.o invalid_date.o invalid_option.o io_error.o dash_dash_help.o \ | 48 | memory_exhausted.o invalid_date.o invalid_option.o io_error.o dash_dash_help.o \ |
47 | write_error.o too_few_args.o name_longer_than_foo.o unknown.o can_not_create_raw_socket.o | 49 | write_error.o too_few_args.o name_longer_than_foo.o unknown.o can_not_create_raw_socket.o \ |
50 | shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o securetty_file.o \ | ||
51 | motd_file.o | ||
48 | LIBBB_MOBJS=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ)) | 52 | LIBBB_MOBJS=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ)) |
49 | 53 | ||
50 | libraries-y+=$(LIBBB_DIR)$(LIBBB_AR) | 54 | libraries-y+=$(LIBBB_DIR)$(LIBBB_AR) |
diff --git a/libbb/change_identity.c b/libbb/change_identity.c new file mode 100644 index 000000000..819b216e0 --- /dev/null +++ b/libbb/change_identity.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <errno.h> | ||
33 | #include <unistd.h> | ||
34 | #include <string.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <syslog.h> | ||
37 | #include <ctype.h> | ||
38 | |||
39 | #include "libbb.h" | ||
40 | |||
41 | |||
42 | /* Become the user and group(s) specified by PW. */ | ||
43 | void change_identity ( const struct passwd *pw ) | ||
44 | { | ||
45 | if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 ) | ||
46 | perror_msg_and_die ( "cannot set groups" ); | ||
47 | endgrent ( ); | ||
48 | |||
49 | if ( setgid ( pw-> pw_gid )) | ||
50 | perror_msg_and_die ( "cannot set group id" ); | ||
51 | if ( setuid ( pw->pw_uid )) | ||
52 | perror_msg_and_die ( "cannot set user id" ); | ||
53 | } | ||
54 | |||
diff --git a/libbb/correct_password.c b/libbb/correct_password.c new file mode 100644 index 000000000..758b89eed --- /dev/null +++ b/libbb/correct_password.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <errno.h> | ||
33 | #include <unistd.h> | ||
34 | #include <string.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <syslog.h> | ||
37 | #include <ctype.h> | ||
38 | #include <crypt.h> | ||
39 | |||
40 | #include "libbb.h" | ||
41 | |||
42 | |||
43 | |||
44 | /* Ask the user for a password. | ||
45 | Return 1 if the user gives the correct password for entry PW, | ||
46 | 0 if not. Return 1 without asking for a password if run by UID 0 | ||
47 | or if PW has an empty password. */ | ||
48 | |||
49 | int correct_password ( const struct passwd *pw ) | ||
50 | { | ||
51 | char *unencrypted, *encrypted, *correct; | ||
52 | |||
53 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
54 | if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) { | ||
55 | struct spwd *sp = getspnam ( pw-> pw_name ); | ||
56 | |||
57 | if ( !sp ) | ||
58 | error_msg_and_die ( "no valid shadow password" ); | ||
59 | |||
60 | correct = sp-> sp_pwdp; | ||
61 | } | ||
62 | else | ||
63 | #endif | ||
64 | correct = pw-> pw_passwd; | ||
65 | |||
66 | if ( correct == 0 || correct[0] == '\0' ) | ||
67 | return 1; | ||
68 | |||
69 | unencrypted = getpass ( "Password: " ); | ||
70 | if ( !unencrypted ) | ||
71 | { | ||
72 | fputs ( "getpass: cannot open /dev/tty\n", stderr ); | ||
73 | return 0; | ||
74 | } | ||
75 | encrypted = crypt ( unencrypted, correct ); | ||
76 | memset ( unencrypted, 0, xstrlen ( unencrypted )); | ||
77 | return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0; | ||
78 | } | ||
diff --git a/libbb/libc5.c b/libbb/libc5.c index df622f65b..af15d1ac7 100644 --- a/libbb/libc5.c +++ b/libbb/libc5.c | |||
@@ -11,6 +11,24 @@ | |||
11 | 11 | ||
12 | #if __GNU_LIBRARY__ < 5 | 12 | #if __GNU_LIBRARY__ < 5 |
13 | 13 | ||
14 | /* | ||
15 | * Some systems already have updwtmp(). Some don't... This is | ||
16 | * the updwtmp() implementation from uClibc, Copyright 2002 by | ||
17 | * Erik Andersen <andersee@debian.org> | ||
18 | */ | ||
19 | extern void updwtmp(const char *wtmp_file, const struct utmp *lutmp) | ||
20 | { | ||
21 | int fd; | ||
22 | |||
23 | fd = open(wtmp_file, O_APPEND | O_WRONLY, 0); | ||
24 | if (fd >= 0) { | ||
25 | if (lockf(fd, F_LOCK, 0)==0) { | ||
26 | write(fd, (const char *) lutmp, sizeof(struct utmp)); | ||
27 | lockf(fd, F_ULOCK, 0); | ||
28 | close(fd); | ||
29 | } | ||
30 | } | ||
31 | } | ||
14 | 32 | ||
15 | /* Copyright (C) 1991 Free Software Foundation, Inc. | 33 | /* Copyright (C) 1991 Free Software Foundation, Inc. |
16 | This file is part of the GNU C Library. | 34 | This file is part of the GNU C Library. |
diff --git a/libbb/messages.c b/libbb/messages.c index 895cfdc2b..185c1ee91 100644 --- a/libbb/messages.c +++ b/libbb/messages.c | |||
@@ -66,3 +66,39 @@ | |||
66 | #ifdef L_can_not_create_raw_socket | 66 | #ifdef L_can_not_create_raw_socket |
67 | const char * const can_not_create_raw_socket = "can`t create raw socket"; | 67 | const char * const can_not_create_raw_socket = "can`t create raw socket"; |
68 | #endif | 68 | #endif |
69 | |||
70 | #ifdef L_passwd_file | ||
71 | #define PASSWD_FILE "/etc/passwd" | ||
72 | const char * const passwd_file = PASSWD_FILE; | ||
73 | #endif | ||
74 | |||
75 | #ifdef L_shadow_file | ||
76 | #define SHADOW_FILE "/etc/shadow" | ||
77 | const char * const shadow_file = SHADOW_FILE; | ||
78 | #endif | ||
79 | |||
80 | #ifdef L_group_file | ||
81 | #define GROUP_FILE "/etc/group" | ||
82 | const char * const group_file = GROUP_FILE; | ||
83 | #endif | ||
84 | |||
85 | #ifdef L_gshadow_file | ||
86 | #define GSHADOW_FILE "/etc/gshadow" | ||
87 | const char * const gshadow_file = GSHADOW_FILE; | ||
88 | #endif | ||
89 | |||
90 | #ifdef L_nologin_file | ||
91 | #define NOLOGIN_FILE "/etc/nologin" | ||
92 | const char * const nologin_file = NOLOGIN_FILE; | ||
93 | #endif | ||
94 | |||
95 | #ifdef L_securetty_file | ||
96 | #define SECURETTY_FILE "/etc/securetty" | ||
97 | const char * const securetty_file = SECURETTY_FILE; | ||
98 | #endif | ||
99 | |||
100 | #ifdef L_motd_file | ||
101 | #define MOTD_FILE "/etc/motd" | ||
102 | const char * const motd_file = MOTD_FILE; | ||
103 | #endif | ||
104 | |||
diff --git a/libbb/obscure.c b/libbb/obscure.c new file mode 100644 index 000000000..dc7de751d --- /dev/null +++ b/libbb/obscure.c | |||
@@ -0,0 +1,246 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | * This version of obscure.c contains modifications to support "cracklib" | ||
33 | * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib | ||
34 | * library source code for this function to operate. | ||
35 | */ | ||
36 | |||
37 | #include <stdlib.h> | ||
38 | #include <stdio.h> | ||
39 | #include <string.h> | ||
40 | #include <ctype.h> | ||
41 | #include "libbb.h" | ||
42 | |||
43 | /* | ||
44 | * can't be a palindrome - like `R A D A R' or `M A D A M' | ||
45 | */ | ||
46 | |||
47 | static int palindrome(const char *old, const char *newval) | ||
48 | { | ||
49 | int i, j; | ||
50 | |||
51 | i = strlen(newval); | ||
52 | |||
53 | for (j = 0; j < i; j++) | ||
54 | if (newval[i - j - 1] != newval[j]) | ||
55 | return 0; | ||
56 | |||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * more than half of the characters are different ones. | ||
62 | */ | ||
63 | |||
64 | static int similiar(const char *old, const char *newval) | ||
65 | { | ||
66 | int i, j; | ||
67 | |||
68 | for (i = j = 0; newval[i] && old[i]; i++) | ||
69 | if (strchr(newval, old[i])) | ||
70 | j++; | ||
71 | |||
72 | if (i >= j * 2) | ||
73 | return 0; | ||
74 | |||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * a nice mix of characters. | ||
80 | */ | ||
81 | |||
82 | static int simple(const char *old, const char *newval) | ||
83 | { | ||
84 | int digits = 0; | ||
85 | int uppers = 0; | ||
86 | int lowers = 0; | ||
87 | int others = 0; | ||
88 | int size; | ||
89 | int i; | ||
90 | |||
91 | for (i = 0; newval[i]; i++) { | ||
92 | if (isdigit(newval[i])) | ||
93 | digits++; | ||
94 | else if (isupper(newval[i])) | ||
95 | uppers++; | ||
96 | else if (islower(newval[i])) | ||
97 | lowers++; | ||
98 | else | ||
99 | others++; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * The scam is this - a password of only one character type | ||
104 | * must be 8 letters long. Two types, 7, and so on. | ||
105 | */ | ||
106 | |||
107 | size = 9; | ||
108 | if (digits) | ||
109 | size--; | ||
110 | if (uppers) | ||
111 | size--; | ||
112 | if (lowers) | ||
113 | size--; | ||
114 | if (others) | ||
115 | size--; | ||
116 | |||
117 | if (size <= i) | ||
118 | return 0; | ||
119 | |||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | static char *str_lower(char *string) | ||
124 | { | ||
125 | char *cp; | ||
126 | |||
127 | for (cp = string; *cp; cp++) | ||
128 | *cp = tolower(*cp); | ||
129 | return string; | ||
130 | } | ||
131 | |||
132 | static char *password_check(const char *old, const char *newval, const struct passwd *pwdp) | ||
133 | { | ||
134 | char *msg = NULL; | ||
135 | char *oldmono, *newmono, *wrapped; | ||
136 | |||
137 | if (strcmp(newval, old) == 0) | ||
138 | return "no change"; | ||
139 | |||
140 | newmono = str_lower(xstrdup(newval)); | ||
141 | oldmono = str_lower(xstrdup(old)); | ||
142 | wrapped = (char *) xmalloc(strlen(oldmono) * 2 + 1); | ||
143 | strcpy(wrapped, oldmono); | ||
144 | strcat(wrapped, oldmono); | ||
145 | |||
146 | if (palindrome(oldmono, newmono)) | ||
147 | msg = "a palindrome"; | ||
148 | |||
149 | if (!msg && strcmp(oldmono, newmono) == 0) | ||
150 | msg = "case changes only"; | ||
151 | |||
152 | if (!msg && similiar(oldmono, newmono)) | ||
153 | msg = "too similiar"; | ||
154 | |||
155 | if (!msg && simple(old, newval)) | ||
156 | msg = "too simple"; | ||
157 | |||
158 | if (!msg && strstr(wrapped, newmono)) | ||
159 | msg = "rotated"; | ||
160 | |||
161 | bzero(newmono, strlen(newmono)); | ||
162 | bzero(oldmono, strlen(oldmono)); | ||
163 | bzero(wrapped, strlen(wrapped)); | ||
164 | free(newmono); | ||
165 | free(oldmono); | ||
166 | free(wrapped); | ||
167 | |||
168 | return msg; | ||
169 | } | ||
170 | |||
171 | static char *obscure_msg(const char *old, const char *newval, const struct passwd *pwdp) | ||
172 | { | ||
173 | int maxlen, oldlen, newlen; | ||
174 | char *new1, *old1, *msg; | ||
175 | |||
176 | oldlen = strlen(old); | ||
177 | newlen = strlen(newval); | ||
178 | |||
179 | #if 0 /* why not check the password when set for the first time? --marekm */ | ||
180 | if (old[0] == '\0') | ||
181 | /* return (1); */ | ||
182 | return NULL; | ||
183 | #endif | ||
184 | |||
185 | if (newlen < 5) | ||
186 | return "too short"; | ||
187 | |||
188 | /* | ||
189 | * Remaining checks are optional. | ||
190 | */ | ||
191 | /* Not for us -- Sean | ||
192 | *if (!getdef_bool("OBSCURE_CHECKS_ENAB")) | ||
193 | * return NULL; | ||
194 | */ | ||
195 | msg = password_check(old, newval, pwdp); | ||
196 | if (msg) | ||
197 | return msg; | ||
198 | |||
199 | /* The traditional crypt() truncates passwords to 8 chars. It is | ||
200 | possible to circumvent the above checks by choosing an easy | ||
201 | 8-char password and adding some random characters to it... | ||
202 | Example: "password$%^&*123". So check it again, this time | ||
203 | truncated to the maximum length. Idea from npasswd. --marekm */ | ||
204 | |||
205 | maxlen = 8; | ||
206 | if (oldlen <= maxlen && newlen <= maxlen) | ||
207 | return NULL; | ||
208 | |||
209 | new1 = (char *) xstrdup(newval); | ||
210 | old1 = (char *) xstrdup(old); | ||
211 | if (newlen > maxlen) | ||
212 | new1[maxlen] = '\0'; | ||
213 | if (oldlen > maxlen) | ||
214 | old1[maxlen] = '\0'; | ||
215 | |||
216 | msg = password_check(old1, new1, pwdp); | ||
217 | |||
218 | bzero(new1, newlen); | ||
219 | bzero(old1, oldlen); | ||
220 | free(new1); | ||
221 | free(old1); | ||
222 | |||
223 | return msg; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * Obscure - see if password is obscure enough. | ||
228 | * | ||
229 | * The programmer is encouraged to add as much complexity to this | ||
230 | * routine as desired. Included are some of my favorite ways to | ||
231 | * check passwords. | ||
232 | */ | ||
233 | |||
234 | extern int obscure(const char *old, const char *newval, const struct passwd *pwdp) | ||
235 | { | ||
236 | char *msg = obscure_msg(old, newval, pwdp); | ||
237 | |||
238 | /* if (msg) { */ | ||
239 | if (msg != NULL) { | ||
240 | printf("Bad password: %s.\n", msg); | ||
241 | /* return 0; */ | ||
242 | return 1; | ||
243 | } | ||
244 | /* return 1; */ | ||
245 | return 0; | ||
246 | } | ||
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c new file mode 100644 index 000000000..0e4eb9f8a --- /dev/null +++ b/libbb/pw_encrypt.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routine. | ||
4 | * | ||
5 | * Copyright (C) 1999-2002 by Erik Andersen <andersee@debian.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <string.h> | ||
24 | #include <crypt.h> | ||
25 | #include "libbb.h" | ||
26 | |||
27 | |||
28 | extern char *pw_encrypt(const char *clear, const char *salt) | ||
29 | { | ||
30 | static char cipher[128]; | ||
31 | char *cp; | ||
32 | |||
33 | #ifdef CONFIG_FEATURE_SHA1_PASSWORDS | ||
34 | if (strncmp(salt, "$2$", 3) == 0) { | ||
35 | return sha1_crypt(clear); | ||
36 | } | ||
37 | #endif | ||
38 | cp = (char *) crypt(clear, salt); | ||
39 | /* if crypt (a nonstandard crypt) returns a string too large, | ||
40 | truncate it so we don't overrun buffers and hope there is | ||
41 | enough security in what's left */ | ||
42 | if (strlen(cp) > sizeof(cipher)-1) { | ||
43 | cp[sizeof(cipher)-1] = 0; | ||
44 | } | ||
45 | strcpy(cipher, cp); | ||
46 | return cipher; | ||
47 | } | ||
48 | |||
diff --git a/libbb/pwd2spwd.c b/libbb/pwd2spwd.c new file mode 100644 index 000000000..95a2e4684 --- /dev/null +++ b/libbb/pwd2spwd.c | |||
@@ -0,0 +1,73 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1994, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | #include <time.h> | ||
32 | #include <sys/types.h> | ||
33 | #include "libbb.h" | ||
34 | |||
35 | /* | ||
36 | * pwd_to_spwd - create entries for new spwd structure | ||
37 | * | ||
38 | * pwd_to_spwd() creates a new (struct spwd) containing the | ||
39 | * information in the pointed-to (struct passwd). | ||
40 | */ | ||
41 | #define DAY (24L*3600L) | ||
42 | #define WEEK (7*DAY) | ||
43 | #define SCALE DAY | ||
44 | struct spwd *pwd_to_spwd(const struct passwd *pw) | ||
45 | { | ||
46 | static struct spwd sp; | ||
47 | |||
48 | /* | ||
49 | * Nice, easy parts first. The name and passwd map directly | ||
50 | * from the old password structure to the new one. | ||
51 | */ | ||
52 | sp.sp_namp = pw->pw_name; | ||
53 | sp.sp_pwdp = pw->pw_passwd; | ||
54 | |||
55 | /* | ||
56 | * Defaults used if there is no pw_age information. | ||
57 | */ | ||
58 | sp.sp_min = 0; | ||
59 | sp.sp_max = (10000L * DAY) / SCALE; | ||
60 | sp.sp_lstchg = time((time_t *) 0) / SCALE; | ||
61 | |||
62 | /* | ||
63 | * These fields have no corresponding information in the password | ||
64 | * file. They are set to uninitialized values. | ||
65 | */ | ||
66 | sp.sp_warn = -1; | ||
67 | sp.sp_expire = -1; | ||
68 | sp.sp_inact = -1; | ||
69 | sp.sp_flag = -1; | ||
70 | |||
71 | return &sp; | ||
72 | } | ||
73 | |||
diff --git a/libbb/restricted_shell.c b/libbb/restricted_shell.c new file mode 100644 index 000000000..74a64140f --- /dev/null +++ b/libbb/restricted_shell.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <errno.h> | ||
33 | #include <unistd.h> | ||
34 | #include <string.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <syslog.h> | ||
37 | #include <ctype.h> | ||
38 | #include "libbb.h" | ||
39 | |||
40 | |||
41 | |||
42 | /* Return 1 if SHELL is a restricted shell (one not returned by | ||
43 | getusershell), else 0, meaning it is a standard shell. */ | ||
44 | |||
45 | int restricted_shell ( const char *shell ) | ||
46 | { | ||
47 | char *line; | ||
48 | |||
49 | setusershell ( ); | ||
50 | while (( line = getusershell ( ))) { | ||
51 | if (( *line != '#' ) && ( strcmp ( line, shell ) == 0 )) | ||
52 | break; | ||
53 | } | ||
54 | endusershell ( ); | ||
55 | return line ? 0 : 1; | ||
56 | } | ||
57 | |||
diff --git a/libbb/run_shell.c b/libbb/run_shell.c new file mode 100644 index 000000000..30050fecb --- /dev/null +++ b/libbb/run_shell.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright 1989 - 1991, Julianne Frances Haugh <jockgrrl@austin.rr.com> | ||
4 | * All rights reserved. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions | ||
8 | * are met: | ||
9 | * 1. Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * 2. Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * 3. Neither the name of Julianne F. Haugh nor the names of its contributors | ||
15 | * may be used to endorse or promote products derived from this software | ||
16 | * without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND | ||
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
21 | * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE | ||
22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
28 | * SUCH DAMAGE. | ||
29 | */ | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <errno.h> | ||
33 | #include <unistd.h> | ||
34 | #include <string.h> | ||
35 | #include <stdlib.h> | ||
36 | #include <syslog.h> | ||
37 | #include <ctype.h> | ||
38 | #include "libbb.h" | ||
39 | |||
40 | |||
41 | /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. | ||
42 | If COMMAND is nonzero, pass it to the shell with the -c option. | ||
43 | If ADDITIONAL_ARGS is nonzero, pass it to the shell as more | ||
44 | arguments. */ | ||
45 | |||
46 | void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args ) | ||
47 | { | ||
48 | const char **args; | ||
49 | int argno = 1; | ||
50 | int additional_args_cnt = 0; | ||
51 | |||
52 | for ( args = additional_args; args && *args; args++ ) | ||
53 | additional_args_cnt++; | ||
54 | |||
55 | if ( additional_args ) | ||
56 | args = (const char **) xmalloc (sizeof (char *) * ( 4 + additional_args_cnt )); | ||
57 | else | ||
58 | args = (const char **) xmalloc (sizeof (char *) * 4 ); | ||
59 | |||
60 | args [0] = get_last_path_component ( xstrdup ( shell )); | ||
61 | |||
62 | if ( loginshell ) { | ||
63 | char *args0 = xmalloc ( xstrlen ( args [0] ) + 2 ); | ||
64 | args0 [0] = '-'; | ||
65 | strcpy ( args0 + 1, args [0] ); | ||
66 | args [0] = args0; | ||
67 | } | ||
68 | |||
69 | if ( command ) { | ||
70 | args [argno++] = "-c"; | ||
71 | args [argno++] = command; | ||
72 | } | ||
73 | if ( additional_args ) { | ||
74 | for ( ; *additional_args; ++additional_args ) | ||
75 | args [argno++] = *additional_args; | ||
76 | } | ||
77 | args [argno] = 0; | ||
78 | execv ( shell, (char **) args ); | ||
79 | perror_msg_and_die ( "cannot run %s", shell ); | ||
80 | } | ||
81 | |||
diff --git a/loginutils/tinylogin.c b/libbb/setup_environment.c index bd611fd70..dc171fa1f 100644 --- a/loginutils/tinylogin.c +++ b/libbb/setup_environment.c | |||
@@ -28,8 +28,6 @@ | |||
28 | * SUCH DAMAGE. | 28 | * SUCH DAMAGE. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "busybox.h" | ||
32 | |||
33 | #include <stdio.h> | 31 | #include <stdio.h> |
34 | #include <errno.h> | 32 | #include <errno.h> |
35 | #include <unistd.h> | 33 | #include <unistd.h> |
@@ -37,98 +35,19 @@ | |||
37 | #include <stdlib.h> | 35 | #include <stdlib.h> |
38 | #include <syslog.h> | 36 | #include <syslog.h> |
39 | #include <ctype.h> | 37 | #include <ctype.h> |
38 | #include "libbb.h" | ||
40 | 39 | ||
41 | #include "pwd.h" | ||
42 | #include "grp.h" | ||
43 | 40 | ||
44 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
45 | #include "shadow.h" | ||
46 | #endif | ||
47 | 41 | ||
48 | #define DEFAULT_LOGIN_PATH "/bin:/usr/bin" | 42 | #define DEFAULT_LOGIN_PATH "/bin:/usr/bin" |
49 | #define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" | 43 | #define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" |
50 | 44 | ||
51 | |||
52 | static void xsetenv ( const char *key, const char *value ) | 45 | static void xsetenv ( const char *key, const char *value ) |
53 | { | 46 | { |
54 | if ( setenv ( key, value, 1 )) | 47 | if ( setenv ( key, value, 1 )) |
55 | error_msg_and_die ( "out of memory" ); | 48 | error_msg_and_die ( "out of memory" ); |
56 | } | 49 | } |
57 | 50 | ||
58 | /* Become the user and group(s) specified by PW. */ | ||
59 | |||
60 | void change_identity ( const struct passwd *pw ) | ||
61 | { | ||
62 | if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 ) | ||
63 | perror_msg_and_die ( "cannot set groups" ); | ||
64 | endgrent ( ); | ||
65 | |||
66 | if ( setgid ( pw-> pw_gid )) | ||
67 | perror_msg_and_die ( "cannot set group id" ); | ||
68 | if ( setuid ( pw->pw_uid )) | ||
69 | perror_msg_and_die ( "cannot set user id" ); | ||
70 | } | ||
71 | |||
72 | /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. | ||
73 | If COMMAND is nonzero, pass it to the shell with the -c option. | ||
74 | If ADDITIONAL_ARGS is nonzero, pass it to the shell as more | ||
75 | arguments. */ | ||
76 | |||
77 | void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args ) | ||
78 | { | ||
79 | const char **args; | ||
80 | int argno = 1; | ||
81 | int additional_args_cnt = 0; | ||
82 | |||
83 | for ( args = additional_args; args && *args; args++ ) | ||
84 | additional_args_cnt++; | ||
85 | |||
86 | if ( additional_args ) | ||
87 | args = (const char **) xmalloc (sizeof (char *) * ( 4 + additional_args_cnt )); | ||
88 | else | ||
89 | args = (const char **) xmalloc (sizeof (char *) * 4 ); | ||
90 | |||
91 | args [0] = get_last_path_component ( xstrdup ( shell )); | ||
92 | |||
93 | if ( loginshell ) { | ||
94 | char *args0 = xmalloc ( xstrlen ( args [0] ) + 2 ); | ||
95 | args0 [0] = '-'; | ||
96 | strcpy ( args0 + 1, args [0] ); | ||
97 | args [0] = args0; | ||
98 | } | ||
99 | |||
100 | if ( command ) { | ||
101 | args [argno++] = "-c"; | ||
102 | args [argno++] = command; | ||
103 | } | ||
104 | if ( additional_args ) { | ||
105 | for ( ; *additional_args; ++additional_args ) | ||
106 | args [argno++] = *additional_args; | ||
107 | } | ||
108 | args [argno] = 0; | ||
109 | execv ( shell, (char **) args ); | ||
110 | perror_msg_and_die ( "cannot run %s", shell ); | ||
111 | } | ||
112 | |||
113 | /* Return 1 if SHELL is a restricted shell (one not returned by | ||
114 | getusershell), else 0, meaning it is a standard shell. */ | ||
115 | |||
116 | int restricted_shell ( const char *shell ) | ||
117 | { | ||
118 | char *line; | ||
119 | |||
120 | setusershell ( ); | ||
121 | while (( line = getusershell ( ))) { | ||
122 | if (( *line != '#' ) && ( strcmp ( line, shell ) == 0 )) | ||
123 | break; | ||
124 | } | ||
125 | endusershell ( ); | ||
126 | return line ? 0 : 1; | ||
127 | } | ||
128 | |||
129 | /* Update `environ' for the new shell based on PW, with SHELL being | ||
130 | the value for the SHELL environment variable. */ | ||
131 | |||
132 | void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ) | 51 | void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ) |
133 | { | 52 | { |
134 | if ( loginshell ) { | 53 | if ( loginshell ) { |
@@ -172,38 +91,3 @@ void setup_environment ( const char *shell, int loginshell, int changeenv, const | |||
172 | } | 91 | } |
173 | } | 92 | } |
174 | 93 | ||
175 | /* Ask the user for a password. | ||
176 | Return 1 if the user gives the correct password for entry PW, | ||
177 | 0 if not. Return 1 without asking for a password if run by UID 0 | ||
178 | or if PW has an empty password. */ | ||
179 | |||
180 | int correct_password ( const struct passwd *pw ) | ||
181 | { | ||
182 | char *unencrypted, *encrypted, *correct; | ||
183 | |||
184 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
185 | if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) { | ||
186 | struct spwd *sp = getspnam ( pw-> pw_name ); | ||
187 | |||
188 | if ( !sp ) | ||
189 | error_msg_and_die ( "no valid shadow password" ); | ||
190 | |||
191 | correct = sp-> sp_pwdp; | ||
192 | } | ||
193 | else | ||
194 | #endif | ||
195 | correct = pw-> pw_passwd; | ||
196 | |||
197 | if ( correct == 0 || correct[0] == '\0' ) | ||
198 | return 1; | ||
199 | |||
200 | unencrypted = getpass ( "Password: " ); | ||
201 | if ( !unencrypted ) | ||
202 | { | ||
203 | fputs ( "getpass: cannot open /dev/tty\n", stderr ); | ||
204 | return 0; | ||
205 | } | ||
206 | encrypted = crypt ( unencrypted, correct ); | ||
207 | memset ( unencrypted, 0, xstrlen ( unencrypted )); | ||
208 | return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0; | ||
209 | } | ||
diff --git a/loginutils/Makefile.in b/loginutils/Makefile.in index adee35baa..cb6452c39 100644 --- a/loginutils/Makefile.in +++ b/loginutils/Makefile.in | |||
@@ -26,9 +26,12 @@ LOGINUTILS-y:= | |||
26 | LOGINUTILS-$(CONFIG_ADDGROUP) += addgroup.o | 26 | LOGINUTILS-$(CONFIG_ADDGROUP) += addgroup.o |
27 | LOGINUTILS-$(CONFIG_ADDUSER) += adduser.o | 27 | LOGINUTILS-$(CONFIG_ADDUSER) += adduser.o |
28 | LOGINUTILS-$(CONFIG_DELUSER) += deluser.o | 28 | LOGINUTILS-$(CONFIG_DELUSER) += deluser.o |
29 | LOGINUTILS-$(CONFIG_GETTY) += getty.o | 29 | LOGINUTILS-$(CONFIG_GETTY) += getty.o |
30 | LOGINUTILS-$(CONFIG_LOGIN) += login.o tinylogin.o | 30 | LOGINUTILS-$(CONFIG_LOGIN) += login.o |
31 | LOGINUTILS-$(CONFIG_SU) += su.o tinylogin.o | 31 | LOGINUTILS-$(CONFIG_PASSWD) += passwd.o |
32 | LOGINUTILS-$(CONFIG_SU) += su.o | ||
33 | LOGINUTILS-$(CONFIG_SULOGIN) += sulogin.o | ||
34 | LOGINUTILS-$(CONFIG_VLOCK) += vlock.o | ||
32 | 35 | ||
33 | libraries-y+=$(LOGINUTILS_DIR)$(LOGINUTILS_AR) | 36 | libraries-y+=$(LOGINUTILS_DIR)$(LOGINUTILS_AR) |
34 | 37 | ||
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c index e04a8d784..87e98fb18 100644 --- a/loginutils/addgroup.c +++ b/loginutils/addgroup.c | |||
@@ -35,9 +35,6 @@ | |||
35 | #include "pwd.h" | 35 | #include "pwd.h" |
36 | #include "grp.h" | 36 | #include "grp.h" |
37 | 37 | ||
38 | #define GROUP_FILE "/etc/group" | ||
39 | #define SHADOW_FILE "/etc/gshadow" | ||
40 | |||
41 | 38 | ||
42 | /* structs __________________________ */ | 39 | /* structs __________________________ */ |
43 | 40 | ||
@@ -92,7 +89,7 @@ static int addgroup(const char *filename, char *group, gid_t gid) | |||
92 | 89 | ||
93 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 90 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
94 | FILE *etc_gshadow; | 91 | FILE *etc_gshadow; |
95 | char *gshadow = SHADOW_FILE; | 92 | char *gshadow = shadow_file; |
96 | #endif | 93 | #endif |
97 | 94 | ||
98 | struct group gr; | 95 | struct group gr; |
@@ -162,7 +159,7 @@ int addgroup_main(int argc, char **argv) | |||
162 | } | 159 | } |
163 | 160 | ||
164 | /* werk */ | 161 | /* werk */ |
165 | return addgroup(GROUP_FILE, group, gid); | 162 | return addgroup(group_file, group, gid); |
166 | } | 163 | } |
167 | 164 | ||
168 | /* $Id: addgroup.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */ | 165 | /* $Id: addgroup.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */ |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 66fcaa23f..7aa7fcfd3 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -33,11 +33,7 @@ | |||
33 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
34 | #include <sys/types.h> | 34 | #include <sys/types.h> |
35 | #include "busybox.h" | 35 | #include "busybox.h" |
36 | #include "pwd.h" | ||
37 | #include "grp.h" | ||
38 | 36 | ||
39 | #define PASSWD_FILE "/etc/passwd" | ||
40 | #define SHADOW_FILE "/etc/shadow" | ||
41 | 37 | ||
42 | 38 | ||
43 | /* structs __________________________ */ | 39 | /* structs __________________________ */ |
@@ -56,9 +52,6 @@ static const char default_home_prefix[] = "/home"; | |||
56 | static const char default_shell[] = "/bin/sh"; | 52 | static const char default_shell[] = "/bin/sh"; |
57 | 53 | ||
58 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 54 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
59 | |||
60 | #include "shadow.h" | ||
61 | |||
62 | /* shadow in use? */ | 55 | /* shadow in use? */ |
63 | static int shadow_enabled = 0; | 56 | static int shadow_enabled = 0; |
64 | #endif | 57 | #endif |
@@ -138,47 +131,6 @@ static void passwd_wrapper(const char *login) | |||
138 | error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually", login); | 131 | error_msg_and_die("Failed to execute 'passwd', you must set the password for '%s' manually", login); |
139 | } | 132 | } |
140 | 133 | ||
141 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
142 | /* | ||
143 | * pwd_to_spwd - create entries for new spwd structure | ||
144 | * | ||
145 | * pwd_to_spwd() creates a new (struct spwd) containing the | ||
146 | * information in the pointed-to (struct passwd). | ||
147 | */ | ||
148 | #define DAY (24L*3600L) | ||
149 | #define WEEK (7*DAY) | ||
150 | #define SCALE DAY | ||
151 | static struct spwd *pwd_to_spwd(const struct passwd *pw) | ||
152 | { | ||
153 | static struct spwd sp; | ||
154 | |||
155 | /* | ||
156 | * Nice, easy parts first. The name and passwd map directly | ||
157 | * from the old password structure to the new one. | ||
158 | */ | ||
159 | sp.sp_namp = pw->pw_name; | ||
160 | sp.sp_pwdp = pw->pw_passwd; | ||
161 | |||
162 | /* | ||
163 | * Defaults used if there is no pw_age information. | ||
164 | */ | ||
165 | sp.sp_min = 0; | ||
166 | sp.sp_max = (10000L * DAY) / SCALE; | ||
167 | sp.sp_lstchg = time((time_t *) 0) / SCALE; | ||
168 | |||
169 | /* | ||
170 | * These fields have no corresponding information in the password | ||
171 | * file. They are set to uninitialized values. | ||
172 | */ | ||
173 | sp.sp_warn = -1; | ||
174 | sp.sp_expire = -1; | ||
175 | sp.sp_inact = -1; | ||
176 | sp.sp_flag = -1; | ||
177 | |||
178 | return &sp; | ||
179 | } | ||
180 | #endif | ||
181 | |||
182 | /* putpwent(3) remix */ | 134 | /* putpwent(3) remix */ |
183 | static int adduser(const char *filename, struct passwd *p) | 135 | static int adduser(const char *filename, struct passwd *p) |
184 | { | 136 | { |
@@ -222,7 +174,7 @@ static int adduser(const char *filename, struct passwd *p) | |||
222 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 174 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
223 | /* add to shadow if necessary */ | 175 | /* add to shadow if necessary */ |
224 | if (shadow_enabled) { | 176 | if (shadow_enabled) { |
225 | shadow = wfopen(SHADOW_FILE, "a"); | 177 | shadow = wfopen(shadow_file, "a"); |
226 | if (shadow == NULL) { | 178 | if (shadow == NULL) { |
227 | /* return -1; */ | 179 | /* return -1; */ |
228 | return 1; | 180 | return 1; |
@@ -333,7 +285,7 @@ int adduser_main(int argc, char **argv) | |||
333 | } | 285 | } |
334 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 286 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
335 | /* is /etc/shadow in use? */ | 287 | /* is /etc/shadow in use? */ |
336 | shadow_enabled = (0 == access(SHADOW_FILE, F_OK)); | 288 | shadow_enabled = (0 == access(shadow_file, F_OK)); |
337 | #endif | 289 | #endif |
338 | 290 | ||
339 | /* create a passwd struct */ | 291 | /* create a passwd struct */ |
@@ -346,7 +298,7 @@ int adduser_main(int argc, char **argv) | |||
346 | pw.pw_shell = (char *)shell; | 298 | pw.pw_shell = (char *)shell; |
347 | 299 | ||
348 | /* grand finale */ | 300 | /* grand finale */ |
349 | return adduser(PASSWD_FILE, &pw); | 301 | return adduser(passwd_file, &pw); |
350 | } | 302 | } |
351 | 303 | ||
352 | /* $Id: adduser.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */ | 304 | /* $Id: adduser.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */ |
diff --git a/loginutils/config.in b/loginutils/config.in index 265d45ab4..b3880aa3d 100644 --- a/loginutils/config.in +++ b/loginutils/config.in | |||
@@ -7,19 +7,22 @@ mainmenu_option next_comment | |||
7 | comment 'Login/Password Management Utilities' | 7 | comment 'Login/Password Management Utilities' |
8 | 8 | ||
9 | 9 | ||
10 | bool 'addgroup' CONFIG_ADDGROUP | 10 | bool 'addgroup' CONFIG_ADDGROUP |
11 | bool 'adduser' CONFIG_ADDUSER | 11 | bool 'adduser' CONFIG_ADDUSER |
12 | bool 'deluser' CONFIG_DELUSER | 12 | bool 'deluser' CONFIG_DELUSER |
13 | bool 'delgroup' CONFIG_DELUSER | 13 | bool 'delgroup' CONFIG_DELUSER |
14 | bool 'getty' CONFIG_GETTY | 14 | bool 'getty' CONFIG_GETTY |
15 | bool 'login' CONFIG_LOGIN | 15 | bool 'login' CONFIG_LOGIN |
16 | if [ "$CONFIG_LOGIN" = "y" ]; then | 16 | if [ "$CONFIG_LOGIN" = "y" ]; then |
17 | bool ' Support for /etc/securetty' CONFIG_FEATURE_SECURETTY | 17 | bool ' Support for /etc/securetty' CONFIG_FEATURE_SECURETTY |
18 | fi | 18 | fi |
19 | bool 'su' CONFIG_SU | 19 | bool 'passwd' CONFIG_PASSWD |
20 | bool 'su' CONFIG_SU | ||
20 | if [ "$CONFIG_ADDUSER" = "y" -o "$CONFIG_DELUSER" = "y" -o "$CONFIG_LOGIN" = "y" -o "$CONFIG_SU" = "y" ]; then | 21 | if [ "$CONFIG_ADDUSER" = "y" -o "$CONFIG_DELUSER" = "y" -o "$CONFIG_LOGIN" = "y" -o "$CONFIG_SU" = "y" ]; then |
21 | bool 'Support for shadow passwords' CONFIG_FEATURE_SHADOWPASSWDS | 22 | bool ' Support for shadow passwords' CONFIG_FEATURE_SHADOWPASSWDS |
22 | fi | 23 | fi |
24 | bool 'sulogin' CONFIG_SULOGIN | ||
25 | bool 'vlock' CONFIG_VLOCK | ||
23 | 26 | ||
24 | endmenu | 27 | endmenu |
25 | 28 | ||
diff --git a/loginutils/deluser.c b/loginutils/deluser.c index 481a716e7..c7d6ece64 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c | |||
@@ -28,10 +28,6 @@ | |||
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include "busybox.h" | 29 | #include "busybox.h" |
30 | 30 | ||
31 | #define PASSWD_FILE "/etc/passwd" | ||
32 | #define GROUP_FILE "/etc/group" | ||
33 | #define SHADOW_FILE "/etc/shadow" | ||
34 | #define GSHADOW_FILE "/etc/gshadow" | ||
35 | 31 | ||
36 | 32 | ||
37 | /* where to start and stop deletion */ | 33 | /* where to start and stop deletion */ |
@@ -123,11 +119,11 @@ int delgroup_main(int argc, char **argv) | |||
123 | show_usage(); | 119 | show_usage(); |
124 | } else { | 120 | } else { |
125 | 121 | ||
126 | failure = del_line_matching(argv[1], GROUP_FILE); | 122 | failure = del_line_matching(argv[1], group_file); |
127 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 123 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
128 | if (access(GSHADOW_FILE, W_OK) == 0) { | 124 | if (access(gshadow_file, W_OK) == 0) { |
129 | /* EDR the |= works if the error is not 0, so he had it wrong */ | 125 | /* EDR the |= works if the error is not 0, so he had it wrong */ |
130 | failure |= del_line_matching(argv[1], GSHADOW_FILE); | 126 | failure |= del_line_matching(argv[1], gshadow_file); |
131 | } | 127 | } |
132 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | 128 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ |
133 | /* if (!successful) { */ | 129 | /* if (!successful) { */ |
@@ -149,35 +145,35 @@ int deluser_main(int argc, char **argv) | |||
149 | show_usage(); | 145 | show_usage(); |
150 | } else { | 146 | } else { |
151 | 147 | ||
152 | failure = del_line_matching(argv[1], PASSWD_FILE); | 148 | failure = del_line_matching(argv[1], passwd_file); |
153 | /* if (!successful) { */ | 149 | /* if (!successful) { */ |
154 | if (failure) { | 150 | if (failure) { |
155 | error_msg_and_die("%s: User could not be removed from %s\n", | 151 | error_msg_and_die("%s: User could not be removed from %s\n", |
156 | argv[1], PASSWD_FILE); | 152 | argv[1], passwd_file); |
157 | } | 153 | } |
158 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 154 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS |
159 | failure = del_line_matching(argv[1], SHADOW_FILE); | 155 | failure = del_line_matching(argv[1], shadow_file); |
160 | /* if (!successful) { */ | 156 | /* if (!successful) { */ |
161 | if (failure) { | 157 | if (failure) { |
162 | error_msg_and_die("%s: User could not be removed from %s\n", | 158 | error_msg_and_die("%s: User could not be removed from %s\n", |
163 | argv[1], SHADOW_FILE); | 159 | argv[1], shadow_file); |
164 | } | 160 | } |
165 | failure = del_line_matching(argv[1], GSHADOW_FILE); | 161 | failure = del_line_matching(argv[1], gshadow_file); |
166 | /* if (!successful) { */ | 162 | /* if (!successful) { */ |
167 | if (failure) { | 163 | if (failure) { |
168 | error_msg_and_die("%s: User could not be removed from %s\n", | 164 | error_msg_and_die("%s: User could not be removed from %s\n", |
169 | argv[1], GSHADOW_FILE); | 165 | argv[1], gshadow_file); |
170 | } | 166 | } |
171 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | 167 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ |
172 | failure = del_line_matching(argv[1], GROUP_FILE); | 168 | failure = del_line_matching(argv[1], group_file); |
173 | /* if (!successful) { */ | 169 | /* if (!successful) { */ |
174 | if (failure) { | 170 | if (failure) { |
175 | error_msg_and_die("%s: User could not be removed from %s\n", | 171 | error_msg_and_die("%s: User could not be removed from %s\n", |
176 | argv[1], GROUP_FILE); | 172 | argv[1], group_file); |
177 | } | 173 | } |
178 | 174 | ||
179 | } | 175 | } |
180 | return (EXIT_SUCCESS); | 176 | return (EXIT_SUCCESS); |
181 | } | 177 | } |
182 | 178 | ||
183 | /* $Id: deluser.c,v 1.1 2002/06/04 20:45:05 sandman Exp $ */ | 179 | /* $Id: deluser.c,v 1.2 2002/06/23 04:24:24 andersen Exp $ */ |
diff --git a/loginutils/login.c b/loginutils/login.c index 8ccc5bc8a..7687556ba 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -14,16 +14,9 @@ | |||
14 | #include <sys/types.h> | 14 | #include <sys/types.h> |
15 | #include <ctype.h> | 15 | #include <ctype.h> |
16 | #include <time.h> | 16 | #include <time.h> |
17 | #include "busybox.h" | ||
18 | |||
19 | #include "pwd.h" | ||
20 | #include "grp.h" | ||
21 | 17 | ||
22 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | 18 | #include "busybox.h" |
23 | #include "shadow.h" | ||
24 | #endif | ||
25 | 19 | ||
26 | #include "tinylogin.h" | ||
27 | 20 | ||
28 | // import from utmp.c | 21 | // import from utmp.c |
29 | static void checkutmp(int picky); | 22 | static void checkutmp(int picky); |
@@ -35,12 +28,7 @@ extern char *pw_encrypt(const char *clear, const char *salt); | |||
35 | 28 | ||
36 | // login defines | 29 | // login defines |
37 | #define TIMEOUT 60 | 30 | #define TIMEOUT 60 |
38 | #define FAIL_DELAY 3 | ||
39 | #define EMPTY_USERNAME_COUNT 10 | 31 | #define EMPTY_USERNAME_COUNT 10 |
40 | #define MOTD_FILE "/etc/motd" | ||
41 | #define NOLOGIN_FILE "/etc/nologin" | ||
42 | #define SECURETTY_FILE "/etc/securetty" | ||
43 | |||
44 | #define USERNAME_SIZE 32 | 32 | #define USERNAME_SIZE 32 |
45 | 33 | ||
46 | /* Stuff global to this file */ | 34 | /* Stuff global to this file */ |
@@ -81,7 +69,9 @@ extern int login_main(int argc, char **argv) | |||
81 | int failed; | 69 | int failed; |
82 | int count=0; | 70 | int count=0; |
83 | struct passwd *pw, pw_copy; | 71 | struct passwd *pw, pw_copy; |
84 | 72 | #ifdef CONFIG_WHEEL_GROUP | |
73 | struct group *grp; | ||
74 | #endif | ||
85 | int opt_preserve = 0; | 75 | int opt_preserve = 0; |
86 | int opt_fflag = 0; | 76 | int opt_fflag = 0; |
87 | char *opt_host = 0; | 77 | char *opt_host = 0; |
@@ -283,11 +273,11 @@ static int login_prompt ( char *buf_name ) | |||
283 | 273 | ||
284 | static int check_nologin ( int amroot ) | 274 | static int check_nologin ( int amroot ) |
285 | { | 275 | { |
286 | if ( access ( NOLOGIN_FILE, F_OK ) == 0 ) { | 276 | if ( access ( nologin_file, F_OK ) == 0 ) { |
287 | FILE *fp; | 277 | FILE *fp; |
288 | int c; | 278 | int c; |
289 | 279 | ||
290 | if (( fp = fopen ( NOLOGIN_FILE, "r" ))) { | 280 | if (( fp = fopen ( nologin_file, "r" ))) { |
291 | while (( c = getc ( fp )) != EOF ) | 281 | while (( c = getc ( fp )) != EOF ) |
292 | putchar (( c == '\n' ) ? '\r' : c ); | 282 | putchar (( c == '\n' ) ? '\r' : c ); |
293 | 283 | ||
@@ -312,7 +302,7 @@ static int check_tty ( const char *tty ) | |||
312 | int i; | 302 | int i; |
313 | char buf[BUFSIZ]; | 303 | char buf[BUFSIZ]; |
314 | 304 | ||
315 | if (( fp = fopen ( SECURETTY_FILE, "r" ))) { | 305 | if (( fp = fopen ( securetty_file, "r" ))) { |
316 | while ( fgets ( buf, sizeof( buf ) - 1, fp )) { | 306 | while ( fgets ( buf, sizeof( buf ) - 1, fp )) { |
317 | for ( i = xstrlen( buf ) - 1; i >= 0; --i ) { | 307 | for ( i = xstrlen( buf ) - 1; i >= 0; --i ) { |
318 | if ( !isspace ( buf[i] )) | 308 | if ( !isspace ( buf[i] )) |
@@ -358,7 +348,7 @@ static void motd ( ) | |||
358 | FILE *fp; | 348 | FILE *fp; |
359 | register int c; | 349 | register int c; |
360 | 350 | ||
361 | if (( fp = fopen ( MOTD_FILE, "r" ))) { | 351 | if (( fp = fopen ( motd_file, "r" ))) { |
362 | while (( c = getc ( fp )) != EOF ) | 352 | while (( c = getc ( fp )) != EOF ) |
363 | putchar ( c ); | 353 | putchar ( c ); |
364 | fclose ( fp ); | 354 | fclose ( fp ); |
@@ -429,23 +419,6 @@ static void checkutmp(int picky) | |||
429 | } | 419 | } |
430 | } | 420 | } |
431 | 421 | ||
432 | #if __GNU_LIBRARY__ < 5 | ||
433 | /* | ||
434 | * Some systems already have updwtmp() and possibly updwtmpx(). Others | ||
435 | * don't, so we re-implement these functions if necessary. --marekm | ||
436 | */ | ||
437 | static void updwtmp(const char *filename, const struct utmp *ut) | ||
438 | { | ||
439 | int fd; | ||
440 | |||
441 | fd = open(filename, O_APPEND | O_WRONLY, 0); | ||
442 | if (fd >= 0) { | ||
443 | write(fd, (const char *) ut, sizeof(*ut)); | ||
444 | close(fd); | ||
445 | } | ||
446 | } | ||
447 | #endif | ||
448 | |||
449 | /* | 422 | /* |
450 | * setutmp - put a USER_PROCESS entry in the utmp file | 423 | * setutmp - put a USER_PROCESS entry in the utmp file |
451 | * | 424 | * |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c new file mode 100644 index 000000000..9c84c167c --- /dev/null +++ b/loginutils/passwd.c | |||
@@ -0,0 +1,408 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | #include <fcntl.h> | ||
3 | #include <stdio.h> | ||
4 | #include <string.h> | ||
5 | #include <signal.h> | ||
6 | #include <sys/stat.h> | ||
7 | #include <sys/types.h> | ||
8 | #include <unistd.h> | ||
9 | #include <utime.h> | ||
10 | #include <syslog.h> | ||
11 | #include <time.h> | ||
12 | #include <sys/resource.h> | ||
13 | #include <errno.h> | ||
14 | |||
15 | #include "busybox.h" | ||
16 | |||
17 | static char crypt_passwd[128]; | ||
18 | |||
19 | static int create_backup(const char *backup, FILE * fp); | ||
20 | static int new_password(const struct passwd *pw, int amroot, int algo); | ||
21 | static void set_filesize_limit(int blocks); | ||
22 | |||
23 | |||
24 | int get_algo(char *a) | ||
25 | { | ||
26 | int x = 0; /* standart: DES */ | ||
27 | |||
28 | if (strcasecmp(a, "md5") == 0) | ||
29 | x = 1; | ||
30 | return x; | ||
31 | } | ||
32 | |||
33 | |||
34 | extern int update_passwd(const struct passwd *pw, char *crypt_pw) | ||
35 | { | ||
36 | char filename[1024]; | ||
37 | char buf[1025]; | ||
38 | char buffer[80]; | ||
39 | char username[32]; | ||
40 | char *pw_rest; | ||
41 | int has_shadow = 0; | ||
42 | int mask; | ||
43 | int continued; | ||
44 | FILE *fp; | ||
45 | FILE *out_fp; | ||
46 | struct stat sb; | ||
47 | struct flock lock; | ||
48 | |||
49 | if (access(shadow_file, F_OK) == 0) { | ||
50 | has_shadow = 1; | ||
51 | } | ||
52 | if (has_shadow) { | ||
53 | snprintf(filename, sizeof filename, "%s", shadow_file); | ||
54 | } else { | ||
55 | snprintf(filename, sizeof filename, "%s", passwd_file); | ||
56 | } | ||
57 | |||
58 | if (((fp = fopen(filename, "r+")) == 0) || (fstat(fileno(fp), &sb))) { | ||
59 | /* return 0; */ | ||
60 | return 1; | ||
61 | } | ||
62 | |||
63 | /* Lock the password file before updating */ | ||
64 | lock.l_type = F_WRLCK; | ||
65 | lock.l_whence = SEEK_SET; | ||
66 | lock.l_start = 0; | ||
67 | lock.l_len = 0; | ||
68 | if (fcntl(fileno(fp), F_SETLK, &lock) < 0) { | ||
69 | fprintf(stderr, "%s: %s\n", filename, strerror(errno)); | ||
70 | return 1; | ||
71 | } | ||
72 | lock.l_type = F_UNLCK; | ||
73 | |||
74 | snprintf(buf, sizeof buf, "%s-", filename); | ||
75 | if (create_backup(buf, fp)) { | ||
76 | fcntl(fileno(fp), F_SETLK, &lock); | ||
77 | fclose(fp); | ||
78 | return 1; | ||
79 | } | ||
80 | snprintf(buf, sizeof buf, "%s+", filename); | ||
81 | mask = umask(0777); | ||
82 | out_fp = fopen(buf, "w"); | ||
83 | umask(mask); | ||
84 | if ((!out_fp) || (fchmod(fileno(out_fp), sb.st_mode & 0777)) | ||
85 | || (fchown(fileno(out_fp), sb.st_uid, sb.st_gid))) { | ||
86 | fcntl(fileno(fp), F_SETLK, &lock); | ||
87 | fclose(fp); | ||
88 | fclose(out_fp); | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | continued = 0; | ||
93 | snprintf(username, sizeof username, "%s:", pw->pw_name); | ||
94 | rewind(fp); | ||
95 | while (!feof(fp)) { | ||
96 | fgets(buffer, sizeof buffer, fp); | ||
97 | if (!continued) { // Check to see if we're updating this line. | ||
98 | if (strncmp(username, buffer, strlen(username)) == 0) { // we have a match. | ||
99 | pw_rest = strchr(buffer, ':'); | ||
100 | *pw_rest++ = '\0'; | ||
101 | pw_rest = strchr(pw_rest, ':'); | ||
102 | fprintf(out_fp, "%s:%s%s", buffer, crypt_pw, pw_rest); | ||
103 | } else { | ||
104 | fputs(buffer, out_fp); | ||
105 | } | ||
106 | } else { | ||
107 | fputs(buffer, out_fp); | ||
108 | } | ||
109 | if (buffer[strlen(buffer) - 1] == '\n') { | ||
110 | continued = 0; | ||
111 | } else { | ||
112 | continued = 1; | ||
113 | } | ||
114 | bzero(buffer, sizeof buffer); | ||
115 | } | ||
116 | |||
117 | if (fflush(out_fp) || fsync(fileno(out_fp)) || fclose(out_fp)) { | ||
118 | unlink(buf); | ||
119 | fcntl(fileno(fp), F_SETLK, &lock); | ||
120 | fclose(fp); | ||
121 | return 1; | ||
122 | } | ||
123 | if (rename(buf, filename) < 0) { | ||
124 | fcntl(fileno(fp), F_SETLK, &lock); | ||
125 | fclose(fp); | ||
126 | return 1; | ||
127 | } else { | ||
128 | fcntl(fileno(fp), F_SETLK, &lock); | ||
129 | fclose(fp); | ||
130 | return 0; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | |||
135 | extern int passwd_main(int argc, char **argv) | ||
136 | { | ||
137 | int amroot; | ||
138 | char *cp; | ||
139 | char *np; | ||
140 | char *name; | ||
141 | char *myname; | ||
142 | int flag; | ||
143 | int algo = 0; /* -a - password algorithm */ | ||
144 | int lflg = 0; /* -l - lock account */ | ||
145 | int uflg = 0; /* -u - unlock account */ | ||
146 | int dflg = 0; /* -d - delete password */ | ||
147 | const struct passwd *pw; | ||
148 | unsigned short ruid; | ||
149 | |||
150 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
151 | const struct spwd *sp; | ||
152 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | ||
153 | amroot = (getuid() == 0); | ||
154 | openlog("passwd", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); | ||
155 | while ((flag = getopt(argc, argv, "a:dlu")) != EOF) { | ||
156 | switch (flag) { | ||
157 | case 'a': | ||
158 | algo = get_algo(optarg); | ||
159 | break; | ||
160 | case 'd': | ||
161 | dflg++; | ||
162 | break; | ||
163 | case 'l': | ||
164 | lflg++; | ||
165 | break; | ||
166 | case 'u': | ||
167 | uflg++; | ||
168 | break; | ||
169 | default: | ||
170 | show_usage(); | ||
171 | } | ||
172 | } | ||
173 | ruid = getuid(); | ||
174 | pw = (struct passwd *) getpwuid(ruid); | ||
175 | if (!pw) { | ||
176 | error_msg_and_die("Cannot determine your user name.\n"); | ||
177 | } | ||
178 | myname = (char *) xstrdup(pw->pw_name); | ||
179 | if (optind < argc) { | ||
180 | name = argv[optind]; | ||
181 | } else { | ||
182 | name = myname; | ||
183 | } | ||
184 | if ((lflg || uflg || dflg) && (optind >= argc || !amroot)) { | ||
185 | show_usage(); | ||
186 | } | ||
187 | pw = getpwnam(name); | ||
188 | if (!pw) { | ||
189 | error_msg_and_die("Unknown user %s\n", name); | ||
190 | } | ||
191 | if (!amroot && pw->pw_uid != getuid()) { | ||
192 | syslog(LOG_WARNING, "can't change pwd for `%s'", name); | ||
193 | error_msg_and_die("Permission denied.\n"); | ||
194 | } | ||
195 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
196 | sp = getspnam(name); | ||
197 | if (!sp) { | ||
198 | sp = (struct spwd *) pwd_to_spwd(pw); | ||
199 | } | ||
200 | cp = sp->sp_pwdp; | ||
201 | np = sp->sp_namp; | ||
202 | #else | ||
203 | cp = pw->pw_passwd; | ||
204 | np = name; | ||
205 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | ||
206 | |||
207 | safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); | ||
208 | if (!(dflg || lflg || uflg)) { | ||
209 | if (!amroot) { | ||
210 | if (cp[0] == '!') { | ||
211 | syslog(LOG_WARNING, "password locked for `%s'", np); | ||
212 | error_msg_and_die( "The password for `%s' cannot be changed.\n", np); | ||
213 | } | ||
214 | } | ||
215 | printf("Changing password for %s\n", name); | ||
216 | if (new_password(pw, amroot, algo)) { | ||
217 | error_msg_and_die( "The password for %s is unchanged.\n", name); | ||
218 | } | ||
219 | } else if (lflg) { | ||
220 | if (crypt_passwd[0] != '!') { | ||
221 | memmove(&crypt_passwd[1], crypt_passwd, | ||
222 | sizeof crypt_passwd - 1); | ||
223 | crypt_passwd[sizeof crypt_passwd - 1] = '\0'; | ||
224 | crypt_passwd[0] = '!'; | ||
225 | } | ||
226 | } else if (uflg) { | ||
227 | if (crypt_passwd[0] == '!') { | ||
228 | memmove(crypt_passwd, &crypt_passwd[1], | ||
229 | sizeof crypt_passwd - 1); | ||
230 | } | ||
231 | } else if (dflg) { | ||
232 | crypt_passwd[0] = '\0'; | ||
233 | } | ||
234 | set_filesize_limit(30000); | ||
235 | signal(SIGHUP, SIG_IGN); | ||
236 | signal(SIGINT, SIG_IGN); | ||
237 | signal(SIGQUIT, SIG_IGN); | ||
238 | umask(077); | ||
239 | if (setuid(0)) { | ||
240 | syslog(LOG_ERR, "can't setuid(0)"); | ||
241 | error_msg_and_die( "Cannot change ID to root.\n"); | ||
242 | } | ||
243 | if (!update_passwd(pw, crypt_passwd)) { | ||
244 | syslog(LOG_INFO, "password for `%s' changed by user `%s'", name, | ||
245 | myname); | ||
246 | printf("Password changed.\n"); | ||
247 | } else { | ||
248 | syslog(LOG_WARNING, | ||
249 | "an error occurred updating the password file"); | ||
250 | error_msg_and_die("An error occurred updating the password file.\n"); | ||
251 | } | ||
252 | return (0); | ||
253 | } | ||
254 | |||
255 | |||
256 | |||
257 | static int create_backup(const char *backup, FILE * fp) | ||
258 | { | ||
259 | struct stat sb; | ||
260 | struct utimbuf ub; | ||
261 | FILE *bkfp; | ||
262 | int c, mask; | ||
263 | |||
264 | if (fstat(fileno(fp), &sb)) | ||
265 | /* return -1; */ | ||
266 | return 1; | ||
267 | |||
268 | mask = umask(077); | ||
269 | bkfp = fopen(backup, "w"); | ||
270 | umask(mask); | ||
271 | if (!bkfp) | ||
272 | /* return -1; */ | ||
273 | return 1; | ||
274 | |||
275 | /* TODO: faster copy, not one-char-at-a-time. --marekm */ | ||
276 | rewind(fp); | ||
277 | while ((c = getc(fp)) != EOF) { | ||
278 | if (putc(c, bkfp) == EOF) | ||
279 | break; | ||
280 | } | ||
281 | if (c != EOF || fflush(bkfp)) { | ||
282 | fclose(bkfp); | ||
283 | /* return -1; */ | ||
284 | return 1; | ||
285 | } | ||
286 | if (fclose(bkfp)) | ||
287 | /* return -1; */ | ||
288 | return 1; | ||
289 | |||
290 | ub.actime = sb.st_atime; | ||
291 | ub.modtime = sb.st_mtime; | ||
292 | utime(backup, &ub); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int i64c(int i) | ||
297 | { | ||
298 | if (i <= 0) | ||
299 | return ('.'); | ||
300 | if (i == 1) | ||
301 | return ('/'); | ||
302 | if (i >= 2 && i < 12) | ||
303 | return ('0' - 2 + i); | ||
304 | if (i >= 12 && i < 38) | ||
305 | return ('A' - 12 + i); | ||
306 | if (i >= 38 && i < 63) | ||
307 | return ('a' - 38 + i); | ||
308 | return ('z'); | ||
309 | } | ||
310 | |||
311 | static char *crypt_make_salt(void) | ||
312 | { | ||
313 | time_t now; | ||
314 | static unsigned long x; | ||
315 | static char result[3]; | ||
316 | |||
317 | time(&now); | ||
318 | x += now + getpid() + clock(); | ||
319 | result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077); | ||
320 | result[1] = i64c(((x >> 12) ^ x) & 077); | ||
321 | result[2] = '\0'; | ||
322 | return result; | ||
323 | } | ||
324 | |||
325 | |||
326 | static int new_password(const struct passwd *pw, int amroot, int algo) | ||
327 | { | ||
328 | char *clear; | ||
329 | char *cipher; | ||
330 | char *cp; | ||
331 | char orig[200]; | ||
332 | char pass[200]; | ||
333 | time_t start, now; | ||
334 | |||
335 | if (!amroot && crypt_passwd[0]) { | ||
336 | if (!(clear = getpass("Old password:"))) { | ||
337 | /* return -1; */ | ||
338 | return 1; | ||
339 | } | ||
340 | cipher = pw_encrypt(clear, crypt_passwd); | ||
341 | if (strcmp(cipher, crypt_passwd) != 0) { | ||
342 | syslog(LOG_WARNING, "incorrect password for `%s'", | ||
343 | pw->pw_name); | ||
344 | time(&start); | ||
345 | now = start; | ||
346 | while (difftime(now, start) < FAIL_DELAY) { | ||
347 | sleep(FAIL_DELAY); | ||
348 | time(&now); | ||
349 | } | ||
350 | fprintf(stderr, "Incorrect password.\n"); | ||
351 | /* return -1; */ | ||
352 | return 1; | ||
353 | } | ||
354 | safe_strncpy(orig, clear, sizeof(orig)); | ||
355 | bzero(clear, strlen(clear)); | ||
356 | bzero(cipher, strlen(cipher)); | ||
357 | } else { | ||
358 | orig[0] = '\0'; | ||
359 | } | ||
360 | if (! | ||
361 | (cp = | ||
362 | getpass ("Enter the new password (minimum of 5, maximum of 8 characters)\n"" | ||
363 | Please use a combination of upper and lower case letters and numbers.\nEnter new password: "))) | ||
364 | { | ||
365 | bzero(orig, sizeof orig); | ||
366 | /* return -1; */ | ||
367 | return 1; | ||
368 | } | ||
369 | safe_strncpy(pass, cp, sizeof(pass)); | ||
370 | bzero(cp, strlen(cp)); | ||
371 | /* if (!obscure(orig, pass, pw)) { */ | ||
372 | if (obscure(orig, pass, pw)) { | ||
373 | if (amroot) { | ||
374 | printf("\nWarning: weak password (continuing).\n"); | ||
375 | } else { | ||
376 | /* return -1; */ | ||
377 | return 1; | ||
378 | } | ||
379 | } | ||
380 | if (!(cp = getpass("Re-enter new password: "))) { | ||
381 | bzero(orig, sizeof orig); | ||
382 | /* return -1; */ | ||
383 | return 1; | ||
384 | } | ||
385 | if (strcmp(cp, pass)) { | ||
386 | fprintf(stderr, "Passwords do not match.\n"); | ||
387 | /* return -1; */ | ||
388 | return 1; | ||
389 | } | ||
390 | bzero(cp, strlen(cp)); | ||
391 | bzero(orig, sizeof(orig)); | ||
392 | |||
393 | if (algo == 1) { | ||
394 | cp = pw_encrypt(pass, "$1$"); | ||
395 | } else | ||
396 | cp = pw_encrypt(pass, crypt_make_salt()); | ||
397 | bzero(pass, sizeof pass); | ||
398 | safe_strncpy(crypt_passwd, cp, sizeof(crypt_passwd)); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static void set_filesize_limit(int blocks) | ||
403 | { | ||
404 | struct rlimit rlimit_fsize; | ||
405 | |||
406 | rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks; | ||
407 | setrlimit(RLIMIT_FSIZE, &rlimit_fsize); | ||
408 | } | ||
diff --git a/loginutils/su.c b/loginutils/su.c index 33e62e837..6d427262e 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -1,7 +1,5 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | 2 | ||
3 | #include "busybox.h" | ||
4 | |||
5 | #include <fcntl.h> | 3 | #include <fcntl.h> |
6 | #include <signal.h> | 4 | #include <signal.h> |
7 | #include <stdio.h> | 5 | #include <stdio.h> |
@@ -18,10 +16,7 @@ | |||
18 | #include <ctype.h> | 16 | #include <ctype.h> |
19 | #include <time.h> | 17 | #include <time.h> |
20 | 18 | ||
21 | #include "pwd.h" | 19 | #include "busybox.h" |
22 | #include "grp.h" | ||
23 | |||
24 | #include "tinylogin.h" | ||
25 | 20 | ||
26 | 21 | ||
27 | 22 | ||
@@ -161,7 +156,7 @@ int su_main ( int argc, char **argv ) | |||
161 | 156 | ||
162 | change_identity ( pw ); | 157 | change_identity ( pw ); |
163 | setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw ); | 158 | setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw ); |
164 | run_shell ( opt_shell, opt_loginshell, opt_command, opt_args ); | 159 | run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args ); |
165 | 160 | ||
166 | return EXIT_FAILURE; | 161 | return EXIT_FAILURE; |
167 | } | 162 | } |
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c new file mode 100644 index 000000000..a654ffb89 --- /dev/null +++ b/loginutils/sulogin.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | #include <fcntl.h> | ||
3 | #include <signal.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdlib.h> | ||
6 | #include <string.h> | ||
7 | #include <syslog.h> | ||
8 | #include <termios.h> | ||
9 | #include <unistd.h> | ||
10 | #include <utmp.h> | ||
11 | #include <sys/resource.h> | ||
12 | #include <sys/stat.h> | ||
13 | #include <sys/time.h> | ||
14 | #include <sys/types.h> | ||
15 | #include <ctype.h> | ||
16 | #include <time.h> | ||
17 | |||
18 | #include "busybox.h" | ||
19 | |||
20 | |||
21 | // sulogin defines | ||
22 | #define SULOGIN_PROMPT "\nGive root password for system maintenance\n" \ | ||
23 | "(or type Control-D for normal startup):" | ||
24 | |||
25 | static const char *forbid[] = { | ||
26 | "ENV", | ||
27 | "BASH_ENV", | ||
28 | "HOME", | ||
29 | "IFS", | ||
30 | "PATH", | ||
31 | "SHELL", | ||
32 | "LD_LIBRARY_PATH", | ||
33 | "LD_PRELOAD", | ||
34 | "LD_TRACE_LOADED_OBJECTS", | ||
35 | "LD_BIND_NOW", | ||
36 | "LD_AOUT_LIBRARY_PATH", | ||
37 | "LD_AOUT_PRELOAD", | ||
38 | "LD_NOWARN", | ||
39 | "LD_KEEPDIR", | ||
40 | (char *) 0 | ||
41 | }; | ||
42 | |||
43 | |||
44 | |||
45 | static void catchalarm(int junk) | ||
46 | { | ||
47 | exit(EXIT_FAILURE); | ||
48 | } | ||
49 | |||
50 | |||
51 | extern int sulogin_main(int argc, char **argv) | ||
52 | { | ||
53 | char *cp; | ||
54 | char *device = (char *) 0; | ||
55 | const char *name = "root"; | ||
56 | int timeout = 0; | ||
57 | static char pass[BUFSIZ]; | ||
58 | struct termios termio; | ||
59 | struct passwd pwent; | ||
60 | struct passwd *pwd; | ||
61 | time_t start, now; | ||
62 | const char **p; | ||
63 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
64 | struct spwd *spwd = NULL; | ||
65 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | ||
66 | |||
67 | tcgetattr(0, &termio); | ||
68 | /* set control chars */ | ||
69 | termio.c_cc[VINTR] = 3; /* C-c */ | ||
70 | termio.c_cc[VQUIT] = 28; /* C-\ */ | ||
71 | termio.c_cc[VERASE] = 127; /* C-? */ | ||
72 | termio.c_cc[VKILL] = 21; /* C-u */ | ||
73 | termio.c_cc[VEOF] = 4; /* C-d */ | ||
74 | termio.c_cc[VSTART] = 17; /* C-q */ | ||
75 | termio.c_cc[VSTOP] = 19; /* C-s */ | ||
76 | termio.c_cc[VSUSP] = 26; /* C-z */ | ||
77 | /* use line dicipline 0 */ | ||
78 | termio.c_line = 0; | ||
79 | /* Make it be sane */ | ||
80 | termio.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD; | ||
81 | termio.c_cflag |= CREAD|HUPCL|CLOCAL; | ||
82 | /* input modes */ | ||
83 | termio.c_iflag = ICRNL | IXON | IXOFF; | ||
84 | /* output modes */ | ||
85 | termio.c_oflag = OPOST | ONLCR; | ||
86 | /* local modes */ | ||
87 | termio.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN; | ||
88 | tcsetattr(0, TCSANOW, &termio); | ||
89 | openlog("sulogin", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH); | ||
90 | if (argc > 1) { | ||
91 | if (strncmp(argv[1], "-t", 2) == 0) { | ||
92 | if (strcmp(argv[1], "-t") == 0) { | ||
93 | if (argc > 2) { | ||
94 | timeout = atoi(argv[2]); | ||
95 | if (argc > 3) { | ||
96 | device = argv[3]; | ||
97 | } | ||
98 | } | ||
99 | } else { | ||
100 | if (argc > 2) { | ||
101 | device = argv[2]; | ||
102 | } | ||
103 | } | ||
104 | } else { | ||
105 | device = argv[1]; | ||
106 | } | ||
107 | if (device) { | ||
108 | close(0); | ||
109 | close(1); | ||
110 | close(2); | ||
111 | if (open(device, O_RDWR) >= 0) { | ||
112 | dup(0); | ||
113 | dup(0); | ||
114 | } else { | ||
115 | syslog(LOG_WARNING, "cannot open %s\n", device); | ||
116 | exit(EXIT_FAILURE); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | if (access(passwd_file, 0) == -1) { | ||
121 | syslog(LOG_WARNING, "No password file\n"); | ||
122 | error_msg_and_die("No password file\n"); | ||
123 | } | ||
124 | if (!isatty(0) || !isatty(1) || !isatty(2)) { | ||
125 | exit(EXIT_FAILURE); | ||
126 | } | ||
127 | |||
128 | |||
129 | /* Clear out anything dangerous from the environment */ | ||
130 | for (p = forbid; *p; p++) | ||
131 | unsetenv(*p); | ||
132 | |||
133 | |||
134 | signal(SIGALRM, catchalarm); | ||
135 | alarm(timeout); | ||
136 | if (!(pwd = getpwnam(name))) { | ||
137 | syslog(LOG_WARNING, "No password entry for `root'\n"); | ||
138 | error_msg_and_die("No password entry for `root'\n"); | ||
139 | } | ||
140 | pwent = *pwd; | ||
141 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
142 | spwd = NULL; | ||
143 | if (pwd && ((strcmp(pwd->pw_passwd, "x") == 0) | ||
144 | || (strcmp(pwd->pw_passwd, "*") == 0))) { | ||
145 | endspent(); | ||
146 | spwd = getspnam(name); | ||
147 | if (spwd) { | ||
148 | pwent.pw_passwd = spwd->sp_pwdp; | ||
149 | } | ||
150 | } | ||
151 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | ||
152 | while (1) { | ||
153 | cp = getpass(SULOGIN_PROMPT); | ||
154 | if (!cp || !*cp) { | ||
155 | puts("\n"); | ||
156 | fflush(stdout); | ||
157 | syslog(LOG_INFO, "Normal startup\n"); | ||
158 | exit(EXIT_SUCCESS); | ||
159 | } else { | ||
160 | safe_strncpy(pass, cp, sizeof(pass)); | ||
161 | bzero(cp, strlen(cp)); | ||
162 | } | ||
163 | if (strcmp(pw_encrypt(pass, pwent.pw_passwd), pwent.pw_passwd) == 0) { | ||
164 | break; | ||
165 | } | ||
166 | time(&start); | ||
167 | now = start; | ||
168 | while (difftime(now, start) < FAIL_DELAY) { | ||
169 | sleep(FAIL_DELAY); | ||
170 | time(&now); | ||
171 | } | ||
172 | puts("Login incorrect"); | ||
173 | fflush(stdout); | ||
174 | syslog(LOG_WARNING, "Incorrect root password\n"); | ||
175 | } | ||
176 | bzero(pass, strlen(pass)); | ||
177 | alarm(0); | ||
178 | signal(SIGALRM, SIG_DFL); | ||
179 | puts("Entering System Maintenance Mode\n"); | ||
180 | fflush(stdout); | ||
181 | syslog(LOG_INFO, "System Maintenance Mode\n"); | ||
182 | run_shell(pwent.pw_shell, 1, 0, 0); | ||
183 | return (0); | ||
184 | } | ||
diff --git a/loginutils/tinylogin.h b/loginutils/tinylogin.h deleted file mode 100644 index 5e56a2c7f..000000000 --- a/loginutils/tinylogin.h +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | #ifndef BB_LOGINUTILS_SHELL_H | ||
2 | #define BB_LOGINUTILS_SHELL_H | ||
3 | |||
4 | extern void change_identity ( const struct passwd *pw ); | ||
5 | extern void run_shell ( const char *shell, int loginshell, const char *command, char **additional_args ); | ||
6 | extern int restricted_shell ( const char *shell ); | ||
7 | extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ); | ||
8 | extern int correct_password ( const struct passwd *pw ); | ||
9 | |||
10 | #endif | ||
diff --git a/loginutils/vlock.c b/loginutils/vlock.c new file mode 100644 index 000000000..a26999f89 --- /dev/null +++ b/loginutils/vlock.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * vlock implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2000 by spoon <spoon@ix.netcom.com> | ||
6 | * Written by spoon <spon@ix.netcom.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | /* Shoutz to Michael K. Johnson <johnsonm@redhat.com>, author of the | ||
25 | * original vlock. I snagged a bunch of his code to write this | ||
26 | * minimalistic vlock. | ||
27 | */ | ||
28 | /* Fixed by Erik Andersen to do passwords the tinylogin way... | ||
29 | * It now works with md5, sha1, etc passwords. */ | ||
30 | |||
31 | #include <stdio.h> | ||
32 | #include <sys/vt.h> | ||
33 | #include <signal.h> | ||
34 | #include <string.h> | ||
35 | #include <unistd.h> | ||
36 | #include <fcntl.h> | ||
37 | #include <errno.h> | ||
38 | #include <sys/ioctl.h> | ||
39 | #include <termios.h> | ||
40 | |||
41 | #include "busybox.h" | ||
42 | |||
43 | static struct passwd *pw; | ||
44 | static struct spwd *spw; | ||
45 | static struct vt_mode ovtm; | ||
46 | static struct termios oterm; | ||
47 | static int vfd; | ||
48 | static int o_lock_all = 0; | ||
49 | |||
50 | /* getspuid - get a shadow entry by uid */ | ||
51 | struct spwd *getspuid(uid_t uid) | ||
52 | { | ||
53 | struct spwd *sp; | ||
54 | struct passwd *mypw; | ||
55 | |||
56 | if ((mypw = getpwuid(getuid())) == NULL) { | ||
57 | return (NULL); | ||
58 | } | ||
59 | setspent(); | ||
60 | while ((sp = getspent()) != NULL) { | ||
61 | if (strcmp(mypw->pw_name, sp->sp_namp) == 0) | ||
62 | break; | ||
63 | } | ||
64 | endspent(); | ||
65 | return (sp); | ||
66 | } | ||
67 | |||
68 | static void release_vt(int signo) | ||
69 | { | ||
70 | if (!o_lock_all) | ||
71 | ioctl(vfd, VT_RELDISP, 1); | ||
72 | else | ||
73 | ioctl(vfd, VT_RELDISP, 0); | ||
74 | } | ||
75 | |||
76 | static void acquire_vt(int signo) | ||
77 | { | ||
78 | ioctl(vfd, VT_RELDISP, VT_ACKACQ); | ||
79 | } | ||
80 | |||
81 | static void restore_terminal(void) | ||
82 | { | ||
83 | ioctl(vfd, VT_SETMODE, &ovtm); | ||
84 | tcsetattr(STDIN_FILENO, TCSANOW, &oterm); | ||
85 | } | ||
86 | |||
87 | extern int vlock_main(int argc, char **argv) | ||
88 | { | ||
89 | sigset_t sig; | ||
90 | struct sigaction sa; | ||
91 | struct vt_mode vtm; | ||
92 | int times = 0; | ||
93 | struct termios term; | ||
94 | |||
95 | if (argc > 2) { | ||
96 | show_usage(); | ||
97 | } | ||
98 | |||
99 | if (argc == 2) { | ||
100 | if (strncmp(argv[1], "-a", 2)) { | ||
101 | show_usage(); | ||
102 | } else { | ||
103 | o_lock_all = 1; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if ((pw = getpwuid(getuid())) == NULL) { | ||
108 | error_msg_and_die("no password for uid %d\n", getuid()); | ||
109 | } | ||
110 | #ifdef CONFIG_FEATURE_SHADOWPASSWDS | ||
111 | if ((strcmp(pw->pw_passwd, "x") == 0) | ||
112 | || (strcmp(pw->pw_passwd, "*") == 0)) { | ||
113 | |||
114 | if ((spw = getspuid(getuid())) == NULL) { | ||
115 | error_msg_and_die("could not read shadow password for uid %d: %s\n", | ||
116 | getuid(), strerror(errno)); | ||
117 | } | ||
118 | if (spw->sp_pwdp) { | ||
119 | pw->pw_passwd = spw->sp_pwdp; | ||
120 | } | ||
121 | } | ||
122 | #endif /* CONFIG_FEATURE_SHADOWPASSWDS */ | ||
123 | if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') { | ||
124 | error_msg_and_die("Account disabled for uid %d\n", getuid()); | ||
125 | } | ||
126 | |||
127 | /* we no longer need root privs */ | ||
128 | setuid(getuid()); | ||
129 | setgid(getgid()); | ||
130 | |||
131 | if ((vfd = open("/dev/tty", O_RDWR)) < 0) { | ||
132 | error_msg_and_die("/dev/tty"); | ||
133 | }; | ||
134 | |||
135 | if (ioctl(vfd, VT_GETMODE, &vtm) < 0) { | ||
136 | error_msg_and_die("/dev/tty"); | ||
137 | }; | ||
138 | |||
139 | /* mask a bunch of signals */ | ||
140 | sigprocmask(SIG_SETMASK, NULL, &sig); | ||
141 | sigdelset(&sig, SIGUSR1); | ||
142 | sigdelset(&sig, SIGUSR2); | ||
143 | sigaddset(&sig, SIGTSTP); | ||
144 | sigaddset(&sig, SIGTTIN); | ||
145 | sigaddset(&sig, SIGTTOU); | ||
146 | sigaddset(&sig, SIGHUP); | ||
147 | sigaddset(&sig, SIGCHLD); | ||
148 | sigaddset(&sig, SIGQUIT); | ||
149 | sigaddset(&sig, SIGINT); | ||
150 | |||
151 | sigemptyset(&(sa.sa_mask)); | ||
152 | sa.sa_flags = SA_RESTART; | ||
153 | sa.sa_handler = release_vt; | ||
154 | sigaction(SIGUSR1, &sa, NULL); | ||
155 | sa.sa_handler = acquire_vt; | ||
156 | sigaction(SIGUSR2, &sa, NULL); | ||
157 | |||
158 | /* need to handle some signals so that we don't get killed by them */ | ||
159 | sa.sa_handler = SIG_IGN; | ||
160 | sigaction(SIGHUP, &sa, NULL); | ||
161 | sigaction(SIGQUIT, &sa, NULL); | ||
162 | sigaction(SIGINT, &sa, NULL); | ||
163 | sigaction(SIGTSTP, &sa, NULL); | ||
164 | |||
165 | ovtm = vtm; | ||
166 | vtm.mode = VT_PROCESS; | ||
167 | vtm.relsig = SIGUSR1; | ||
168 | vtm.acqsig = SIGUSR2; | ||
169 | ioctl(vfd, VT_SETMODE, &vtm); | ||
170 | |||
171 | tcgetattr(STDIN_FILENO, &oterm); | ||
172 | term = oterm; | ||
173 | term.c_iflag &= ~BRKINT; | ||
174 | term.c_iflag |= IGNBRK; | ||
175 | term.c_lflag &= ~ISIG; | ||
176 | term.c_lflag &= ~(ECHO | ECHOCTL); | ||
177 | tcsetattr(STDIN_FILENO, TCSANOW, &term); | ||
178 | |||
179 | do { | ||
180 | char *pass, *crypt_pass; | ||
181 | char prompt[100]; | ||
182 | |||
183 | if (o_lock_all) { | ||
184 | printf("All Virtual Consoles locked.\n"); | ||
185 | } else { | ||
186 | printf("This Virtual Console locked.\n"); | ||
187 | } | ||
188 | fflush(stdout); | ||
189 | |||
190 | snprintf(prompt, 100, "%s's password: ", pw->pw_name); | ||
191 | |||
192 | if ((pass = getpass(prompt)) == NULL) { | ||
193 | perror("getpass"); | ||
194 | restore_terminal(); | ||
195 | exit(1); | ||
196 | } | ||
197 | |||
198 | crypt_pass = pw_encrypt(pass, pw->pw_passwd); | ||
199 | if (strncmp(crypt_pass, pw->pw_passwd, sizeof(crypt_pass)) == 0) { | ||
200 | memset(pass, 0, strlen(pass)); | ||
201 | memset(crypt_pass, 0, strlen(crypt_pass)); | ||
202 | restore_terminal(); | ||
203 | return 0; | ||
204 | } | ||
205 | memset(pass, 0, strlen(pass)); | ||
206 | memset(crypt_pass, 0, strlen(crypt_pass)); | ||
207 | |||
208 | if (isatty(STDIN_FILENO) == 0) { | ||
209 | perror("isatty"); | ||
210 | restore_terminal(); | ||
211 | exit(1); | ||
212 | } | ||
213 | |||
214 | sleep(++times); | ||
215 | printf("Password incorrect.\n"); | ||
216 | if (times >= 3) { | ||
217 | sleep(15); | ||
218 | times = 2; | ||
219 | } | ||
220 | } while (1); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | Local Variables: | ||
225 | c-file-style: "linux" | ||
226 | c-basic-offset: 4 | ||
227 | tab-width: 4 | ||
228 | End: | ||
229 | */ | ||