Compare commits

..

781 Commits

Author SHA1 Message Date
nekral-guest
499c6f7938 Tag release 4.1.4.2 2009-07-24 16:22:16 +00:00
nekral-guest
e568b9e435 * NEWS, configure.in: Prepare for the next release 4.1.4.2.
* po/shadow.pot, man/po/shadow-man-pages.pot: Regenerated.
	* po/*.po, man/po/*.po: Updated PO files.
2009-07-24 01:13:21 +00:00
nekral-guest
36ef489fe1 * configure.in: Fixed definition of the SHELL configuration. 2009-07-23 21:02:03 +00:00
nekral-guest
65741533ca * etc/login.defs: SYS_GID_MIN /SYS_UID_MIN changed from 100 to
101. GID 100 seems to be used statically.
2009-07-23 20:41:35 +00:00
nekral-guest
93ce5304fe Added a TODO item for /etc/defautl/useradd 2009-07-23 19:40:53 +00:00
nekral-guest
355e31d19d Added one todo item. 2009-07-23 19:40:00 +00:00
nekral-guest
24cfe44b07 * libmisc/shell.c, src/su.c: Execute the scripts with "sh -"
rather than "sh".
2009-07-22 13:35:57 +00:00
nekral-guest
db38a728d1 * configure.in, libmisc/shell.c, libmisc/setupenv.c, src/newgrp.c,
src/su.c: Let the system shell be configurable.
2009-07-22 13:30:06 +00:00
nekral-guest
4ad827768e * NEWS, src/su.c, libmisc/shell.c: Added support for shells being a
shell script without a shebang.
2009-07-20 14:00:50 +00:00
bubulle
b04c2d7e99 And fix a typo in French..:) 2009-07-19 11:54:44 +00:00
bubulle
cb550dae17 Fix obvious mistake in Dutch translation 2009-07-19 11:53:49 +00:00
nekral-guest
56c7096000 2009-07-18 Peter Vrabec <pvrabec@redhat.com>
* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Since
	system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
	reverse order, accounts are packed close to SYS_?ID_MAX if
	SYS_?ID_MIN is already used but there are still dome gaps.
2009-07-18 00:35:35 +00:00
nekral-guest
b0bcb01888 * NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Do not use
getpwent / getgrent for system accounts. Trying the low-IDs with
	getpwuid / getgrgid should be more efficient on LDAP configured
	systems with many accounts.
2009-07-17 22:54:23 +00:00
nekral-guest
f7257fafe1 * po/eu.po: Updated Basque translation. 2009-07-05 20:13:41 +00:00
nekral-guest
616ed68b48 * man/fi/Makefile.am: Stop distributing the Finnish translation of
passwd.1 (outdated).
2009-06-22 19:23:42 +00:00
nekral-guest
7e96d749e4 * man/pwck.8.xml: The shadow file is optional.
* man/pwck.8.xml: Updated description of the checks. Added
	description of the shadow checks.
	* man/pwck.8.xml: Updated description of the checks.
2009-06-20 13:02:33 +00:00
nekral-guest
885692e3c5 * man/po/fr.po: Fixed typo (forunis) 2009-06-14 12:47:41 +00:00
nekral-guest
bbb2a1522f * lib/fputsx.c: Compare the result of fgets() with the provided
buffer instead of NULL.
2009-06-12 20:20:45 +00:00
nekral-guest
ae00a3579c * lib/gshadow.c: Removed limitation on the length of the gshadow
lines.
	* lib/gshadow.c: Compare the result of fgetsx() with the provided
	buffer instead of NULL.
2009-06-12 17:50:24 +00:00
nekral-guest
fa69d08d13 * libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetgrnam.c,
libmisc/xgetpwuid.c, libmisc/xgetgrgid.c, libmisc/xgetspnam.c: Do
	not limit the size of the buffer to hold the group or user
	structure. It used to be limited to 16k, which caused issues with
	groups having many users.
2009-06-11 21:33:00 +00:00
nekral-guest
7d5d9c1841 * src/su.c, man/su.1.xml: The default behavior (without -p or
--login) is to copy most of the environment variables. Revert a
	previous change and update the documentation.
2009-06-11 20:01:21 +00:00
nekral-guest
80907f451b * man/passwd.5.xml, man/shadow.5.xml: Document the passwd- and
shadow- files.
2009-06-06 11:21:15 +00:00
nekral-guest
f4f6300499 * NEWS, src/su.c: Preserve the DISPLAY and XAUTHORITY environment
variables, even with --login. This was not the case before in the
	PAM version.
2009-06-05 22:19:38 +00:00
nekral-guest
d6f18c207e * src/useradd.c, src/groupmod.c, src/groupadd.c, src/faillog.c:
Fix typos. Take this opportunity to split the usage messages into
	smaller messages (one per option).
	* src/pwck.c: Fix typo.
2009-06-05 22:16:56 +00:00
nekral-guest
35c0b2cb47 * man/passwd.1.xml: The short option for --mindays is -n, not -m. 2009-06-05 21:14:12 +00:00
nekral-guest
d07e4b8e32 Updated previous documentation of the environment variables handling. 2009-06-04 20:47:50 +00:00
nekral-guest
0762426c4d * .gitignore, man/.gitignore, src/.gitignore: Added .gitignore
files.
2009-06-04 20:08:11 +00:00
nekral-guest
5cd975acbf * man/su.1.xml: Use <option> for the login.defs options.
* man/su.1.xml: Improve the documentation of the su behavior
	regarding environment variables.
	* man/su.1.xml: Document that the login.defs file is used.
2009-06-04 17:28:09 +00:00
nekral-guest
ae69e6da5a * man/login.1.xml: Document that the login.defs file is used. 2009-06-04 17:25:18 +00:00
nekral-guest
647c22c85a * man/login.defs.d/ENVIRON_FILE.xml: Document the format for
comments.
2009-06-04 17:23:08 +00:00
nekral-guest
1edc2153bb * man/gpasswd.1.xml: Ease the translation of the refpurpose.
* man/gpasswd.1.xml: Fix typo, shorten sentences.
2009-05-26 19:23:40 +00:00
nekral-guest
bf56a7097e * man/pwck.8.xml, man/grpck.8.xml: Move the SEE ALSO section at
the end.
2009-05-26 17:00:58 +00:00
nekral-guest
a6418fb0df * src/vipw.c: Make sure opened files are closed. 2009-05-25 19:51:23 +00:00
nekral-guest
401d72d609 * man/chpasswd.8.xml, man/grpck.8.xml, man/newgrp.1.xml,
man/passwd.1.xml, man/sg.1.xml: Avoid a spurious comma.
2009-05-25 19:41:43 +00:00
nekral-guest
a1352582df * man/passwd.1.xml: Avoid a spurious comma. 2009-05-25 19:29:19 +00:00
nekral-guest
2e239f44cf * NEWS: New placeholder for the next release. 2009-05-25 19:26:31 +00:00
nekral-guest
5b22b11454 * po/fr.po: Updated French translation. 2009-05-22 13:53:18 +00:00
nekral-guest
91d5c24f58 * NEWS: Prepare the next release.
* po/shadow.pot, man/po/shadow-man-pages.pot: Regenerated.
	* po/*.po, man/po/*.po: Updated PO files.
	* man/passwd.1.xml: passwd -u does not reset the expiry field.
2009-05-22 13:50:45 +00:00
nekral-guest
e9a8ffbb51 re-indent. 2009-05-22 13:32:26 +00:00
nekral-guest
1b9b5ec306 * man/po/fr.po: Updated some strings. 2009-05-22 13:31:18 +00:00
nekral-guest
f596cd113c * NEWS, src/newgrp.c: Return the exit status of the child. Thanks
to Lionel Elie Mamane.
2009-05-22 11:10:02 +00:00
nekral-guest
2e075ad91b * NEWS, src/newgrp.c: Return the exit status of the child. Thanks
to Lionel Elie Mamane.
2009-05-22 11:08:46 +00:00
nekral-guest
fd55bd5d4a * src/usermod.c: Added warnings for absolute symlinks which could
be broken by rename().
2009-05-22 10:42:51 +00:00
nekral-guest
604c7d72d9 * NEWS, src/userdel.c: Report errors to remove the user's mailbox.
* NEWS, src/userdel.c: When USERGROUPS_ENAB is enabled, remove the
	user's group when the user was the only member. This is still not
	complete, as the user could have been specified twice in the
	members.
	* NEWS, src/userdel.c: Do not fail when -r is used and the home
	directory does not exist.
2009-05-22 10:41:10 +00:00
nekral-guest
738ebc04b9 * libmisc/copydir.c: Added warning for relative symlinks.
* libmisc/copydir.c (remove_tree): There is no need to check if
	the root argument exist. opendir() will report this.
2009-05-22 10:16:12 +00:00
nekral-guest
8dfd253b9c * man/faillog.8.xml: Minor updates. 2009-05-21 14:04:53 +00:00
nekral-guest
2a08642cdc * man/faillog.5.xml: Split a long paragraph. Typo fixes. 2009-05-21 14:01:16 +00:00
nekral-guest
3aa2765d59 * man/gpasswd.1.xml: Minor updates. 2009-05-21 13:54:45 +00:00
nekral-guest
12235612b5 * man/gshadow.5.xml: Updated documentation. 2009-05-21 13:53:56 +00:00
nekral-guest
39b17ee5d5 * man/usermod.8.xml, man/userdel.8.xml, man/useradd.8.xml:
Harmonize formatting of login.defs and default/useradd variables.
	Use an <option> tag.
	* man/usermod.8.xml: Added reference to gshadow(5).
	* man/login.defs.d/USERDEL_CMD.xml: Shorten the lines of the
	USERDEL_CMD example.
2009-05-21 12:02:12 +00:00
nekral-guest
37bda83dfc * src/su.c: Use a boolean instead of 0. 2009-05-21 11:58:59 +00:00
bubulle
16ea6678ef msgcat + leave Jean-Luc as translator 2009-05-20 05:40:31 +00:00
bubulle
a7118480af French translation update 2009-05-20 05:39:40 +00:00
nekral-guest
41705d4532 * man/usermod.8.xml: Fixed typos. 2009-05-19 22:28:34 +00:00
nekral-guest
b98658bd11 * configure.in: Next version will be 4.1.4.1. 2009-05-19 22:19:41 +00:00
nekral-guest
50916c195b * man/newusers.8.xml: Added notes regarding the ownership of
files.
2009-05-19 22:17:55 +00:00
nekral-guest
a61ecc3177 Added FIXMEs. 2009-05-19 22:12:27 +00:00
nekral-guest
627ebe09ed * man/groupmod.8.xml: Split the -g option description into smaller
paragraphs.
2009-05-19 22:00:14 +00:00
nekral-guest
2adab29e61 * man/usermod.8.xml: Ownership of the mailbox is also changed with
the -u option.
2009-05-19 21:57:04 +00:00
nekral-guest
fb41fb8c46 * man/useradd.8.xml: When no passwords are provided, the password
is disabled, not the account.
2009-05-19 21:37:53 +00:00
nekral-guest
738eac8669 * man/newusers.8.xml, man/chpasswd.8.xml, man/useradd.8.xml,
man/groupadd.8.xml, man/usermod.8.xml, man/chgpasswd.8.xml,
	man/groupmod.8.xml: Added warning: passwords set with these tools
	may not respect the password policy.
2009-05-19 21:29:26 +00:00
nekral-guest
82afbc40ce * man/groupadd.8.xml: Fixed formatting issue. 2009-05-19 20:32:48 +00:00
nekral-guest
00694672cd * man/groupdel.8.xml: Move the warning on filesystems checks to
the CAVEAT section.
2009-05-19 20:31:45 +00:00
nekral-guest
fa2afc96ac This was meant for the previous man/userdel.8.xml commit:
* man/userdel.8.xml: Added warning for files that could remain
	owner by the removed user.
2009-05-19 20:31:02 +00:00
nekral-guest
42cb56a3a0 * man/useradd.8.xml: Fix formatting typo. 2009-05-19 20:26:56 +00:00
nekral-guest
b5e7ede8b7 * man/groupdel.8.xml: Move the warning on filesystems checks to
the CAVEAT section.
2009-05-19 20:26:28 +00:00
nekral-guest
c859ad91c4 Added missing return value. 2009-05-18 22:46:13 +00:00
nekral-guest
5dead2b296 * man/login.defs.d/GID_MAX.xml: Fixed typo. useradd was specified
twice.
2009-05-18 22:45:39 +00:00
nekral-guest
6573e0175f * man/groupadd.8.xml, man/useradd.8.xml: names may also contain
digits.
2009-05-18 22:43:59 +00:00
nekral-guest
96816f495e * man/shadow.5.xml: What is important in shadow is not the
encryption, but that the file is not world readable.
2009-05-18 22:40:57 +00:00
nekral-guest
9f13b4fdaa * man/po/fr.po: Updated French translation. Thanks to ABBAS
Belkacem for the login.defs update.
2009-05-18 22:39:48 +00:00
nekral-guest
5f143879df * man/usermod.8.xml: Split the CAVEAT section in paragraphs.
Updated information on the user_busy check.
2009-05-18 19:18:29 +00:00
nekral-guest
785231657c * man/userdel.8.xml: Document that -f forces the deletion of a
busy user.
2009-05-18 18:53:23 +00:00
nekral-guest
b9ecd1cf42 * NEWS, src/usermod.c: Check if the user is busy when the user's
UID, name or home directory is changed.
2009-05-18 18:37:16 +00:00
nekral-guest
4a4549c49b * src/userdel.c, libmisc/user_busy.c, libmisc/Makefile.am,
lib/prototypes.h: Move user_busy() to libmisc/user_busy.c.
	* NEWS, libmisc/user_busy.c: On Linux, do not check if an user is
	logged in with utmp, but check if the user is running some
	processes. If not on Linux, continue to search for an utmp record,
	but make sure the process recorded in the utmp entry is still
	running.
2009-05-18 18:32:17 +00:00
nekral-guest
3e85eafb4c * man/usermod.8.xml: Document the -m/--move-home option. 2009-05-18 18:28:06 +00:00
nekral-guest
e3343c1d9b * src/userdel.c (user_busy): Check if the process registered in
utmp is still running. This avoids rejecting the removal of an
	user when UTMP was not updated and indicate that the user is still
	logged in.
2009-05-17 16:27:29 +00:00
nekral-guest
297141c6c4 re-indent. 2009-05-17 16:02:35 +00:00
nekral-guest
589a773f7e Document the changes in 4.1.4.1:
- login
  * Fix failures with empty usernames on non PAM versions.
  * Fix CONSOLE (securetty) support on non PAM versions.
2009-05-16 18:27:13 +00:00
nekral-guest
f634cd3e2c * libmisc/console.c (console): Remove the leading /dev/ from the
tty before comparing with the lines specified by CONSOLE.
	* src/su.c: Do not remove the /dev/ prefix since it is done by
	console().
2009-05-16 18:19:24 +00:00
nekral-guest
8eaa6f8b4c * man/login.defs.d/CONSOLE.xml: Document the format of the CONSOLE
file.
2009-05-16 17:08:44 +00:00
nekral-guest
9ee294ba70 * src/login.c: Fix failure of non PAM enabled versions when an
empty username is entered after a first prompt.
2009-05-16 15:43:13 +00:00
nekral-guest
d945d61e42 * src/passwd.c: Added missing end of line at the end of success
messages.
2009-05-16 15:39:01 +00:00
nekral-guest
f8f0886248 * po/fr.po: Fixed typo in the vipw usage string. 2009-05-16 15:38:00 +00:00
nekral-guest
87bb724151 * libmisc/shell.c: Removed invalid code that executed the user's
shell as a shell script when the direct execution of the user's
	shell failed with ENOEXEC and the user's shell has a shebang. The
	interpreter might not be the right one.  Executing the user's
	shell with sh -c might be better, but I'm not sure we should try
	harder when there is a failure. Note: The removed code was only
	included #ifndef __linux__.
2009-05-12 20:01:41 +00:00
nekral-guest
205e8b5137 * man/userdel.8.xml: The USERGROUPS_ENAB group may not be removed
when the group is used by other users, not the user.
2009-05-12 19:25:26 +00:00
nekral-guest
a9b8fdc3c9 * src/userdel.c, man/login.defs.d/USERDEL_CMD.xml: Move the
USERDEL_CMD script example from the source code to the
	documentation.
2009-05-12 19:23:46 +00:00
nekral-guest
321e3ed02c * man/newusers.8.xml: PAM enabled version: describe how passwords
are updated and how newusers behave in case of error.
2009-05-11 19:29:38 +00:00
nekral-guest
63e6dc6b11 * NEWS, configure.in: New release will be 4.1.4.
* po/shadow.pot, man/po/shadow-man-pages.pot: Regenerated.
	* po/*.po, man/po/*.po: Updated PO files.
2009-05-10 20:02:21 +00:00
nekral-guest
a96a8861dd Fix compilation warnings. 2009-05-10 18:26:33 +00:00
nekral-guest
24875bb422 * libmisc/copydir.c: Added prototype of readlink_malloc(), and
readlink_malloc() changed to static.
2009-05-10 18:21:58 +00:00
nekral-guest
74073db5db * src/su.c: Avoid redeclaration of root_pw. 2009-05-10 18:20:41 +00:00
nekral-guest
fe0a5b6ee3 Added Changelog and NEWS entry for the French and Japanese translations. 2009-05-10 17:10:44 +00:00
bubulle
12875d2687 French translation update 2009-05-10 16:42:43 +00:00
bubulle
489432d742 Japanese translation received directly from NAKANO Takeo 2009-05-10 16:42:17 +00:00
nekral-guest
750093a3ed * lib/commonio.c: Avoid PATH_MAX. On glibc, we can use realpath
with a NULL argument.
	* src/useradd.c: Replace PATH_MAX by a fixed constant. The buffer
	was not meant as a storage for a path.
	* src/useradd.c, src/newusers.c, src/chpasswd.c: Better detection
	of fgets errors. Lines shall end with a \n, unless we reached the
	end of file.
	* libmisc/copydir.c: Avoid PATH_MAX. Support file paths with any
	length. Added readlink_malloc().
2009-05-10 13:49:03 +00:00
nekral-guest
a01499179f * src/pwck.c: Warn if an user has an entry in passwd and shadow,
and the password field in passwd is not 'x'.
	* src/grpck.c: Warn if a group has an entry in group and gshadow,
	and the password field in group is not 'x'.
2009-05-09 21:20:54 +00:00
nekral-guest
6ba7fd7d13 Fix typo. 2009-05-09 13:38:51 +00:00
nekral-guest
1737e6e0ec Added notes about updated translations. 2009-05-09 13:16:17 +00:00
nekral-guest
3f649c5504 * man/login.defs.d/ENCRYPT_METHOD.xml,
man/login.defs.d/MD5_CRYPT_ENAB.xml,
	man/login.defs.d/SHA_CRYPT_MIN_ROUNDS.xml: Updated note for PAM
	enabled versions. These variables are only used for group
	passwords in this case.
2009-05-09 13:16:10 +00:00
nekral-guest
9bdcf8fa15 * man/chpasswd.8.xml: Sorted options alphabetically. 2009-05-09 13:16:03 +00:00
nekral-guest
7f9e196903 * NEWS, src/newusers.c, src/Makefile.am: Added support for
changing the passwords with PAM.
	* src/newusers.c: Split the usage string in smaller parts to
	allow enabling single parts.
	* man/newusers.8.xml: Indicate the options and configuration
	variables valid for PAM and non-PAM versions.
	* man/newusers.8.xml: Added pointer to /etc/pam.d/chpasswd.
2009-05-09 13:15:57 +00:00
nekral-guest
8bcb2c1e71 Sort entries alphabetically. 2009-05-09 13:15:51 +00:00
nekral-guest
79db09da98 * src/userdel.c: Remove duplicate definitions of exit codes. 2009-05-09 13:15:44 +00:00
nekral-guest
8f64190223 Fix typos. 2009-05-09 13:15:38 +00:00
nekral-guest
ce684e236c Fix typo. 2009-05-09 13:15:32 +00:00
nekral-guest
d1534c53f7 * libmisc/non_interactive_pam_conv.c,
libmisc/pam_pass_non_interractive.c, libmisc/Makefile.am: Renamed.
	* libmisc/pam_pass_non_interractive.c, lib/prototypes.h:
	non_interactive_password and non_interactive_pam_conv do not need
	to be externally visible.
	* libmisc/pam_pass_non_interractive.c: Added declaration of
	ni_conv.
	* libmisc/pam_pass_non_interractive.c: Only compile ifdef USE_PAM.
	* libmisc/pam_pass_non_interractive.c, lib/prototypes.h:
	Added do_pam_passwd_non_interractive().
	* src/chpasswd.c: Use do_pam_passwd_non_interractive().
2009-05-09 13:15:25 +00:00
nekral-guest
19b672c3a4 * libmisc/pam_pass.c: Removed comment regarding pam_misc. This is
checked by configure.in.
2009-05-09 13:15:17 +00:00
nekral-guest
a979e7d14d * man/login.defs.5.xml: PAM enabled chpasswd do not use any
configuration variable from login.defs.
2009-05-09 13:15:10 +00:00
nekral-guest
4654150518 * man/passwd.1.xml: Differentiate the files used for PAM and
non-PAM versions.
2009-05-09 13:15:03 +00:00
nekral-guest
0921785ca2 * man/chpasswd.8.xml: Describe how chpasswd in case of error.
* man/chpasswd.8.xml: Describe the PAM enabled chpasswd behavior.
	* man/chpasswd.8.xml: Differentiate the files and configurations
	needed for PAM and non PAM versions.
2009-05-09 13:14:56 +00:00
nekral-guest
b60e8b6b45 * src/login.c: failcount does not need to be signed. 2009-05-09 13:14:50 +00:00
nekral-guest
538336a332 * src/Makefile.am: PAM enabled chpasswd now needs to be linked to
the PAM library, even if --enable-account-tools-setuid is not
	used.
2009-05-09 13:14:44 +00:00
nekral-guest
5c1279d803 * src/chpasswd.c: Added the line number when an error is reported
instead of only the username.
	* src/chpasswd.c: PAM enabled chpasswd do may change the password
	database (for the user where the password update succeeded) even
	if there were a failure for one user. Do not indicate that changes
	were ignored.
2009-05-09 13:14:37 +00:00
nekral-guest
61939960cc * src/passwd.c: Exit immediately when unlocking a password would
result in a passwordless account. This avoid printing a success
	message after the warning.
2009-05-09 13:14:31 +00:00
nekral-guest
ee7af4d7e2 * src/nologin.c: Include <stdlib.h> to get EXIT_FAILURE. 2009-05-09 13:14:23 +00:00
bubulle
b8355dba15 Russian completed 2009-05-09 05:57:18 +00:00
bubulle
5d661e366b Russian translation update 2009-05-08 17:22:15 +00:00
bubulle
787fbd3fab Completed German translation 2009-05-08 17:19:15 +00:00
bubulle
c671c3a738 German translation update 2009-05-07 17:48:51 +00:00
nekral-guest
69fe59a632 * NEWS, configure.in: Fix build failure on non-PAM enabled system
when --without-pam is not specified.
2009-05-03 22:46:26 +00:00
nekral-guest
ba65b06b4a * lib/commonio.c: Ignore teh return values of fclose() and
unlink() in case of failure of fopen_set_perms() or
	create_backup().
	* lib/commonio.c: Should the backup file be unlink'ed in case of
	failure of create_backup()?
2009-04-30 21:53:54 +00:00
nekral-guest
4da0573bf7 * lib/getulong.c: Added splint annotations. 2009-04-30 21:44:35 +00:00
nekral-guest
4e75bb57bb * src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
src/userdel.c, src/chpasswd.c, src/grpck.c, src/gpasswd.c,
	src/groupdel.c, src/chgpasswd.c, src/vipw.c, src/useradd.c,
	src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
	src/groupadd.c, src/chage.c, src/login.c, src/faillog.c,
	src/sulogin.c, src/chsh.c, src/pwconv.c: Added splint annotations.
	* src/userdel.c, src/pwconv.c, src/lastlog.c, src/grpck.c,
	src/vipw.c, src/groupmod.c, src/passwd.c, src/pwck.c, src/login.c,
	src/sulogin.c, src/usermod.c: Use return instead of exit at the
	end of main().
	* src/gpasswd.c, src/passwd.c, src/faillog.c: Use the exitcodes.h
	exit codes.
	* src/chpasswd.c: Added missing ||.
	* src/nologin.c: Do not include exitcodes.h.
	* src/nologin.c: Added brackets.
	* src/nologin.c: Avoid assignments in comparisons.
2009-04-30 21:39:38 +00:00
nekral-guest
c527c0196b * libmisc/getgr_nam_gid.c, lib/get_gid.c, lib/get_pid.c,
lib/get_uid.c: Added splint annotations.
2009-04-30 21:12:33 +00:00
nekral-guest
a326ffa435 * lib/exitcodes.h: Define E_SUCCESS as EXIT_SUCCESS. Added FIXMEs.
* libmisc/chowntty.c, libmisc/rlogin.c, libmisc/sub.c,
	src/newusers.c, libmisc/sulog.c, libmisc/system.c, src/logoutd.c,
	src/groups.c, src/id.c, lib/encrypt.c, libmisc/audit_help.c,
	libmisc/limits.c: Return EXIT_FAILURE instead of 1, and
	EXIT_SUCCESS instead of 0.
	* libmisc/audit_help.c: Replace an fprintf() by fputs().
	* libmisc/audit_help.c: Remove documentation of the audit_logger
	returned values. The function returns void.
	* libmisc/system.c: Only return status if waitpid succeeded.
	Return -1 otherwise.
2009-04-30 21:08:49 +00:00
nekral-guest
0f448edf19 Fix some splint warnings.
Rmove debug code.
2009-04-28 22:01:20 +00:00
nekral-guest
9b6b06cd03 Restore string. 2009-04-28 21:46:06 +00:00
nekral-guest
d7d0b06a41 * NEWS, src/chpasswd.c: Added support for changing the passwords
with PAM.
	* src/chpasswd.c: Split the usage string in smaller parts to
	allows enabling single parts.
	* src/chpasswd.c: Do not set a global lock on the password files.
	This is done by PAM each time a password is updated.
2009-04-28 21:45:38 +00:00
nekral-guest
72fa8afa07 * lib/defines.h: Include <utmpx.h> and <utmp.h> to define
USER_NAME_MAX_LENGTH.
2009-04-28 21:01:20 +00:00
nekral-guest
1e75786616 * src/login.c: Change a snprintf() to strncpy(). There are no
format.
2009-04-28 20:59:31 +00:00
nekral-guest
1db4402dbb Re-indent, reformat #ifndef blocks. 2009-04-28 20:55:10 +00:00
nekral-guest
59e1947950 * src/passwd.c: Harmonize status report at the end of passwd.
Prefix the messages with "passwd: ", only indicate a password
	change if the password was actually changed, and password
	properties changed otherwise.
2009-04-28 20:46:35 +00:00
nekral-guest
f8b8aaf5e4 * src/chgpasswd.c, src/newusers.c: There is no need to test for 0
after getopt_long. No options have flag != NULL.
2009-04-28 20:10:18 +00:00
nekral-guest
613dc54ac5 * src/newusers.c: There is no need to test for 0 after
getopt_long. No options have flag != NULL.
2009-04-28 20:08:30 +00:00
nekral-guest
a1591f77e8 * libmisc/Makefile.am, lib/prototypes.h,
libmisc/non_interactive_pam_conv.c: Added
	non_interactive_pam_conv() and non_interactive_password.
2009-04-28 20:07:24 +00:00
nekral-guest
102253834a * lib/prototypes.h: Replace #if by #ifdef
* lib/prototypes.h, libmisc/non_interactive_pam_conv.c: Added
	non_interactive_pam_conv() and non_interactive_password.
2009-04-28 20:06:46 +00:00
nekral-guest
dd85562fac * libmisc/utmp.c, src/userdel.c, src/logoutd.c: Replace #if by #ifdef 2009-04-28 20:03:23 +00:00
nekral-guest
90cc7f0f1d * src/vipw.c: Harmonize messages. 2009-04-28 19:26:27 +00:00
nekral-guest
bb00d1630a * src/lastlog.c: Replace atoi() by getulong(). 2009-04-28 19:25:15 +00:00
nekral-guest
a5188d2f05 * libmisc/failure.h: Replace HAVE_UTMPX_H by USE_UTMPX. 2009-04-28 19:19:33 +00:00
nekral-guest
6547cbda6f * libmisc/rlogin.c: Replace atoi() by getulong(). 2009-04-28 19:17:21 +00:00
nekral-guest
79919f184c * libmisc/failure.c: Replace HAVE_UTMPX_H by USE_UTMPX. 2009-04-28 19:14:50 +00:00
nekral-guest
e6b23e1431 * libmisc/chkname.c: Do not include <utmp.h> and <utmpx.h>. There
are no more needed.
2009-04-28 19:14:05 +00:00
nekral-guest
b0c0a94c66 * libmisc/limits.c: Replace strtol() by getlong().
* libmisc/limits.c: Replace HAVE_UTMPX_H by USE_UTMPX.
2009-04-28 19:12:48 +00:00
nekral-guest
76b51939aa * man/groupmod.8.xml, man/usermod.8.xml, man/groupadd.8.xml,
man/useradd.8.xml: Added note to warn about insecurity in using
	--password.
	* man/groupmod.8.xml: Removed not regarding default if --password
	is not used. This was a cut&paste from groupadd.8.xml.
	* man/passwd.1.xml: Split some paragraphs.
	* man/passwd.1.xml: Recommend other encryption methods than DES.
2009-04-27 20:29:43 +00:00
nekral-guest
91fc51387c * src/login.c: Move update_utmp() after the PID or session ID
changed in order to get more accurate data in UTMP. This also
	fixes "exec login" when login in installed setuid.
2009-04-27 20:25:23 +00:00
nekral-guest
009125484e * src/login.c: Reuse a string and avoid an untranslated message
"Login incorrect".
2009-04-27 20:21:48 +00:00
nekral-guest
8112a12521 * src/login.c: Replace HAVE_UTMPX_H by USE_UTMPX.
* src/login.c: Avoid name clash between global variables and the
	update_utmp() arguments.
2009-04-27 20:20:37 +00:00
nekral-guest
69307a1f2b * src/groupadd.c, lib/commonio.c, lib/groupio.c: Added missing
include of <assert.h>
2009-04-27 20:18:00 +00:00
nekral-guest
e68e07d095 * src/groupadd.c: Added missing include of <assert.h> 2009-04-27 20:16:04 +00:00
nekral-guest
851245107d * lib/prototypes.h: Replace HAVE_UTMPX_H by USE_UTMPX.
* lib/prototypes.h, libmisc/log.c: Added splint annotations.
	* libmisc/log.c: Added SYSLOG warning when lseek fails (should not
	happen).
2009-04-27 20:15:09 +00:00
nekral-guest
e88d1f5803 * libmisc/mail.c, libmisc/copydir.c: Added missing include of
<assert.h>
2009-04-27 20:09:18 +00:00
nekral-guest
988f7334ad * libmisc/env.c: Added assertions on the snprintf results. 2009-04-27 20:07:59 +00:00
nekral-guest
80fd2969c9 * libmisc/utmp.c: Replace HAVE_UTMPX_H by USE_UTMPX.
* libmisc/utmp.c: Removed old comment on HAVE_STRUCT_UTMP_UT_ID
	and UTMPX support.
2009-04-27 20:06:25 +00:00
nekral-guest
13b74243a6 * NEWS, configure.in: Added configure option --enable-utmpx,
disabled by default. This defines USE_UTMPX, which should be used
	instead of HAVE_UTMPX_H.
2009-04-27 20:03:48 +00:00
nekral-guest
c7035dbe9c * man/po/fr.po: Fix typo. 2009-04-27 19:56:34 +00:00
nekral-guest
8f78169a52 * src/newgrp.c: Close the databases before changing the UDI and
GID.
2009-04-26 17:11:38 +00:00
nekral-guest
5766499b85 * libmisc/myname.c: Updated splint annotations. 2009-04-26 17:10:49 +00:00
nekral-guest
4fd672c5b9 * lib/commonio.c: Added splint annotations.
* lib/commonio.c: old_context should be local to commonio_close(),
	not global.
2009-04-26 16:48:51 +00:00
nekral-guest
fca3b5cdc9 * src/passwd.c: Do not freecon strings duplicated with strdup.
Also avoid allocation of memory.
	* src/passwd.c: Use SYSLOG instead of syslog.
2009-04-26 16:44:54 +00:00
bubulle
8fa9bedcf7 Updated Czech translation 2009-04-26 12:26:10 +00:00
nekral-guest
44869516d3 Updated splint annotations. 2009-04-25 15:18:49 +00:00
nekral-guest
06d5369fdb Updated splint annotations. 2009-04-25 14:16:22 +00:00
nekral-guest
71f7f777ec * lib/commonio.c: Do not assumes eptr is always notnull.
Updated splint annotations.
2009-04-25 13:41:52 +00:00
nekral-guest
3a37388d43 Updated splint annotations. 2009-04-25 13:13:50 +00:00
nekral-guest
4c1d96e8e0 * lib/commonio.h, lib/commonio.c: Added splint annotations. 2009-04-25 12:43:27 +00:00
nekral-guest
f9bd143012 * NEWS, po/pt.po: Updated Portuguese translation. 2009-04-25 11:06:35 +00:00
nekral-guest
98e42fa944 * libmisc/copydir.c: Added splint annotations.
* libmisc/copydir.c: Added assert to help splint.
	* libmisc/copydir.c: Free allocated structures in cas of failure.
	* libmisc/copydir.c: Avoid implicit conversion of pointers to
	booleans.
	* libmisc/copydir.c: Use buffers of size PATH_MAX instead of 1024
	for filenames.
	* libmisc/copydir.c: Use fchmod and fchown to change the mode of
	the opened file.
	* libmisc/copydir.c: Indicate the mode to open(), even if we chmod
	later.
2009-04-24 23:41:28 +00:00
nekral-guest
ab6c366668 * lib/prototypes.h: Added prototypes of getulong() and get_pid().
* lib/prototypes.h: Added splint annotations.
2009-04-24 23:35:57 +00:00
nekral-guest
fc656ad7bd * lib/commonio.c: Use get_pid() instead of strtol.
* lib/commonio.c: Replace an int by a size_t.
2009-04-24 23:35:01 +00:00
nekral-guest
1353c71054 * lib/commonio.h: Added splint annotations. 2009-04-24 23:33:47 +00:00
nekral-guest
566fbac1ef * lib/sgroupio.c: Free allocated structures on failure.
* lib/sgroupio.c: Added splint annotations.
2009-04-24 23:32:52 +00:00
nekral-guest
496002abc9 * lib/Makefile.am, lib/get_pid.c, lib/getulong.c: Added get_pid()
and getulong().
2009-04-24 23:28:15 +00:00
nekral-guest
e8dd48ac09 * lib/getlong.c: Do not check for NULL string but empty string. 2009-04-24 23:27:12 +00:00
nekral-guest
08b4253001 * lib/groupio.c: Updated splint annotations.
* lib/groupio.c: Added assert to help splint.
2009-04-24 23:26:31 +00:00
nekral-guest
1a87c69854 * src/useradd.c: Check assumptions on snprintf().
* src/useradd.c: Replace peror by an strerror and avoid an
	intermediate buffer.
	* src/useradd.c: Save errno between the failure and the report by
	perror/strerror.
	* src/useradd.c: Prefer xmalloc to malloc.
2009-04-24 23:23:51 +00:00
nekral-guest
861773bf77 * src/lastlog.c: Remove function calls from within assert(). 2009-04-24 23:05:29 +00:00
nekral-guest
01e88bda16 * libmisc/obscure.c: Change some int to size_t. 2009-04-24 23:04:27 +00:00
nekral-guest
5e45ac1688 * libmisc/console.c: Use a less disturbing construct for splint. 2009-04-24 23:03:14 +00:00
nekral-guest
10396f9536 * libmisc/limits.c: Parse the limits, umask, nice, maxlogin, file
limit with getlog() / getulong(). This also means, in case of
	non-PAM enabled systems, that the umask specified on the GECOS
	fields should start with a 0 if specified in octal. (it used to be
	force to octal). Do the appropriate cast and range checking.
2009-04-24 22:56:42 +00:00
nekral-guest
0c571784a3 * libmisc/salt.c: In case gettimeofday() fails, get some entropy
from the PID.
2009-04-24 22:49:20 +00:00
nekral-guest
7646230de2 * libmisc/setupenv.c: Prefer snprintf to sprintf, even if a small
context indicates no issues.
	* libmisc/setupenv.c: Avoid implicit conversion of pointers to
	booleans.
2009-04-24 22:46:06 +00:00
nekral-guest
42e72c418d * libmisc/loginprompt.c: Prefer snprintf to sprintf, even if a
small context indicates no issues.
2009-04-24 22:27:58 +00:00
nekral-guest
37eec13774 * src/faillog.c: Remove function calls from within assert(). 2009-04-24 22:27:09 +00:00
nekral-guest
f28f5f3af4 * libmisc/mail.c: Ignore the return value of puts().
* libmisc/mail.c: Prefer snprintf to sprintf, even if a small
	context indicates no issues.
2009-04-24 22:22:57 +00:00
nekral-guest
6e357e14fc * lib/commonio.c, lib/commonio.h, lib/groupio.c, lib/groupio.h,
lib/pwio.c, lib/pwio.h, lib/shadowio.c, lib/shadowio.h: Added
	splint annotations. The *_locate() and *_next() functions
	currently return an observer. As the structure are often modified
	by the caller, it could maybe be changed to exposed later. (and
	non-const).
2009-04-23 21:19:02 +00:00
nekral-guest
d0d01ffb00 * lib/pwauth.c: Use a boolean for wipe_clear_pass and use_skey.
* lib/pwauth.c: Added splint annotations.
	* lib/pwauth.c: Added brackets and parenthesis.
	* lib/pwauth.c: Avoid assignments in comparisons.
	* lib/pwauth.c: Avoid implicit conversion of pointers or
	characters to booleans.
2009-04-23 20:46:01 +00:00
nekral-guest
916977c5bb * src/groupmod.c: Cast ID to ulongs and use ulong formats for IDs. 2009-04-23 20:39:29 +00:00
nekral-guest
af8ff8c1ca * src/newgrp.c: Added splint annotations.
* src/newgrp.c: audit_buf is only used in newgrp. Make it static.
	* src/newgrp.c: Ignore the return value of fputs().
	* src/newgrp.c: Use exit(EXIT_FAILURE) instead of exit(1).
2009-04-23 20:37:00 +00:00
nekral-guest
3d2f164dca * libmisc/pwdcheck.c (passwd_check): The progname is not used.
* libmisc/pwdcheck.c: Ignore the return value of sleep().
	* libmisc/pwdcheck.c: Use exit(EXIT_FAILURE) instead of exit(1).
2009-04-23 20:17:02 +00:00
nekral-guest
c357e94283 * libmisc/setupenv.c: Avoid assignments in comparisons.
* libmisc/setupenv.c: Added brackets and parenthesis.
	* libmisc/setupenv.c: Ignore the return value of fclose (file
	opened read-only)
	* libmisc/setupenv.c: Ignore the return value of puts().
	* libmisc/setupenv.c:Avoid implicit conversion of pointers to
	booleans.
2009-04-23 17:45:42 +00:00
nekral-guest
7f165aab7f * libmisc/find_new_gid.c, libmisc/find_new_uid.c,
libmisc/isexpired.c, src/groupadd.c, lib/pwauth.h, lib/groupmem.c,
	lib/shadowmem.c, lib/pwmem.c, lib/prototypes.h: Added splint
	annotations.
2009-04-23 17:43:27 +00:00
nekral-guest
956d68c870 * libmisc/loginprompt.c: Use exit(EXIT_FAILURE) instead of
exit(1).
	* libmisc/loginprompt.c: Avoid implicit conversion of pointers to
	booleans.
	* libmisc/loginprompt.c: Ignore return value of putc().
2009-04-23 17:34:46 +00:00
nekral-guest
61ebff6d97 * libmisc/env.c, libmisc/age.c: Added splint annotations.
* libmisc/age.c: Added brackets and parenthesis.
	* libmisc/age.c: Ignore the return value of fclose (file opened
	read-only)
	* libmisc/age.c: Ignore puts() return value.
	* libmisc/age.c: Use exit(EXIT_FAILURE) instead of exit(1).
	* libmisc/age.c: Avoid assignments in comparisons.
2009-04-23 17:33:21 +00:00
nekral-guest
0b1397b33b * lib/fputsx.c, lib/gshadow.c, lib/commonio.h: Added splint
annotations.
2009-04-23 11:54:30 +00:00
nekral-guest
a121b9b659 * lib/gshadow.c, lib/commonio.h: Added splint annotations. 2009-04-23 11:53:55 +00:00
nekral-guest
43033b65ad * lib/getdef.c: Added splint annotations.
* lib/getdef.c: Ignore fputs() return value.
	* lib/getdef.c: Use EXIT_FAILURE / EXIT_SUCCESS for exit()
2009-04-23 11:46:46 +00:00
nekral-guest
0c6159650d * lib/get_gid.c: gidstr should not be NULL, but the check was
meant to make sure it is not empty.
	* lib/get_uid.c: Likewise.
2009-04-23 11:46:06 +00:00
nekral-guest
7b562d96b3 * src/faillog.c: Added splint annotations.
* src/faillog.c: Cast ID to ulongs and use ulong formats for IDs.
	* src/faillog.c: Ignore fflush() return value.
	* src/faillog.c: Added parenthesis.
2009-04-23 11:23:53 +00:00
nekral-guest
988ec76cf8 * src/grpck.c: Ignore puts return value.
* src/grpck.c: Avoid variable format string.
2009-04-23 11:21:57 +00:00
nekral-guest
87e15d7b82 * src/lastlog.c: Use EXIT_FAILURE / EXIT_SUCCESS for exit()
* src/lastlog.c: Added splint annotations.
	* src/lastlog.c: Avoid global pwent.
	* src/lastlog.c: Cast ID to ulongs and use ulong formats for IDs.
	* src/lastlog.c: Avoid assignment in comparisons.
	* src/lastlog.c: Ignore fclose() return value since the file is
	only opened for reading.
2009-04-23 11:21:01 +00:00
nekral-guest
77c1b2a369 * src/newgrp.c: Added assertion to guide splint (and me). 2009-04-23 11:17:22 +00:00
nekral-guest
b0db85bc04 * libmisc/find_new_gid.c: Use booleans instead of char fo
used_gids.
	* libmisc/find_new_gid.c: Use getdef_ulong and cast to git_t to
	get GID values.
	* libmisc/find_new_gid.c: Use UL as a prefix for ulong values.
	* libmisc/find_new_uid.c: Likewise.
2009-04-23 11:16:38 +00:00
nekral-guest
cbd90eed74 * libmisc/yesno.c: Ignore the return value of puts. 2009-04-23 11:14:56 +00:00
nekral-guest
35f0a2e951 * libmisc/age.c: Use exit(EXIT_FAILURE) instead of exit(1).
* libmisc/age.c: The return value of execl() is not used.
2009-04-23 11:14:18 +00:00
nekral-guest
614c79defc * libmisc/xgetXXbyYY.c, libmisc/myname.c, libmisc/getgr_nam_gid.c,
libmisc/salt.c, libmisc/list.c, libmisc/cleanup.c, src/login.c,
	lib/getdef.h, lib/groupio.c, lib/getlong.c, lib/gshadow_.h,
	lib/sgroupio.c, lib/shadowio.c, lib/pwio.c, lib/commonio.h,
	lib/fputsx.c, lib/prototypes.h: Added splint annotations.
	* lib/groupio.c: Avoid implicit conversion of pointers to
	booleans.
	* lib/groupio.c: Free allocated buffers in case of failure.
2009-04-23 09:57:03 +00:00
nekral-guest
fef6f9379a Fix typo. 2009-04-22 21:33:09 +00:00
nekral-guest
fe29344b33 * lib/defines.h: Added splint definitions to replace <locale.h> 2009-04-22 21:22:32 +00:00
nekral-guest
2c0f3ef707 * libmisc/utmp.c, libmisc/age.c, libmisc/shell.c, lib/groupio.c,
lib/groupio.h, lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c,
	lib/pwio.c, lib/commonio.c, lib/shadowio.h, lib/pwio.h,
	lib/commonio.h, lib/prototypes.h: Added splint annotations.
2009-04-22 21:21:14 +00:00
nekral-guest
aebddca35d * libmisc/utmp.c: Added splint annotations. 2009-04-22 21:07:33 +00:00
nekral-guest
620ee81b7e * libmisc/utmp.c: Only set ut_time and ut_tv if gettimeofday()
succeeds.
2009-04-22 21:06:13 +00:00
nekral-guest
e76a5df932 * libmisc/utmp.c: Fix the check for empty host in prepare_utmp()
and prepare_utmpx().
2009-04-22 21:04:16 +00:00
nekral-guest
7fb1063ccd * libmisc/utmp.c: The ut argument of prepare_utmp() might be NULL.
ut_id needs to be forged in that case.
2009-04-22 21:02:46 +00:00
nekral-guest
811288df64 * libmisc/utmp.c: Removed old documentation of setutmp(). 2009-04-22 21:00:18 +00:00
nekral-guest
31906409c8 * libmisc/utmp.c: Use xmalloc() rather than malloc(). 2009-04-22 20:59:23 +00:00
nekral-guest
b05783da32 * libmisc/utmp.c: The name returned by ttyame() needs to be copied
locally.
2009-04-22 20:57:29 +00:00
nekral-guest
54302f6006 * src/login.c: Added splint annotations. 2009-04-22 20:53:15 +00:00
nekral-guest
2a32262725 * src/login.c: Added assert()s for NULL (or ! NULL) username, and
pwd. This helps splint.
2009-04-22 20:51:13 +00:00
nekral-guest
e35a7fbd89 Re-indent. 2009-04-22 20:48:42 +00:00
nekral-guest
c55311aa6d * src/login.c: After login_prompt(), do not check for unset
username, but for empty username.
2009-04-22 20:46:49 +00:00
nekral-guest
3704745289 * lib/defines.h: Define USER_NAME_MAX_LENGTH, based on utmp and
default to 32.
	* libmisc/chkname.c: Use USER_NAME_MAX_LENGTH.
	* src/login.c: Use USER_NAME_MAX_LENGTH instead of the default 32.
	username also needs to be bigger than USER_NAME_MAX_LENGTH because
	it has to be nul-terminated.
2009-04-22 20:42:48 +00:00
nekral-guest
eae8b63d4f * src/login.c: Use xmalloc() instead of malloc(). 2009-04-22 20:21:17 +00:00
nekral-guest
349efcb0a6 * src/login.c: Ignore the return value of puts(), fputs(),
strftime().
2009-04-22 20:17:11 +00:00
nekral-guest
46d697cded * src/login.c: timeout, delay, and retries should be unsigned.
* src/login.c: Ignore the return value of alarm() and sleep().
2009-04-22 20:15:21 +00:00
nekral-guest
53e0ff91d3 * src/login.c: If we cannot get the terminal configuration, do not
change the terminal configuration. setup_tty() is just a best
	effort configuration of the terminal.
	* src/login.c: Ignore failures when setting the terminal
	configuration.
	* src/login.c: Fail if the ERASECHAR or KILLCHAR configurations
	are not compatible with a cc_t type.
2009-04-22 20:12:06 +00:00
nekral-guest
a362a68f53 * src/login.c: utent might be NULL after get_current_utmp(). 2009-04-22 20:07:34 +00:00
nekral-guest
332a50c273 * src/login.c: Removed temp_shell. No more used.
* src/login.c: lastlog is only used #ifndef USE_PAM
	* src/login.c: Rename lastlog to ll to avoid name clash with the
	lastlog type.
2009-04-22 20:03:26 +00:00
nekral-guest
790dbb07fc * src/login.c: Added update_utmp() to group the prepare_utmp and
setutmp (and the utmpx versions).
2009-04-22 19:58:39 +00:00
nekral-guest
f59a69f4b6 * src/login.c: Do not include netdb.h. gethostbyname() is no more
called from within login.c. Also UT_ADDR does not exist anymore.
2009-04-22 19:54:28 +00:00
nekral-guest
efcbbc3d74 * src/login.c: Check if login is run with effective root
privileges. This should be more helpful to users than a failure to
	find an utmp entry or failure to access a file.
2009-04-21 22:46:01 +00:00
nekral-guest
a0503bc3a1 Added previous commit changelog. 2009-04-21 22:39:52 +00:00
nekral-guest
82c1a583f8 * libmisc/utmp.c: Reworked. Get rid of Linux specific stuff. Get rid
of global utent/utxent variables. Only reuse the ut_id and maybe
	the ut_host fields from utmp.
	* lib/prototypes.h, libmisc/utmp.c: Removed checkutmp(),
	setutmp(), setutmpx().
	* lib/prototypes.h, libmisc/utmp.c: Added get_current_utmp(),
	prepare_utmp(), prepare_utmpx(), setutmp(), setutmpx().
	* libmisc/utmp.c (is_my_tty): Only compare the name of the utmp
	line with ttyname(). (No stat of the two terminals to compare the
	devices).
	* libmisc/utmp.c: Use getaddrinfo() to get the address of the
	host.
	* configure.in: Check for getaddrinfo().
	* configure.in: Use AC_CHECK_MEMBERS to check for the existence of
	fields in the utmp/utmpx structures.
	* configure.in: Reject systems with utmpx support but no ut_id
	field in utmp. This could be fixed later if needed.
	* src/login.c: Use the new utmp functions. This also simplifies
	the failtmp() handling.
	* src/login.c: passwd_free() renamed to pw_free() and
	shadow_free() renamed to spw_free()
2009-04-21 22:39:14 +00:00
nekral-guest
fcfa81283e * NEWS, configure.in: Enable --enable-account-tools-setuid by
default for PAM builds, as it used to be before the introduction
	of this option.
2009-04-21 22:22:08 +00:00
nekral-guest
fba5cad820 * etc/pam.d/Makefile.am: Distribute all pam.d files, even if
ACCT_TOOLS_SETUID is not enabled.
2009-04-21 22:16:17 +00:00
nekral-guest
5bdf239a66 * lib/shadowmem.c: Added spw_free().
* lib/shadowio.c: Use spw_free() for shadow_free().
	* lib/groupmem.c: Added gr_free().
	* lib/groupio.c: Use gr_free() for group_free().
	* lib/pwmem.c: Include define.h before prototypes.h
	* lib/pwmem.c: Added pw_free().
	* lib/pwio.c: Use pw_free() for passwd_free().
	* lib/sgroupio.c: Added sgr_free().
	* lib/sgroupio.c: Use sgr_free() for gshadow_free().
	* lib/prototypes.h: Added gr_free(), pw_free(), sgr_free(),
	spw_free().
2009-04-21 22:14:10 +00:00
nekral-guest
408a30f0ba * libmisc/shell.c: Add brackets and parenthesis.
* libmisc/shell.c: Avoid assignments in comparisons.
	* libmisc/shell.c: Re-indent.
2009-04-21 22:07:35 +00:00
nekral-guest
c8f45eda53 * lib/defines.h: Added MIN and MAX macros.
* libmisc/salt.c: Removed MIN and MAX macros.
2009-04-21 22:06:09 +00:00
nekral-guest
2ba18ea4a9 Fix typo (&nbsp;) and fix a compilation warning (wrong const). 2009-04-21 22:03:33 +00:00
nekral-guest
a45b272a2f Fix typo. 2009-04-21 22:02:37 +00:00
nekral-guest
5ad0d896f1 Added more comments to the changelog entry. 2009-04-20 14:06:06 +00:00
nekral-guest
9efd6a53d2 * NEWS, src/lastlog.c: Fix regression causing empty reports. 2009-04-20 14:04:48 +00:00
nekral-guest
18fdfee274 * src/login.c: Get rid of pwent. pwd is sufficient as long as it
is always coming from xgetpwnam. There is no need to copy pwd to
	pwent, this was not a good idea anyway as the strings from pwd
	were not duplicated.
	* src/login.c: Always free the pwd and spwd structure when we
	retrieve a new one. This will clear the password of the previous
	user from the memory.
	* src/login.c: user_passwd is used to keep point to the password
	of the user being authenticated.
	* src/login.c: (non PAM) Fail if the user's entry cannot be found
	after the user updated her password (if expire() requested an
	update).
	* src/login.c: If the user does not exist on the system, there is
	no need to build a pwd structure (with shell).
2009-04-20 13:29:15 +00:00
nekral-guest
a6ac4dda75 * src/login.c: ttytype already checks for TTYTYPE_FILE and TERM.
Just call ttytype.
2009-04-20 13:12:09 +00:00
nekral-guest
29c3763f9c Re-indent. 2009-04-20 13:10:20 +00:00
nekral-guest
c694843da5 * src/login.c: Open the PAM session before pam_setcred and before
initgroups. This is more consistent with rfc86.0.
2009-04-20 12:54:17 +00:00
nekral-guest
432faba3e1 * src/login.c: Added helper functions get_pam_user() and
get_failent_user().
2009-04-20 12:47:04 +00:00
nekral-guest
70e1a5c9b6 * src/login.c: Added parameter to check_nologin. This will help
getting rid of the global pwent variable.
2009-04-20 12:33:01 +00:00
nekral-guest
61c1d100dc * src/login.c: Added comments.
* src/login.c: Close the user and group files before dropping root
	privileges.
2009-04-20 12:27:27 +00:00
nekral-guest
3508f7dccc * src/login.c: We do not need to keep the old umask. Discard the
umask() return value.
2009-04-20 12:17:38 +00:00
nekral-guest
d4158bdf77 * src/login.c: We do not need to keep the old umask. Discard the
umask() return value.
2009-04-20 12:16:07 +00:00
nekral-guest
1bcf2ffb59 * libmisc/hushed.c, lib/prototypes.h, src/login.c: Change the
hushed() prototype to take a username instead of a passwd
	structure in argument. The passwd entry is retrieved withing
	hushed().
2009-04-20 11:48:59 +00:00
nekral-guest
87ac185752 * libmisc/setugid.c: Updated comments. 2009-04-20 11:43:36 +00:00
nekral-guest
22fbd774dc * libmisc/failure.h, libmisc/failure.c, src/login.c: Added
username as first parameter of failtmp to avoid issues with
	non-null terminated ut_user, unavailability of ut_user, incomplete
	username (that should not happen currently).
2009-04-20 11:39:16 +00:00
nekral-guest
a87e747049 * libmisc/failure.h, libmisc/failure.c, src/login.c: Added
username as first parameter of failtmp to avoid issues with
	non-null terminated ut_user, unavailability of ut_user, incomplete
	username (that should not happen currently).
2009-04-20 11:37:41 +00:00
nekral-guest
f3bea401e9 * libmisc/ttytype.c: Add brackets and parenthesis.
* libmisc/ttytype.c: Avoid assignments in comparisons.
2009-04-20 11:31:05 +00:00
nekral-guest
2ce68e8aec * lib/pwio.c, lib/shadowio.c, lib/groupio.c, lib/sgroupio.c: Fill
the password fields with zeros before they are freed.
2009-04-20 11:29:17 +00:00
nekral-guest
bf66861e3f * po/ko.po: Updated Korean translation. 2009-04-19 16:26:17 +00:00
nekral-guest
131e95ffaf * NEWS, src/login.c: Also check if the authentication token of the
user has to be updated in case the user was already authenticated.
2009-04-19 16:22:17 +00:00
nekral-guest
ca10b825c7 * src/login.c: fflg is already restricted to root. Move
pam_acct_mgmt(), in case of fflg, earlier. This is equivalent and
	simplifies the code.
2009-04-19 16:09:00 +00:00
nekral-guest
2ed05e548b * libmisc/utmp.c: Always call endutent or endutxent when setutent
or setutxent were used.
2009-04-19 15:28:38 +00:00
nekral-guest
8156c3b0be * src/login.c: Added comment to make sure PAM_RHOST or PAM_TTY do
not get set to unsanitized values.
2009-04-19 13:33:24 +00:00
nekral-guest
d2a822fe39 * libmisc/utmp.c: Do not trust the current utmp entry's ut_line.
Always set ut_line based on ttyname(0).
2009-04-17 21:25:30 +00:00
nekral-guest
5298ac3dd9 * NEWS, src/login.c: Do not trust the current utmp entry's ut_line
to set PAM_TTY.
2009-04-17 20:40:26 +00:00
nekral-guest
c49371e423 * configure.in: Updated version number. 2009-04-15 21:46:42 +00:00
nekral-guest
76f7ae8d7d * po/shadow.pot, man/po/shadow-man-pages.pot: Regenerated.
* po/*.po, man/po/*.po: Updated PO files.
2009-04-15 21:46:06 +00:00
nekral-guest
e312f007b8 Fix NEWS entry. 2009-04-15 21:31:09 +00:00
nekral-guest
239bb04b18 Fixed nb.po format and added info about the update. 2009-04-15 21:29:00 +00:00
nekral-guest
4d2bee2e23 * NEWS, src/userdel.c: Fixed SE Linux support. semanage should be
called at the end.
	* src/useradd.c: Always call selinux_update_mapping() (i.e.
	semanage), not only when -Z is used.
2009-04-15 21:14:08 +00:00
nekral-guest
a24058d660 * NEWS, srclib/getlong.c: Fix parsing of octal numbers.
* NEWS, src/login.c: Fix segfault when no user is provided on the
	command line.
2009-04-15 17:50:17 +00:00
nekral-guest
70d9bc6233 libmisc/system.c was contributed by Dan Walsh. 2009-04-15 17:42:34 +00:00
nekral-guest
5fa86c2b42 * NEW, src/vipw.c: SE Linux: Set the default context to the
context of the file being edited. This ensures that the backup
	file inherit from the file's context.
2009-04-15 17:42:27 +00:00
nekral-guest
a8586cbce7 Added one TODO item for usermod. 2009-04-14 22:19:17 +00:00
nekral-guest
acc3423c96 * man/usermod.8.xml: There are no default values for --inactive
and --gid. If the options are no provided, the original values are
	not changed.
2009-04-14 22:19:11 +00:00
nekral-guest
ceddfa340d Removed TODO entries
* groupmems has a testsuite now
 * long user names are tested for gpasswd
 * groups and id arenot receiving updates
 * tests with UID/GID sets to (*id_t)-1 already exist.
2009-04-14 22:19:05 +00:00
bubulle
8675b74bf4 Norwegian Bokmål translation update 2009-04-12 17:43:31 +00:00
nekral-guest
b4a3ab4082 Added release date. 2009-04-12 02:45:11 +00:00
nekral-guest
0b4b3d63da * po/shadow.pot, man/po/shadow-man-pages.pot: Regenerated.
* po/*.po, man/po/*.po: Updated PO files.
2009-04-12 01:24:45 +00:00
nekral-guest
774f8a073a Added TODO entry. 2009-04-12 00:38:41 +00:00
nekral-guest
6b46161f2d * src/su.c: If there are no root account, or if the root account
has an UID != 0, default to the first UID 0 account.
2009-04-12 00:28:32 +00:00
nekral-guest
08a212ccae * src/login.c: Restore the echoctl, echoke, onclr flags to the
terminal termio flags. Reset echoprt, noflsh, tostop. This
	behavior seems to have change by mistake in earlier releases
	(4.0.8, for no obvious reason).
2009-04-12 00:17:36 +00:00
nekral-guest
64a9f33ffa * src/login.c: Fix the count of failures before login exits in
case of PAM enabled configurations.
2009-04-12 00:08:26 +00:00
nekral-guest
bc0f4fa509 * man/passwd.1.xml: Document that passwd uses PAM to authenticate
and change passwords on PAM-enabled builds.
2009-04-11 23:32:00 +00:00
nekral-guest
681c1d12b5 * src/newusers.c: Add more information to the mkdir and chown
failure messages.
2009-04-11 23:30:44 +00:00
nekral-guest
ce156b578f * man/po/fr.po: Updated some login.defs entries. Thanks to
Belkacem Abbas.
2009-04-11 22:41:00 +00:00
nekral-guest
4e32b9fea9 * man/login.defs.d/MAX_MEMBERS_PER_GROUP.xml,
man/login.defs.d/CONSOLE_GROUPS.xml: Fix typos.
2009-04-11 22:36:11 +00:00
nekral-guest
fb631fa4eb Add the POT files to the repository. 2009-04-11 19:19:21 +00:00
nekral-guest
ac305b82a4 Fix typo. 2009-04-11 19:18:38 +00:00
nekral-guest
5a56996eef * man/es/Makefile.am: Disable the distribution of Spanish
manpages. They are outdated. Please contact
	pkg-shadow-devel@lists.alioth.debian.org if you wish to provide
	updates.
2009-04-11 18:57:14 +00:00
nekral-guest
af7b9b8b62 Fix typo. 2009-04-11 18:44:15 +00:00
nekral-guest
554d4f6b95 * src/usermod.c, src/useraddd.c: Fix the usage string so that it
does not change depending on the configure option. Use a format.
2009-04-11 18:39:56 +00:00
nekral-guest
80a30dfe6f * src/gpasswd.c: Fix the usage of the unused macro. 2009-04-11 18:37:59 +00:00
nekral-guest
cab74eddef * lib/prototypes.h, libmisc/age.c, src/expiry.c, src/login.c: A
shadow entry is now sufficient for agecheck. Remove the first
	passwd entry parameter.
2009-04-11 18:37:08 +00:00
nekral-guest
42590e062f * src/userdel.c: Rename argv to args to avoid nameclash with the
main() parameters.
2009-04-11 16:52:45 +00:00
nekral-guest
3fdefd3e40 * src/useradd.c, src/usermod.c: Only call selinux_update_mapping()
if Zflg is set.
2009-04-11 16:47:32 +00:00
nekral-guest
192fa18195 Added TODO item. 2009-04-11 16:24:06 +00:00
nekral-guest
60a7cc9d7c * libmisc/getgr_nam_gid.c: Added support for NULL argument.
* libmisc/chowntty.c: Reuse getgr_nam_gid(), and get rid of atol().
2009-04-11 16:23:21 +00:00
nekral-guest
e27f4a91b9 Tag one of the remaining strtol. 2009-04-11 16:08:00 +00:00
nekral-guest
ca1bb50c24 * libmisc/find_new_gid.c, libmisc/find_new_uid.c: For system
accounts, return the first unused ID, starting from the max value.
	This could be useful later to increase the static IDs range.
2009-04-11 16:00:45 +00:00
nekral-guest
8d136297c4 * NEWS, src/useradd.c, man/useradd.8.xml: add -Z option to map
SELinux user for user's login.
	* NEWS, src/usermod.c, man/usermod.8.xml: Likewise.
	* libmisc/system.c, libmisc/Makefile.am, lib/prototypes.h: Added
	safe_system(). Used to run semanage.
	* lib/prototypes.h, libmisc/copydir.c: Make a
	selinux_file_context() an extern function.
	* libmisc/copydir.c: Reset SELinux to create files with default
	contexts at the end of copy_tree().
	* NEWS, src/userdel.c: Delete the SELinux user mapping for user's
	login.
2009-04-11 15:34:10 +00:00
nekral-guest
2c400eff94 * src/useradd.c (get_defaults): Close the default file after the
default values were read.
2009-04-11 14:55:49 +00:00
bubulle
5d9c298e9d Slovak translation updated 2009-04-11 13:53:41 +00:00
nekral-guest
689a7197a0 Re-indent. 2009-04-11 13:00:32 +00:00
nekral-guest
413bb19543 * lib/Makefile.am, lib/prototypes.h: Added sgetspent.c. 2009-04-10 22:35:43 +00:00
nekral-guest
db337babbc * po/POTFILES.in: Added missing files. Sorted. 2009-04-10 22:35:37 +00:00
nekral-guest
46861e6bd8 Removed declaration of ep. No more used.
Re-indent.
2009-04-10 22:35:32 +00:00
nekral-guest
84f5ca951c * lib/getdef.c: Use getlong instead of strtol/strtoul.
* libmisc/getlong, lib/getlong.c, libmisc/Makefile.am,
	lib/Makefile.am: getlong.c moved from libmisc/ to lib/.
2009-04-10 22:35:26 +00:00
nekral-guest
1c97cf5c83 Removed DONE entry. 2009-04-10 22:35:19 +00:00
nekral-guest
9a7f5c6b16 * lib/shadow.c: Replace strtol() by getlong(). Also detect more
issues in a numerical shadow entry field.
2009-04-10 22:35:14 +00:00
nekral-guest
b5200cf753 * lib/sgetspent.c: Only compile ifndef HAVE_SGETSPENT 2009-04-10 22:35:07 +00:00
nekral-guest
686ac847aa Revert " * lib/sgetspent.c: Removed (is not used / compiled) anymore."
This reverts commit dbeb402f0b0befd8c48b68d53277e1bd1b5f751b.
2009-04-10 22:35:01 +00:00
nekral-guest
e075442345 * lib/sgetspent.c: Removed (is not used / compiled) anymore. 2009-04-10 22:34:55 +00:00
nekral-guest
c7258f22d8 * lib/sgetspent.c: Replace strtol() by getlong(). Also detect more
issues in a numerical shadow entry field.
2009-04-10 22:34:49 +00:00
nekral-guest
304b0ec202 * src/chage.c: expdays renamed to expdate. It is a date, even if
expressed in a number of days since Jan 1, 1970.
	* src/chage.c: Likewise: lastday renamed to lstchgdate. Also fix
	the --lastday documentation.
2009-04-10 22:34:42 +00:00
nekral-guest
52238dd6a7 * src/chage.c: More strtol() replaced by getlong(). 2009-04-10 22:34:36 +00:00
nekral-guest
66e39884e2 * lib/prototypes.h: pwd_to_spwd() should be declared if USE_PAM is
NOT defined.
2009-04-10 22:34:29 +00:00
nekral-guest
d548bf4742 * src/passwd.c: Replace getnumber() by getlong(). This permits to
get rid of another strtol().
2009-04-10 22:34:23 +00:00
nekral-guest
1675ca3378 * libmisc/getlong.c: Include both <stdlib.h> and <errno.h> needed
for strtol and errno, and do not include "defines.h" (not needed).
2009-04-10 22:34:17 +00:00
nekral-guest
77459dc27d * src/useradd.c, src/usermod.c, libmisc/getgr_nam_gid.c,
libmisc/Makefile.am, lib/prototypes.h: Moved getgr_nam_gid() from
	src/useradd.c and src/usermod.c to libmisc/getgr_nam_gid.c.
2009-04-10 22:34:10 +00:00
nekral-guest
ffd3e43ad8 * src/useradd.c: Get rid of strtol.
* src/useradd.c: Provide better warning in case a default GROUP or
	INACTIVE value is not valid in /etc/default/useradd.
2009-04-10 22:34:04 +00:00
nekral-guest
95bc6eb7b2 * src/useradd.c: Re-indent. 2009-04-10 22:33:57 +00:00
nekral-guest
06c81b67c2 * src/useradd.c: Use getlong instead of get_number. 2009-04-10 22:33:50 +00:00
nekral-guest
c3f109556a * src/usermod.c: Re-indent.
* src/usermod.c: Specifying a inactivity value < -1 is not valid.
2009-04-10 22:33:43 +00:00
nekral-guest
f481938cc5 * po/*.po, man/po/*.po: Updated PO files. 2009-04-05 23:52:46 +00:00
nekral-guest
4b15eefd3c Added todo items. 2009-04-05 23:50:58 +00:00
nekral-guest
b9df8b5817 * configure.in: Prepare the next 4.1.3 release. 2009-04-05 22:35:12 +00:00
nekral-guest
ac52639b77 * libmisc/setugid.c libmisc/age.c (setup_uid_gid): is_console is
never set ifndef USE_PAM. Change the prototype of setup_uid_gid()
	when USE_PAM is not defined. This permits to remove add_groups
	from PAM builds.  setup_uid_gid is already subject to
	HAVE_INITGROUPS.
2009-04-05 22:33:00 +00:00
nekral-guest
a51954203e * lib/prototypes.h, libmisc/addgrps.c: restrict add_groups() to
ifndef USE_PAM.
	* lib/prototypes.h: Remove the declaration of add_cons_grps(). The
	function does not exist.
	* libmisc/age.c (setup_uid_gid): is_console is never set ifndef
	USE_PAM. Change the prototype of setup_uid_gid() when USE_PAM is
	not defined. This permits to remove add_groups from PAM builds.
	setup_uid_gid is already subject to HAVE_INITGROUPS.
	* libmisc/pwd2spwd.c (pwd_to_spwd): pwd_to_spwd() is not used in
	PAM builds.
2009-04-05 22:29:42 +00:00
nekral-guest
021066a980 * src/passwd.c: do_update_age is only used ifndef USE_PAM. Make it
more explicit.
2009-04-05 22:04:31 +00:00
nekral-guest
a1cac18ac3 * src/useradd.c: Set errno to 0 before calling strtol. 2009-04-05 22:02:50 +00:00
nekral-guest
2a3b84b888 * libmisc/isexpired.c: If there are no shadow entry, there is no
need to convert the password entry to a shadow entry. The password
	is valid.
2009-04-05 22:02:00 +00:00
nekral-guest
f703b686da Fix typo. 2009-04-05 21:56:37 +00:00
nekral-guest
682eedb167 * man/usermod.8.xml: Split some paragraphs into smaller units. 2009-04-05 21:23:55 +00:00
nekral-guest
3511b1de80 Updated copyright dates. 2009-04-05 21:23:42 +00:00
nekral-guest
2f85113366 * man/shadow.5.xml: Rewrote to mention the meaning of special
values.
2009-04-05 21:23:35 +00:00
nekral-guest
b23443630c * libmisc/pwd2spwd.c, src/chpasswd.c, src/newusers.c,
src/passwd.c, src/pwck.c, src/pwconv.c, src/useradd.c,
	src/usermod.c: On Jan 01, 1970, do not set the sp_lstchg field to
	0 (which means that the password shall be changed during the next
	login), but use -1 (password aging disabled).
	* src/passwd.c: Do not check sp_min if sp_lstchg is null or -1.
2009-04-05 21:23:27 +00:00
nekral-guest
7585fa0fe9 * src/chage.c: When no shadow entry exist, thedefault sp_lstchg
value should be -1 (no aging) rather than 0 (password must be
	changed).
	* src/chage.c: For password expiration and inactivity, indicate
	that the password must be changed when sp_lstchg is null rather
	than indicating that expiration and inactivity are not enabled.
2009-04-05 21:23:17 +00:00
nekral-guest
1ba2139d5c * libmisc/isexpired.c: Document the isexpired return value. 2009-04-05 21:23:06 +00:00
nekral-guest
f67403ba01 * libmisc/age.c: Return a specific message when sp_lstchg is null. 2009-04-05 21:22:53 +00:00
nekral-guest
996e842149 Added missing space at the end of the question. 2009-03-22 12:32:40 +00:00
nekral-guest
c2bb947c14 Remove unused variable. 2009-03-21 20:45:35 +00:00
nekral-guest
d4fc74e43c * lib/sgetpwent.c, lib/sgetgrent.c: Use get_uid and get_gid to
validate the UIDs or GIDs instead of atoi/strtol.
2009-03-21 20:29:58 +00:00
nekral-guest
a1dd26d2d6 * libmisc/get_gid.c, libmisc/get_uid.c, libmisc/Makefile.am,
lib/get_gid.c, lib/get_uid.c, lib/Makefile.am: get_uid.c and
	get_gid.c moved from libmisc/ to lib/.
2009-03-21 20:24:37 +00:00
nekral-guest
503976fc6a * src/grpck.c (check_members): When a member is removed, do not
increase the index.
	* src/grpck.c: Fix typo in messages and comments.
2009-03-21 19:42:48 +00:00
nekral-guest
dab1523df5 * libmisc/sulog.c: Likewise for the su log. 2009-03-21 19:32:14 +00:00
nekral-guest
a65c2c9b18 * src/vipw.c: Likewise for the backup file. 2009-03-21 19:28:02 +00:00
nekral-guest
5331930716 * src/usermod.c: Likewise for the faillog and lastlog file. 2009-03-21 19:25:02 +00:00
nekral-guest
96c7b12bc4 * src/useradd.c: Likewise for the default file, faillog, lastlog,
and mail spool.
2009-03-21 19:18:06 +00:00
nekral-guest
5dd5f51700 * lib/commonio.c: Call fsync before closing the backup file. This
ensures that the backup file is flushed to the storage medium.
2009-03-21 19:12:00 +00:00
nekral-guest
df7abc5447 Fixed TODO item. 2009-03-15 21:43:24 +00:00
nekral-guest
db7370d242 Added TODO items. 2009-03-15 21:38:46 +00:00
nekral-guest
a8e9fc86eb * src/groupmod.c: Embed gshadow related cleanup in #ifdef
SHADOWGRP.
2009-03-15 21:38:08 +00:00
nekral-guest
a402c4db3b * src/usermod.c: get_number() replaced by getlong().
* src/usermod.c: When the user is renamed, make sure we do not
	override an user with the same name (in passwd or shadow).
2009-03-15 21:34:20 +00:00
nekral-guest
780af2653a * src/gpasswd.c: log_gpasswd_success_gshadow is in the cleanup
stack only when the shadow group file is present.
2009-03-15 21:32:26 +00:00
nekral-guest
9372111aaa * NEWS, src/userdel.c: Make sure the user exists in the shadow
database before calling spw_remove().
	* NEWS, src/userdel.c: When the user's group is removed, make sure
	the group is in the gshadow database before calling sgr_remove().
	* src/userdel.c: Improve warning's wording.
2009-03-15 21:29:16 +00:00
nekral-guest
9fda9f5c28 * libmisc/cleanup.c: Fix del_cleanup. The arguments were not
desynchronized with the cleanup functions.
	* libmisc/cleanup.c: cleanup_function_args is an array of void
	pointer, not strings.
2009-03-15 21:15:48 +00:00
nekral-guest
80135cdc17 * libmisc/find_new_gid.c: Fix find_new_gid() the current group
database was not taken into account.
2009-03-15 21:12:57 +00:00
nekral-guest
6aa874a0a0 * libmisc/addgrps.c: Fix compilation warnings. 2009-03-15 21:10:35 +00:00
nekral-guest
d1dac25379 * man/po/Makefile.in.in: xml2po cannot exclude one entity for
expansion. Make sure config.xml does not exist when the POT file
	is created in order to keep the configurations in the POT file
	* man/generate_translations.mak: make sure config.xml does not
	exist neither when the translated XML is generated. Add the
	missing %config; (strip out by xml2po). and make sure config.xml
	is present when the translated manpage is generated.
	* man/generate_mans.mak: config.xml is needed for the generation
	of manpages (already in the .deps for the English manpages, but
	needed for the translations).
	* man/Makefile.am: Added missing CREATE_HOME.xml.
2009-03-14 16:18:06 +00:00
nekral-guest
526e7ac972 * man/generate_mans.deps: Added Makefile dependency rules. 2009-03-14 13:29:55 +00:00
nekral-guest
fa7bae1210 Updated TODO list. 2009-03-14 13:21:15 +00:00
nekral-guest
d60f0a1a10 * etc/login.defs: Added note for PAM enabled configurations. 2009-03-14 13:20:25 +00:00
nekral-guest
78230efd01 Added config.xml to the list of ignored files. 2009-03-14 13:18:28 +00:00
nekral-guest
8411a8e8b4 * man/Makefile.am: Compute the dependencies for building the
manpages.
2009-03-14 13:16:55 +00:00
nekral-guest
295106b6a8 * libmisc/addgrps.c: Fix warnings. 2009-03-14 13:13:47 +00:00
nekral-guest
29381bf9d6 * man/po/fr.po: Added missing space. 2009-03-14 13:08:49 +00:00
nekral-guest
5a5cf15430 * man/lastlog.8.xml: Document that there might be entries, for
deleted users, that are not displayed.
2009-03-14 11:11:04 +00:00
nekral-guest
884a2de437 * man/chgpasswd.8.xml, man/chpasswd.8.xml: Fix the man page in
case SHA crypt is not supported.
2009-03-14 11:09:57 +00:00
nekral-guest
5349c79d12 * man/vipw.8.xml: MAX_MEMBERS_PER_GROUP is not used by vipw and
vigr.
2009-03-14 11:08:39 +00:00
nekral-guest
9ee627fe02 * man/login.defs.5.xml: Indicate that sg uses the same variables
as newgrp.
	* man/login.defs.5.xml: vipw does not use any variable.
	* man/login.defs.5.xml: In PAM enabled configurations, login still
	uses some login.defs variables.
2009-03-13 23:17:43 +00:00
nekral-guest
1def19ecea * man/usermod.8.xml: use a <replaceable> instead of a
<emphasis remap='I'>.
2009-03-13 23:14:18 +00:00
nekral-guest
dc857372ed * man/newusers.8.xml: Document the behavior of newusers for each
field.
	* man/newusers.8.xml: Do not add the note on PAM on non-PAM
	enabled configurations.
2009-03-13 23:12:06 +00:00
nekral-guest
730fc8fc33 * src/faillog.c: Added support for the specification of a range of
users with -u.
	* src/faillog.c: Do not call print_one() for users which do not
	exist.
	* src/faillog.c: Make sure the user's entry is not outside the
	faillog file and initialize the faillog structure in that case.
	* src/faillog.c: Move print_one() closer to print().
	* src/faillog.c: reset(), setmax(), set_locktime() can also change
	entries of user which do not exist.
	* src/faillog.c: reset(), setmax() and set_locktime() shall not
	create entries for users which have no entries if the value has to
	be set to 0.
	* src/faillog.c: reset(), setmax() and set_locktime(): better
	handling of users whose entry is outside the faillog file.
	* src/faillog.c: Improved option handling. Options can now be
	specified in any order.
	* src/faillog.c: Improved warnings when options are not
	compatible or when the faillog cannot be open with the right mode.
	* src/faillog.c: Only fstat the faillog file once.
	* man/faillog.8.xml: Improved documentation.
2009-03-13 22:49:20 +00:00
nekral-guest
fafe281d31 * src/useradd.c, man/useradd.8.xml: Added long name for the -l
option: --no-log-init.
2009-03-13 22:30:38 +00:00
nekral-guest
f98b47eb55 * src/chpasswd.c: Make sure the SHA related variables is not
compiled when disabled at configuration time.
	* src/chgpasswd.c: Make sure the SHA related variables is not
	compiled when disabled at configuration time.
	* src/chgpasswd.c: Fix the test for getlong() failure.
2009-03-13 22:28:27 +00:00
nekral-guest
e3e64317e8 * src/newusers.c: Make sure the SHA related variables are not
compiled when disabled at configuration time.
	* src/newusers.c: Added FIXME
2009-03-13 22:26:35 +00:00
nekral-guest
f2c8017df4 * src/gpasswd.c: Remove the documentation of options from the
main() documentation. It will always be outdated here.
2009-03-13 22:21:26 +00:00
nekral-guest
bf9036d27a * src/lastlog.c: lastlog variable renamed to ll to avoid name
clash with the structure.
	* src/lastlog.c: check the offset in print_one() so that it is
	used for the display of one entry or a set of entries.
	* src/lastlog.c: Do not loop over the whole user database when -u
	is used with a single user.
	* src/lastlog.c: Check the size of the lastlog file so that we
	can identify failures to read.
2009-03-13 22:20:20 +00:00
nekral-guest
87da822c7f * libmisc/salt.c: Removed l64a prototype. The libc declaration is
non static, but the internal definition is static.
2009-03-13 19:17:24 +00:00
nekral-guest
47a57bced1 Add TODO item for the testsuite. 2009-03-08 23:30:56 +00:00
nekral-guest
1dc04372df Compile fixes. Fixes warnings. 2009-03-08 23:30:25 +00:00
nekral-guest
27153ae92b * src/gpasswd.c: log_gpasswd_success_gshadow only exists ifdef
SHADOWGRP.
2009-03-08 23:29:46 +00:00
nekral-guest
28d7f83c87 * NEWS, src/newusers.c, src/usermod.c, src/useradd.c,
src/groupmod.c, src/groupadd.c: Make sure no user or group are
	created with an ID set to -1.
2009-03-08 20:43:15 +00:00
nekral-guest
c1052e2df2 * NEWS, src/grpck.c, src/pwck.c: Issue a warning if an ID is set
to -1.
2009-03-08 20:29:22 +00:00
nekral-guest
c9121d025f * NEWS, src/grpck.c, src/pwck.c: Issue a warning if an ID is set
to -1.
2009-03-08 20:28:55 +00:00
nekral-guest
0e2a3979f4 * libmisc/get_gid.c, libmisc/get_uid.c, libmisc/Makefile.am,
lib/prototypes.h: Added get_uid() and get_gid() to parse user and
	group IDs.
2009-03-08 20:26:56 +00:00
nekral-guest
186ea0e203 * libmisc/getlong.c: Make sure the getlong argument is not empty. 2009-03-08 20:21:24 +00:00
nekral-guest
f47d9eba94 * contrib/adduser-old.c, contrib/adduser.c: Do not use the target
of snprintf in one of the format's parameters.
2009-03-07 16:32:11 +00:00
nekral-guest
7368452e49 * man/groupmems.8.xml: groupmems does not create new user. 2009-03-07 16:30:49 +00:00
nekral-guest
635ef3bbf8 Added TODO items. 2009-03-07 16:29:28 +00:00
nekral-guest
b46fd9a2b4 * NEWS, po/LINGUAS, po/kk.po: Added Kazakh translation. Thanks to
Timur Birsh <taem@linukz.org>.
2009-03-03 20:53:20 +00:00
nekral-guest
a62e781248 * libmisc/find_new_gid.c, libmisc/find_new_uid.c: Avoid calling
getgrent()/getpwent() after they return NULL. This caused LDAP to
	return at the beginning of the group/user entries.
2009-02-22 23:23:15 +00:00
nekral-guest
32ef9c2135 * man/nologin.8.xml: Fix typo (HYSTORY -> HISTORY). 2009-01-27 18:17:54 +00:00
nekral-guest
f2d6449374 * NEWS, src/gpasswd.c: Only report success to audit and syslog
when the changes are committed to the system. Do not log failure
	for on-memory changes to audit or syslog. Make sure failures and
	inconsistencies will be reported in case of unexpected failures
	(e.g. malloc failures). Only specify an audit message if it is not
	implicitly implied by the type argument. Removed fail_exit
	(replaced by atexit(do_cleanups)). Log failures in case of
	permission denied.
2009-01-26 22:03:37 +00:00
nekral-guest
7b532f0b44 - newusers should use the CREATE_HOME variable (and new options are needed)
- usermod
  - the mode of new home directories should be set according to the
    original mode. Does copy_tree does this?
2009-01-21 14:49:42 +00:00
nekral-guest
af96cba0cc * etc/login.defs: Improve the documentation of UMASK. 2009-01-19 10:21:50 +00:00
nekral-guest
a684cadbb6 * man/useradd.8.xml, man/login.defs.d/CREATE_HOME.xml,
man/login.defs.5.xml: Document the CREATE_HOME variable.
2009-01-19 10:00:53 +00:00
nekral-guest
6c85ca9661 * man/limits.5.xml: Remove space before an end of tag. 2009-01-19 09:51:53 +00:00
nekral-guest
de60b7b2de * man/login.defs.d/UMASK.xml: Indicate how UMASK is used and
limitations.
2009-01-19 09:51:00 +00:00
nekral-guest
d8c9236a18 * NEWS, src/su.c: Preserve COLORTERM in addition to TERM when su
is called with the -l option.
2009-01-06 20:13:31 +00:00
nekral-guest
2bb7007fcb * libmisc/chkname.c: Use a bool when possible instead of integers.
* libmisc/chkname.c: Add brackets and parenthesis.
2008-12-23 22:42:22 +00:00
nekral-guest
4c7d798307 * man/groupadd.8.xml, configure.in, man/config.xml.in: Use the
real group name length limit in the documentation.
2008-12-23 22:36:44 +00:00
nekral-guest
3cb730bcfe * src/Makefile.am: Only link with the needed library. When
compiled with PAM support, chfn, chsh, login, newgrp, passwd, and
	su do not need the libcrypt library.
2008-12-23 00:44:29 +00:00
nekral-guest
1b0a32d71c * libmisc/cleanup_group.c: Fix compilation when compiled without
shadow group support.
2008-12-23 00:39:54 +00:00
nekral-guest
915ec6531a * src/groupdel.c: Remove the fail_exit () declaration. 2008-12-22 23:23:14 +00:00
nekral-guest
1df7433e44 Fix typo. 2008-12-22 22:13:50 +00:00
nekral-guest
0bd396011a * src/gpasswd.c: Fix the support for usernames with arbitrary
length.
2008-12-22 22:13:23 +00:00
nekral-guest
6405b58a98 * libmisc/chkname.c: Remove outdated comments. 2008-12-22 22:08:13 +00:00
nekral-guest
9d977dba8e * src/groupdel.c: Re-indent. 2008-12-22 22:07:12 +00:00
nekral-guest
ad7a108d60 * src/groupmod.c: Re-indent.
* src/groupmod.c: Do not add the command synopsis to the main ()
	documentation. This avoids outdated information.
2008-12-22 22:06:27 +00:00
nekral-guest
fca6aeeea2 * src/groupadd.c: Re-indent. 2008-12-22 22:03:34 +00:00
nekral-guest
5b8ff14caf * libmisc/audit_help.c: Added audit_logger_message() to log
messages not related to an account.
	* lib/prototypes.h, libmisc/cleanup.c, libmisc/cleanup_group.c,
	libmisc/cleanup_user.c, libmisc/Makefile.am: Added stack of
	cleanup functions to be executed on exit.
	* NEWS, src/groupadd.c, src/groupdel.c, src/groupmod.c: Only
	report success to audit and syslog when the changes are committed
	to the system. Do not log failure for on-memory changes to audit
	or syslog. Make sure failures and inconsistencies will be reported
	in case of unexpected failures (e.g. malloc failures). Only
	specify an audit message if it is not implicitly implied by the
	type argument. Removed fail_exit (replaced by atexit(do_cleanups)).
2008-12-22 21:52:43 +00:00
nekral-guest
a438c2f184 * NEWS, src/gpasswd.c: Added support usernames with arbitrary
length.
2008-12-15 21:54:53 +00:00
nekral-guest
66cb5b33ad * configure.in: Fix the "$enable_acct_tools_setuid" = "yes" test. 2008-11-30 01:32:38 +00:00
nekral-guest
c28c443d8f * NEWS, configure.in, libmisc/chkname.c: make group max length a
configure option.  The configure behavior encoded is:
	<no option> -> default of 16 (like today);
	--with-group-name-max-length -> default of 16;
	--without-group-name-max-length -> no max length;
	--with-group-name-max-length=n > max is set to n.
2008-11-30 01:29:40 +00:00
nekral-guest
93358ac3de * src/su.c: (!USE_PAM) Provide visible information indicating that
su was denied.
2008-11-23 12:10:21 +00:00
nekral-guest
0667aee3cc * man/ja/login.1: Fix the path of the utmp and wtmp files. 2008-11-23 00:16:53 +00:00
nekral-guest
2297508f13 * man/su.1.xml: Fix the su synopsis. username is referenced in the
manpage, not LOGIN.
2008-11-23 00:16:10 +00:00
nekral-guest
1a04bbb044 * libmisc/chowntty.c: Only closelog() when failure cause an exit. 2008-11-23 00:06:56 +00:00
nekral-guest
cf31f05cfb * libmisc/chowntty.c: Improve the logs for fchown and fchmod
failures.
2008-11-23 00:05:39 +00:00
nekral-guest
2b290e7abb * libmisc/chowntty.c, src/login.c, lib/prototypes.h: Remove the
tty argument from chown_tty. chown_tty always changes stdin and
	does not need this argument anymore.
2008-11-22 23:56:51 +00:00
nekral-guest
a324a7f13f * NEWS, libmisc/chowntty.c, libmisc/utmp.c: is_my_tty() moved from
utmp.c to chowntty.c. checkutmp() now only uses an existing utmp
	entry if the pid matches and ut_line matches with the current tty.
	This fixes a possible DOS when entries can be forged in the utmp
	file.
	* libmisc/chowntty.c, src/login.c, lib/prototypes.h: Remove the
	tty argument from chown_tty. chown_tty always changes stdin and
	does not need this argument anymore.
2008-11-22 23:56:11 +00:00
nekral-guest
eb4097180b * NEWS, libmisc/chowntty.c: Fix a race condition that could lead to
gaining ownership or changing mode of arbitrary files.
2008-11-22 23:22:16 +00:00
nekral-guest
8d7e1faebf Added todo items for pwck. 2008-10-11 13:15:29 +00:00
nekral-guest
c0311206c8 * man/gshadow.5.xml, man/shadow.5.xml, man/passwd.5.xml,
man/grpck.8.xml: Sorted SEE ALSO references.
	* man/gshadow.5.xml: Added reference to grpck(8) and grpconv(8).
	* man/pwck.8.xml: Added reference to grpck(8).
	* man/shadow.5.xml: Added reference to pwck(8).
	* man/passwd.5.xml: Added reference to pwck(8).
	* man/grpck.8.xml: Added reference to pwck(8).
2008-10-11 12:59:02 +00:00
nekral-guest
4b2f537795 * man/*.xml, man/login.defs.d/*.xml: Added copyright and licence
header.
2008-10-11 11:44:43 +00:00
nekral-guest
4d49f543dd * src/login.c: Always check the return value of the pam_* APIs. 2008-09-20 21:17:26 +00:00
nekral-guest
d400af51fa * src/login.c, man/login.1.xml: the username is not an optional
parameter of -f. Fix the getopt optstring, remove the parsing of
	username in the -f processing block, and remove unnecessary checks
	(username cannot be parsed twice anymore), better documentation of
	the synopsis.
2008-09-20 20:20:19 +00:00
nekral-guest
c8d2175981 * src/login.c: Erase the username later since it it used for the
fake password check (in case of empty password).
2008-09-20 20:05:22 +00:00
nekral-guest
11c7543c76 * src/login.c: Explicitly tag the end of the #ifdef RLOGIN
sections.
2008-09-20 20:03:04 +00:00
nekral-guest
29d4533047 * src/login.c: Check that no username is specified with -r.
* src/login.c: Make sure a username is specified with -f.
2008-09-20 20:00:51 +00:00
nekral-guest
c813e692a2 * src/login.c: Copy the name of the user authenticated by PAM to
username. This simplify later logging (avoid USE_PAM
	conditional).
2008-09-20 19:54:35 +00:00
nekral-guest
65e32d850c * src/login.c: Use a dynamic buffer for usernames. 2008-09-20 19:44:12 +00:00
nekral-guest
9f2ce12b28 * src/login.c: Existence of pam_user was already checked. pwd was
already copied to pwent. Remove duplicated code.
2008-09-20 16:23:04 +00:00
nekral-guest
f4860274be * src/login.c: check_flags() renamed process_flags(). All flag
processing blocs moved to process_flags().
2008-09-20 16:21:46 +00:00
nekral-guest
6b17118e72 * src/logoutd.c, src/userdel.c: Re-indent. This helps pmccabe. 2008-09-20 14:56:10 +00:00
nekral-guest
54a0762bbb * src/login.c: Re-indent. 2008-09-20 14:39:09 +00:00
nekral-guest
1e3f19ad89 * src/login.c: Add missing closing }. This was probably never
noticed because UT_ADDR is never defined.
2008-09-20 14:21:51 +00:00
nekral-guest
5b73a0492d * src/login.c: Do not mix USE_PAM and !USE_PAM code. 2008-09-20 14:17:20 +00:00
nekral-guest
9fa519c983 * src/login.c: Use failent_user to log to audit. username is the
caller, not the user login tries to authenticate.
	* src/login.c: Use pwd->pw_name instead of pwd->pw_uid. This might
	be more precise (name must be unique, uid might not be).
2008-09-20 13:20:31 +00:00
nekral-guest
c71e7861ed * man/passwd.1.xml: passwd cannot change the full name of the
user, the user's login shell; but it can change the account or
	password validity period. Thanks to Reuben Thomas.
2008-09-20 10:53:00 +00:00
nekral-guest
f3df48ab4f * src/useradd.c: Added missing declaration of Mflg.
* src/pwck.c: Only unlock files if they were locked before (e.g.
	not in read-only mode).
	* src/pwck.c: Quote the username in error messages (harmonization
	with other messages).
	* libmisc/find_new_gid.c: Fixed typo (s/grp->gr_gid/group_id/).
	* libmisc/find_new_gid.c: Likewise.
2008-09-14 13:42:10 +00:00
nekral-guest
5df1f2f683 * libmisc/setugid.c, src/login_nopam.c, src/suauth.c,
lib/getdef.c: Replace the %m format string by strerror(). This
	avoids errno to be reset between the system call error and the
	report function.
2008-09-13 18:03:50 +00:00
nekral-guest
0833bc3cc0 * lib/commonio.c: Ignore the return value of umask() when the mask
is set to the old value.
2008-09-13 11:55:50 +00:00
nekral-guest
b18d46e68d * NEWS, etc/login.defs: New CREATE_HOME variable to tell useradd
to create a home directory for new users.
	* src/useradd.c, man/useradd.8.xml: New -M/--no-create-home option
	and CREATE_HOME usage. System accounts are not impacted by
	CREATE_HOME.
	* man/useradd.8.xml: Indicate that a new group is created by
	default.
	* src/useradd.c: Removed TODO item (moved to the TODO file).
2008-09-13 11:55:41 +00:00
nekral-guest
d1f92a2225 * po/cs.po: Updated Czech translation.
Thanks to Miroslav Kuře
2008-09-13 11:55:30 +00:00
nekral-guest
a279244709 * man/login.defs.d/USERGROUPS_ENAB.xml: Fix typo: new <para> tag
before the previous one is closed. This caused a missng
	explanation for USERGROUPS_ENAB.
2008-09-13 11:55:20 +00:00
nekral-guest
b12db09e31 * man/groupadd.8.xml: Remove the list of (short) options from the
SYNOPSIS. Replaced with [options] for consistency with other tools
	and maintainability.
2008-09-13 11:55:08 +00:00
nekral-guest
4d6385633f New TODO item.
useradd:
  - Add support for -K in -D mode
2008-09-13 11:54:58 +00:00
nekral-guest
8c060833c8 From RedHat's patch shadow-4.1.2-sysAccountDownhill.patch
Thanks to Peter Vrabec.
	* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Build an
	index of used IDs to avoid a database request for each id in the
	allowed range (when the highest allowed ID is already used).
	This speedups the addition of users or groups when the highest
	allowed ID is already used. The additional memory usage of the
	tools should be acceptable when UID_MAX/SYS_UID_MAX are set to a
	reasonable number.
2008-09-13 11:54:49 +00:00
nekral-guest
70c9eeff05 * configure.in: Fix the dependency of ACCT_TOOLS_SETUID on
USE_PAM. Build failed with --without-libpam.
2008-09-07 20:40:41 +00:00
nekral-guest
f91b828708 * libmisc/copydir.c: Call utimes() after closing the file. 2008-09-07 00:51:17 +00:00
nekral-guest
828e9d095e * libmisc/copydir.c, configure.in: Check for the presence of
st_mtim and st_mtimensec, as for st_atim and st_atimensec.
2008-09-07 00:05:38 +00:00
nekral-guest
bab84a13ff Additional PAM cleanup:
* src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
	src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
	src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
	src/chsh.c: If the username cannot be determined, report it as
	such (not a PAM authentication failure).
2008-09-06 23:46:44 +00:00
nekral-guest
49f0d8b680 Support for blowfish was requested twice.
Add link to a patch for libxcrypt.
2008-09-06 22:52:35 +00:00
nekral-guest
4976708c00 * src/gpasswd.c: Document the long options in the usage. 2008-09-06 22:20:19 +00:00
nekral-guest
761cdf5dfc Remove done item:
- groupmems: 
  - need some work on add PAM and i18n support.
- userdel:
  - add lookop and remove per user group.
2008-09-06 21:53:12 +00:00
nekral-guest
2fb1dbfcd1 Remove done item:
PAM: add support for customization of the PAM support (i.e.
	support the Debian PAM configuration)
2008-09-06 21:50:15 +00:00
nekral-guest
8b3029e430 * NEWS: Added configure --enable-account-tools-setuid (default) /
--disable-account-tools-setuid options. This permits to disable
	the PAM authentication of the caller for chage, chgpasswd,
	chpasswd, groupadd, groupdel, groupmod, newusers, useradd,
	userdel, and usermod.  This authentication is not necessary when
	these tools are not installed setuid root.
2008-09-06 21:42:26 +00:00
nekral-guest
f8aef607ae * configure.in: Added option --enable-account-tools-setuid to
enable/disable the usage of PAM to authenticate the callers of
	account management tools: chage, chgpasswd, chpasswd, groupadd,
	groupdel, groupmod, useradd, userdel, usermod.
	* src/Makefile.am: Do not link the above tools with libpam if
	account-tools-setuid is disabled.
	* src/userdel.c, src/newusers.c, src/chpasswd.c, src/usermod.c,
	src/groupdel.c, src/chgpasswd.c, src/useradd.c, src/groupmod.c,
	src/groupadd.c, src/chage.c: Implement ACCT_TOOLS_SETUID
	(--enable-account-tools-setuid).
	* etc/pam.d/Makefile.am: Install the pam service file for the
	above tools only when needed.
	* src/useradd.c, src/userdel.c, src/usermod.c: It is no more
	needed to initialize retval to PAM_SUCCESS.
2008-09-06 21:35:37 +00:00
nekral-guest
bbae92e76f * libmisc/tz.c: tz() is only used when USE_PAM is not defined.
* lib/prototypes.h: Indicate functions whose presence depends on
	the USE_PAM flag.
2008-09-06 16:43:21 +00:00
nekral-guest
c89eb6d7eb * libmisc/tz.c: tz() is only used when USE_PAM is not defined.
* lib/prototypes.h: Indicate functions whose presence depends on
	the USE_PAM flag.
2008-09-06 16:42:41 +00:00
nekral-guest
70cf08329b * src/groupmems.c: Call open_files() and close_files().
* src/groupmems.c: Always call check_perms(), which takes care of
	checking if --list is used.
2008-09-06 16:27:21 +00:00
nekral-guest
a7b3bcb43c Fix typo. s/Prog/%s/ in the format string. 2008-09-06 16:00:00 +00:00
nekral-guest
18b7c8d188 * libmisc/obscure.c: Compare characters to '\0', not NULL. 2008-09-06 15:59:28 +00:00
nekral-guest
f34a638b38 * lib/defines.h: Do not include <config.h>. This complicate
undefining some configuration macros when the file is included
	multiple times.
	* libmisc/xgetXXbyYY.c, libmisc/xgetpwnam.c, libmisc/xgetpwuid.c,
	libmisc/xgetgrgid.c, libmisc/xgetgrnam.c, libmisc/xgetspnam.c:
	Include <config.h> from teh compiled C file, not the included
	getXXbyYY.c.
2008-09-06 15:58:23 +00:00
nekral-guest
e48fb58753 Remove DONE item. 2008-09-06 14:00:11 +00:00
nekral-guest
18fc4505d3 * src/userdel.c, src/newusers.c, src/chpasswd.c, src/chfn.c,
src/groupmems.c, src/usermod.c, src/groupdel.c, src/chgpasswd.c,
	src/useradd.c, src/groupmod.c, src/groupadd.c, src/chage.c,
	src/chsh.c: Simplify the PAM error handling. Do not keep the pamh
	handle, but terminate the PAM transaction as soon as possible if
	there are no PAM session opened.
2008-09-06 13:28:02 +00:00
nekral-guest
ee4e367ea8 * src/newgrp.c, src/userdel.c, src/grpck.c, src/gpasswd.c,
src/newusers.c, src/pwconv.c, src/chpasswd.c, src/logoutd.c,
	src/chfn.c, src/groupmems.c, src/usermod.c, src/pwunconv.c,
	src/expiry.c, src/groupdel.c, src/chgpasswd.c, src/useradd.c,
	src/su.c, src/groupmod.c, src/passwd.c, src/pwck.c,
	src/groupadd.c, src/chage.c, src/login.c, src/grpconv.c,
	src/groups.c, src/grpunconv.c, src/chsh.c: Prog is now global (not
	static to the file) so that it can be used by the helper functions
	of libmisc.
	* lib/prototypes.h: Added extern char *Prog.
	* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Indicate the
	program name with the warning.
2008-09-06 12:51:53 +00:00
nekral-guest
7034a913fd * configure.in: Check if AUDIT_ADD_USER, AUDIT_DEL_USER,
AUDIT_ADD_GROUP, and AUDIT_DEL_GROUP are defined in <libaudit.h>.
2008-09-04 22:34:20 +00:00
nekral-guest
e3ebd2c736 * src/useradd.c: Fix comment of lflg: it is also used for faillog. 2008-09-04 20:46:00 +00:00
nekral-guest
25d67da1da Updated TODO list. 2008-09-04 20:41:18 +00:00
nekral-guest
7e17182e4c * NEWS, src/groupmems.c, man/groupmems.8.xml: Document the long
options.
2008-09-04 20:20:20 +00:00
nekral-guest
7e0008a2d7 * lib/prototypes.h, libmisc/audit_help.c: Define new type
shadow_audit_result for the result argument of audit_logger().
	This permits stronger type checking and a better readability of
	the results (SHADOW_AUDIT_FAILURE/SHADOW_AUDIT_SUCCESS constants).
	* src/groupadd.c, src/groupdel.c, src/useradd.c, src/userdel.c:
	Use the SHADOW_AUDIT_FAILURE/SHADOW_AUDIT_SUCCESS results instead
	of 0 or 1 in audit_logger().
2008-09-04 19:36:27 +00:00
nekral-guest
a21809cdae * lib/prototypes.h, libmisc/audit_help.c: Define new type
shadow_audit_result for the result argument of audit_logger().
	This permits stronger type checking and a better readability of
	the results (SHADOW_AUDIT_FAILURE/SHADOW_AUDIT_SUCCESS constants).
	* src/groupadd.c, src/groupdel.c, src/useradd.c, src/userdel.c:
	Use the SHADOW_AUDIT_FAILURE/SHADOW_AUDIT_SUCCESS results instead
	of 0 or 1 in audit_logger().
2008-09-04 19:35:48 +00:00
nekral-guest
3dcaaf87e7 * src/userdel.c: Log failures to remove the mailbox to syslog and
audit.
	* src/userdel.c: Log successful removal of home directory to audit
	only in case of success.
	* src/userdel.c: Move the audit log of failure to remove the home
	directory before the call to function that may exit.
	* src/userdel.c: Document that errors is only used to count errors
	during the removal of the home directory.
2008-09-03 21:22:04 +00:00
nekral-guest
f3c7ca59c5 * src/useradd.c: Log errors to syslog in grp_update() since
changes have started to be reported to syslog.
	* src/userdel.c: Fix some result parameters sent to
	audit_logger().

	* NEWS: Following changes from a patch contributed by Steve Grubb
	<sgrubb@redhat.com>
	* src/groupadd.c: Log to audit with type AUDIT_ADD_GROUP instead
	of AUDIT_USER_CHAUTHTOK.
	* src/groupdel.c: Log to audit with type AUDIT_DEL_GROUP instead 
	of AUDIT_USER_CHAUTHTOK.
	* src/useradd.c: Log to audit with type AUDIT_ADD_USER /
	AUDIT_ADD_GROUP / AUDIT_USYS_CONFIG instead of
	AUDIT_USER_CHAUTHTOK.
	* src/useradd.c: Add missing logs to audit.
	* src/userdel.c: Log to audit with type AUDIT_DEL_USER /
	AUDIT_DEL_GROUP instead of AUDIT_USER_CHAUTHTOK.
	* src/userdel.c: Add missing logs to audit.
2008-09-03 21:02:32 +00:00
nekral-guest
ba98ffe152 Add Tobias' name. 2008-09-02 18:49:56 +00:00
nekral-guest
abddd42aa0 * src/groupmems.c: Remove duplicated gr_open(). 2008-08-31 17:41:03 +00:00
nekral-guest
118303b9da * man/useradd.8.xml: Document that -o is only valid with -u 2008-08-31 17:31:08 +00:00
nekral-guest
f74d7a9fd0 * man/useradd.8.xml: Document the /etc/default/useradd variables.
* man/useradd.8.xml: Fix the documentation of the GROUP variable
	(and -g/--gid option).
2008-08-31 17:31:00 +00:00
nekral-guest
12a9942732 Added TODO items for useradd. 2008-08-31 17:30:52 +00:00
nekral-guest
a109ff1d85 * shadow.spec.in: Fix the source (new FTP). 2008-08-31 17:30:45 +00:00
nekral-guest
3766b78eba Added TODO items.
Removed done items.
2008-08-31 17:30:37 +00:00
nekral-guest
614e95af39 * src/su.c: Add brackets and parenthesis.
* src/su.c: Avoid implicit conversion of pointers to booleans.
2008-08-31 17:30:30 +00:00
nekral-guest
05e4cf9aae * libmisc/list.c: Added assertions for non NULL parameters. 2008-08-31 17:30:21 +00:00
nekral-guest
d2c11f8bee * libmisc/list.c: Remove historical comment. 2008-08-31 17:30:12 +00:00
nekral-guest
c04189bfb6 * src/pwconv.c, src/pwunconv.c: Fail if unexpected parameters are
provided.
2008-08-31 17:30:00 +00:00
nekral-guest
6c5e97e745 * src/passwd.c: Add brackets and parenthesis.
* src/passwd.c: Avoid implicit conversion of pointers to booleans.
	* src/passwd.c: Avoid assignments in comparisons.
2008-08-31 17:29:51 +00:00
nekral-guest
687ae4f4a8 Finish the support for shadow groups. 2008-08-31 17:29:41 +00:00
nekral-guest
87b56b19fb * NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for
shadow groups.
	* src/groupmems.c: Use fail_exit() instead of exit().
2008-08-31 17:29:34 +00:00
nekral-guest
190a6e7687 re-indent. 2008-08-31 17:29:24 +00:00
nekral-guest
046fe0cfe0 * src/groupmems.c: Avoid mixed declarations and code. 2008-08-31 17:29:17 +00:00
nekral-guest
81e1dbc90e * src/groupmems.c: The grp structure returned by gr_locate is a
const. Duplicate this structure before working on it.
	* src/groupmems.c: Do not fail and do not display warnings if a
	close failure happens with the --list option. (Files are opened
	read-only).
2008-08-31 17:29:08 +00:00
nekral-guest
281721cd15 * src/gpasswd.c: Replace the 'valid' variable by is_valid to avoid
clashes with the valid() function.
2008-08-31 17:28:59 +00:00
nekral-guest
0fcae007a0 * libmisc/obscure.c: Add brackets and parenthesis.
* libmisc/obscure.c: Avoid implicit conversion of pointers / chars to
	booleans.
	* libmisc/obscure.c: Simplify the list of if.
2008-08-31 17:28:49 +00:00
nekral-guest
6b3266f228 * src/passwd.c: Fix a typo in the Usage string. 2008-08-31 17:28:39 +00:00
nekral-guest
ce4152c817 * src/logoutd.c: Fail if
unexpected parameters are provided.
2008-08-31 17:28:30 +00:00
nekral-guest
73877b22c4 * src/grpunconv.c: Fail if unexpected parameters
are provided.
	* src/grpunconv.c: Indicate that argc is not used
	in the no SHADOWGRP version.
2008-08-31 17:28:21 +00:00
nekral-guest
bf3e8f290c * src/grpconv.c, src/groups.c: Name the parameters in the
prototypes of the static functions.
	* src/grpconv.c: Fail if unexpected parameters are provided.
	* src/grpconv.c: Indicate that argc is not used in the no
	SHADOWGRP version.
2008-08-31 17:28:12 +00:00
nekral-guest
81a4edb776 Name the parameters in the prototypes of the static functions. 2008-08-31 17:28:03 +00:00
nekral-guest
399f453b4d * src/chgpasswd.c, src/chpasswd.c: Removed variable ok, which is
no more used.
2008-08-31 17:27:56 +00:00
nekral-guest
8e6c4b2e07 * src/chage.c: Fix the format for long integers (from %ul to %lu). 2008-08-31 17:27:47 +00:00
nekral-guest
4507bd32af * libmisc/utmp.c: Mark the line and host arguments of setutmp() as
not used in the __linux__ version.
2008-08-31 17:27:37 +00:00
nekral-guest
e9a14b2409 * lib/nscd.c: Avoid redefinition of _GNU_SOURCE. 2008-08-31 17:27:26 +00:00
nekral-guest
cd6a300222 * configure.in, src/login.c: Do not use HAVE_PAM_FAIL_DELAY, but
HAS_PAM_FAIL_DELAY, to avoid a redefinition with Linux PAM.
2008-08-31 17:27:16 +00:00
nekral-guest
978b3ef881 * configure.in: Indentation fix. 2008-08-31 17:27:06 +00:00
nekral-guest
da693710f6 Revert " * src/groupmems.c: Added function open_°files and close_files to"
This reverts commit eb3860eb3647d1b092ffe9baa1eb2f73a27a0d87.
2008-08-31 17:26:55 +00:00
nekral-guest
71656e3cba * src/groupmems.c: Added function open_°files and close_files to
ease the support of gshadow.
	* src/groupmems.c: Always call check_perms(). This function now
	succeed when the requested action is to list the members.
2008-08-30 18:34:43 +00:00
nekral-guest
72d75d50d9 * src/groupmems.c: Added functions add_user(), remove_user(), and
purge_members() to ease the support of gshadow.
2008-08-30 18:34:24 +00:00
nekral-guest
cdf963b2b3 * src/expiry.c: Use Basename for Prog.
* src/expiry.c: Added missing OPENLOG.
2008-08-30 18:34:04 +00:00
nekral-guest
6598f82111 Added brackets. 2008-08-30 18:33:37 +00:00
nekral-guest
de11907053 * lib/nscd.c: Make sure the file is not empty when configured
without nscd support.
2008-08-30 18:33:13 +00:00
nekral-guest
8075d27e32 * configure.in: Remove the USE_NSCD AM_CONDITIONAL (USE_NSCD is
not used in any Makefile.am).
	* configure.in: Make sure posix_spawn is present when configured
	with nscd support.
2008-08-30 18:32:43 +00:00
nekral-guest
7109072b8f * lib/groupmem.c, lib/pwmem.c, lib/shadowmem.c: Added brackets and
parenthesis.
	* lib/groupmem.c, lib/pwmem.c, lib/shadowmem.c: Avoid assignments
	in comparisons.
2008-08-30 18:32:19 +00:00
nekral-guest
cf4aea18b4 * libmisc/mail.c: Added brackets and parenthesis.
* libmisc/mail.c: Avoid assignments in comparisons.
2008-08-30 18:31:56 +00:00
nekral-guest
7bbaec8fed Added missing changes from last commit. 2008-08-30 18:31:35 +00:00
nekral-guest
68b7aad535 * configure.in: Check if the stat structure has a st_atim or
st_atimensec field.
	* libmisc/copydir.c: Conditionally use the stat's st_atim and
	st_atimensec fields.
2008-08-30 18:31:21 +00:00
nekral-guest
f86b2704d5 * lib/groupio.h, lib/prototypes.h, lib/pwio.h, lib/sgetgrent.c:
Include <sys/types.h> before <pwd.h> and <grp.h>. It is necessary
	for the definition of uid_t and gid_t.
	* lib/pwmem.c: do not include <pwd.h>, "pwio.h" is sufficient
	here.
2008-08-30 18:30:58 +00:00
nekral-guest
c59126a817 * configure.in, lib/nscd.h, lib/nscd.c: Added --with-nscd flag to
support systems without nscd.
2008-08-30 18:30:36 +00:00
nekral-guest
b4899946ef Added missing include file (assert.h). 2008-08-30 18:30:15 +00:00
nekral-guest
76ea48bb64 * NEWS: Added support for uclibc.
* configure.in, libmisc/copydir.c: futimes() and lutimes() are not
	standard. Check if they are implemented before using them. Do not
	set the time of links if lutimes() does not exist, and use
	utimes() as a replacement for futimes().
2008-08-30 18:29:55 +00:00
nekral-guest
0802405344 * src/groupmems.c: Handle the options alphabetically. 2008-08-30 18:29:31 +00:00
nekral-guest
0c7df2f9a0 * src/groupmems.c: When removing an user, check if deluser is on
the list, not adduser. This fixes a segmentation fault for every
	call of groupmems -d.
	* libmisc/list.c: Add assertions to help identifying these issues.
	* libmisc/list.c: Avoid implicit conversion of pointers to
	booleans.
2008-08-30 18:29:08 +00:00
nekral-guest
77f81fa0b6 * NEWS, src/groupmems.c: Use the "groupmems" PAM service name
instead of "groupmod".
2008-08-30 18:28:45 +00:00
nekral-guest
8851893412 * src/chfn.c: Merge some translated messages.
* src/groupmems.c, src/groupadd.c, src/gpasswd.c, src/chsh.c,
	src/chfn.c: Harmonize *_update() failure messages.
	* src/groupmems.c: Harmonize gr_close() failure messages.
	* src/newgrp.c: Harmonize "unknown GID" messages.
	* src/newusers.c: Move the pwd declaration to a inner block scope.
2008-08-30 18:28:24 +00:00
nekral-guest
aa2fee4969 * src/useradd.c: Harmonize some error messages.
* src/userdel.c: Add log to syslog when the mail file could not be
	removed.
	* src/userdel.c: Give more context an error message (merge with
	perror()).
	* src/usermod.c: Harmonize some error messages.
2008-08-30 18:27:59 +00:00
nekral-guest
d7b55ce2bb * src/groupmems.c: Check the return value of gr_update().
* src/chage.c, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
	src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupmems.c,
	src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
	src/passwd.c, src/pwck.c, src/pwconv.c, src/pwunconv.c,
	src/useradd.c, src/userdel.c, src/usermod.c: Harmonize the error
	message sent to stderr in case of *_update () failure.
	* src/chage.c, src/chsh.c, src/groupadd.c, src/passwd.c: Do not
	log to syslog when pw_update() or spw_update() fail.
	* src/newusers.c: Do not log specific error message to stderr when
	sgr_update() fails.
	* src/pwconv.c: Remove duplicated definition of Prog.
2008-08-30 18:27:34 +00:00
nekral-guest
38a50366bc * src/chfn.c, src/chsh.c, src/expiry.c, src/gpasswd.c,
src/newgrp.c, src/passwd.c, src/su.c: Use the same stderr and
	syslog warnings when the username cannot be determined.
	* src/newgrp.c: Reuse the same stderr message for groups which do
	not exist in the system.
2008-08-30 18:27:07 +00:00
nekral-guest
307f703b99 * src/usermod.c: Log errors while *_close to syslog.
* src/usermod.c: Added missing }
2008-08-22 02:34:04 +00:00
nekral-guest
306f19b805 * src/grpconv.c: Use Basename for the definition of Prog. Prog
needs a file visibility.
	* src/grpunconv.c: Likewise.
2008-08-22 02:33:08 +00:00
nekral-guest
421085672b Fix typos. 2008-08-22 02:31:55 +00:00
nekral-guest
b6dc6082ab Fix a typo (sgr_dbmane -> sgr_dbname) 2008-08-22 02:31:15 +00:00
nekral-guest
a3be8ff055 * src/chfn.c: Do not exit on pw_unlock failures.
* src/grpconv.c, src/grpunconv.c, src/pwconv.c, src/pwunconv.c,
	src/vipw.c: Open syslog with the right identification name.
	* src/vipw.c: Log unlock errors to syslog.
	* src/vipw.c: Log edits to syslog.
	* src/chage.c, src/chfn.c, src/chsh.c, src/gpasswd.c,
	src/groupadd.c, src/groupdel.c, src/groupmod.c, src/grpconv.c,
	src/grpunconv.c, src/passwd.c, src/pwck.c, src/pwunconv.c,
	src/useradd.c, src/usermod.c: Harmonize the syslog levels. Failure
	to close or unlock are errors. Failure to open files are warnings.
2008-08-22 02:30:33 +00:00
nekral-guest
c9119dc6bb * src/newusers.c: Open syslog with the right identification name.
* src/newusers.c: Mark the files as locked only if they are really
	locked (i.e. if shadow is not enabled, the files are not locked).
2008-08-22 02:29:31 +00:00
nekral-guest
cfeacc4d67 * NEWS, src/gpasswd.c: Use getopt_long instead of getopt. Added
support for long options --add (-a), --delete (-d),
	--remove-password (-r), --restrict (-R), --administrators (-A),
	and --members (-M)
	* man/gpasswd.1.xml: Document the new long options.
	* src/gpasswd.c: The sgrp structure is only used if SHADOWGRP is
	defined.
2008-08-22 02:28:15 +00:00
nekral-guest
7cc0389757 Remove done items. 2008-08-22 02:27:26 +00:00
nekral-guest
2bdcb9c33d * src/grpck.c: Added function fail_exit(). Check failure to unlock
files. Report errors to stderr and syslog, but continue.
	* src/grpconv.c: Check failure to unlock files. Report errors to
	stderr and syslog, but continue.
2008-08-22 02:26:46 +00:00
nekral-guest
7ae6b8fc34 * src/passwd.c: Check failure to unlock files. Report errors to
stderr and syslog, but continue.
2008-08-22 02:24:29 +00:00
nekral-guest
82779cd336 * src/chfn.c, src/chgpasswd.c, src/chpasswd.c, src/gpasswd.c,
src/groupadd.c, src/groupdel.c, src/groupmems.c, src/groupmod.c,
	src/grpconv.c, src/grpunconv.c, src/newusers.c, src/pwconv.c,
	src/pwunconv.c, src/useradd.c, src/userdel.c: Harmonize the name
	of the variables keeping the lock status, to match the shadow
	library prefixes.
2008-08-22 02:22:34 +00:00
nekral-guest
82ed690817 * src/chage.c, src/chgpasswd.c, src/chpasswd.c, src/chsh.c,
src/gpasswd.c, src/groupadd.c, src/groupdel.c, src/groupmems.c,
	src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
	src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
	src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c: In
	case of a lock failure, indicate to the user that she can try
	again later. Do not log to syslog.
2008-08-22 02:20:53 +00:00
nekral-guest
130553a578 Sort the NEWS entry alphabetically (per program name). 2008-08-22 02:18:48 +00:00
nekral-guest
1355d5d3eb * NEWS, src/passwd.c: For compatibility with other passwd version,
the --lock an --unlock options do not lock or unlock the user
	account anymore.  They only lock or unlock the user's password.
	* man/passwd.1.xml: Document above change. Document how an account
	can be locked and what a password lock means.
2008-08-22 02:16:21 +00:00
nekral-guest
fa33bb9d0e * man/groupadd.8.xml: Fix the regular expression for group policy.
The final $ character is optional.
	* man/groupadd.8.xml: Likewise.
	* man/groupadd.8.xml: Indicate the maximum size of usernames.
2008-08-15 15:25:53 +00:00
nekral-guest
0ebc407246 * man/po/pl.po: Fix typo in the Polish translation (see
http://bugs.debian.org/491460)
2008-08-15 15:25:23 +00:00
nekral-guest
2c950c5cb5 * man/pl/Makefile.am: Do not build the Polish translation of
login.1 and su.1 (not enough translated). See
	http://bugs.debian.org/491460
2008-08-13 06:55:55 +00:00
nekral-guest
2722e6bb68 * man/shadow.5.xml: Fix typo. The password must be changed before
the maximum number of days, not after.
2008-08-13 06:55:37 +00:00
nekral-guest
ce4e0b78bc Updated TODO file.
Added entries:
  * all: report nscd_flush_cache failures?
  * groupmems: Add support for gshadow
Removed entries:
  * groupmems: check reason for isgroup (function already removed)
2008-08-09 23:34:04 +00:00
nekral-guest
5d1795062f * src/groupmems.c: Harmonize the unlock failure messages. 2008-08-09 23:33:46 +00:00
nekral-guest
b6cc69cd8f * src/pwck.c: Added fail_exit().
* src/pwck.c: Report failure to unlock files to stderr and
	syslog.
	* src/pwck.c: Report failure to sort to stderr, and exit with
	E_CANTSORT.
	* man/pwck.8.xml: Document return code 6 (E_CANTSORT).
2008-08-09 23:33:26 +00:00
nekral-guest
10e78fbd8e * src/vipw.c: Report failures to remove files to stderr.
* src/vipw.c: Report failures to unlock files to stderr.
2008-08-09 23:31:36 +00:00
nekral-guest
e3e99974f8 * NEWS, src/groupmems.c: Added syslog support.
* src/groupmems.c: members() renamed display_members() to
	avoid name clash with its members argument.
	* src/groupmems.c: Report failure to unlock to syslog.
	* src/groupmems.c: Harmonize error messages.
	* src/groupmems.c: Report failures to write the new group file to
	syslog (gr_close() failure).
	* src/groupmems.c: Don't use fail_exit for non-failure exit.
2008-08-09 23:28:30 +00:00
nekral-guest
e069125a2c * src/chsh.c: Added fail_exit().
* src/chsh.c: Use fail_exit() instead of exit(), this avoid
	calling closelog() every times.
	* src/chsh.c: Ignore the return value or pam_end().
	* src/chsh.c: Simplify the PAM error handling.
	* src/chsh.c: Report failure to unlock files to stderr and
	syslog.
2008-08-09 23:27:50 +00:00
nekral-guest
0528803da6 Include missing exitcodes.h 2008-08-09 23:27:05 +00:00
nekral-guest
e5e00ce9d6 Improve commonalities between chgpasswd and chpasswd. 2008-08-09 23:25:49 +00:00
nekral-guest
69b276a712 * src/chpasswd.c: Added fail_exit().
* src/chpasswd.c: Added support for syslog.
	* src/chpasswd.c: Report failure to unlock files to stderr and
	syslog.
	* src/chpasswd.c: Simplify the PAM error handling.
	* src/chpasswd.c: Report failure during *_close() to syslog.
	* src/chpasswd.c: Ignore the return value or pam_end().
2008-08-09 23:25:18 +00:00
nekral-guest
5c04fe9b61 Added missing Prog. 2008-08-09 23:24:15 +00:00
nekral-guest
9c050c54ef Added missing Prog. 2008-08-09 23:23:44 +00:00
nekral-guest
3a07026740 Fix typo: missing O_RDWR parameter to *_open(). 2008-08-09 23:23:12 +00:00
nekral-guest
538db04950 * src/chgpasswd.c: Added fail_exit().
* src/chgpasswd.c: Added support for syslog.
	* src/chgpasswd.c: Report failure to unlock files to stderr and
	syslog.
	* src/chgpasswd.c: Simplify the PAM error handling.
	* src/chgpasswd.c: Report failure during *_close() to syslog.
	* src/chgpasswd.c: Ignore the return value or pam_end().
2008-08-09 23:22:00 +00:00
nekral-guest
e2b778a38e * src/userdel.c: Report failure to remove entries from group or
gshadow to stderr.
	* src/userdel.c: Fail in case of failure during the write of a
	user or group database. Report errors to syslog.
	* src/userdel.c: Do not unlock non locked files.
	* src/userdel.c: Report failure to unlock the passwd or shadow
	file to stderr and syslog.
2008-08-07 08:44:06 +00:00
nekral-guest
85bc9c1d1a * src/pwunconv.c: Report failure to unlock the passwd or shadow
file to stderr and syslog.
2008-08-07 08:03:55 +00:00
nekral-guest
501ae11f51 * src/usermod.c: Report failure to unlock the passwd or shadow
file to stderr and syslog.
2008-08-07 08:03:38 +00:00
nekral-guest
eb6cb5311b * src/newusers.c: Report failure to unlock the passwd or shadow
file to stderr and syslog.
	* src/newusers.c: In case of error when files are open or closed,
	indicate the failing file.
	* src/newusers.c: Do not try to unlock the files manually since
	this is done in fail_exit.
2008-08-07 08:03:13 +00:00
nekral-guest
e3a5f66059 * src/chage.c: Report failure to unlock the passwd or shadow file
to stderr and syslog.
2008-08-07 08:02:52 +00:00
nekral-guest
fd4b6cc52a * src/pwconv.c: Report failure to unlock the passwd or shadow file
to stderr and syslog.
	* src/pwconv.c: Report failure to chmod the backup file.
2008-08-07 08:02:34 +00:00
nekral-guest
93ccc35ff0 * src/grpunconv.c: Report failure to unlock the group or gshadow
files to stderr and syslog.
2008-08-07 08:02:13 +00:00
nekral-guest
ccc49e8841 * src/chfn.c: Added fail_exit(). Check if the passwd file is
locked. Report failures to unlock to stderr and syslog.
	* src/chfn.c: Is case of failure, use fail_exit() rather than
	exit().
	* src/chfn.c: Ignore the return value of pam_end().
2008-08-07 08:01:44 +00:00
nekral-guest
7fc596fb8a * lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
	Added *_dbname() functions to retrieve the name of the databases.
	* lib/groupio.c, lib/groupio.h, lib/pwio.c, lib/pwio.h,
	lib/sgroupio.c, lib/sgroupio.h, lib/shadowio.c, lib/shadowio.h:
	*_name() functions renamed *setname().
	* src/grpck.c, src/pwck.c: Likewise.
	* lib/groupio.h, lib/pwio.h, lib/sgroupio.h, lib/shadowio.h: Added
	the name of the arguments to the prototypes.
	* src/chage, src/chfn.c, src/chgpasswd.c, src/chpasswd.c,
	src/chsh.c, src/gpasswd.c, src/groupadd.c, src/groupdel.c,
	src/groupmod.c, src/grpck.c, src/grpconv.c, src/grpunconv.c,
	src/newusers.c, src/passwd.c, src/pwck.c, src/pwconv.c,
	src/pwunconv.c, src/useradd.c, src/userdel.c, src/usermod.c:
	Harmonize the erro & syslog messages in case of failure of the
	*_lock(), *_open(), *_close(), *_unlock(), *_remove() functions.
	* src/chgpasswd.c, src/chpasswd.c, src/usermod.c: Avoid
	capitalized messages.
	* src/chpasswd.c, src/useradd.c, src/usermod.c: Harmonize messages
	in case of inexistent entries.
	* src/usermod.c:  Harmonize messages in case of already existing
	entries.
	* src/newusers.c, src/useradd.c: Simplify PAM error handling.
	* src/useradd.c: Report failures to unlock files (stderr, syslog,
	and audit). But do not fail (continue).
	* src/useradd.c (open_files): Do not report to syslog & audit
	failures to lock or open the databases. This might be harmless,
	and the logs were not already informed that a change was
	requested.
	* src/usermod.c: It's not the account which is unlocked, but its
	password.
2008-08-06 15:57:31 +00:00
nekral-guest
b0fe7d3a0b * src/groupadd.c: Only call gr_unlock() and sgr_unlock() in the
group or gshadow files were previously locked.
	* src/groupadd.c: Make sure failures are reported to syslog/audit
	after the change is mentioned.
	* src/groupmod.c: Add logging to syslog & audit on lock/unlock
	failures.
	* src/groupmod.c: Make sure issues are reported to syslog or audit
	after the change is mentioned.
	* src/groupdel.c: Only call gr_unlock() and sgr_unlock() in the
	group or gshadow files were previously locked.
	* src/groupdel.c: Simplify the handling of PAM errors.
2008-08-06 15:56:51 +00:00
nekral-guest
6461841ccd * Merge two is_shadowgrp blocks.
* Indicate that we continue when *_unlock fail
2008-08-06 15:55:57 +00:00
nekral-guest
75e65f72c2 Re-indent. 2008-08-06 15:55:16 +00:00
nekral-guest
2cba7fdfcd * src/groupdel.c: Add logging to syslog & audit on lock/unlock
failures.
2008-08-06 15:54:49 +00:00
nekral-guest
9ddc88dd9d * src/groupdel.c: Harmonize error & syslog messages. 2008-08-06 15:54:16 +00:00
nekral-guest
bc8456425d * src/groupmod.c: Harmonize error & syslog messages. 2008-08-06 15:53:50 +00:00
nekral-guest
7eab6d9958 * src/groupadd.c: Harmonize error & syslog messages.
* src/groupadd.c: Add logging to syslog in some error cases.
2008-08-06 15:53:30 +00:00
nekral-guest
2bf3f0c03c * src/gpasswd.c: Warn and log to syslog and audit when group or
gshadow cannot be unlocked, but do not fail.
2008-08-06 15:52:42 +00:00
nekral-guest
9eea2344fc * src/gpasswd.c: Harmonize error & syslog messages. 2008-08-06 15:52:21 +00:00
nekral-guest
538600ef48 * src/chfn.c, src/chsh.c, src/groupdel.c, src/groupmems.c,
src/groupmod.c, src/grpck.c, src/login.c, src/logoutd.c,
	src/newgrp.c, src/newusers.c, src/passwd.c, src/pwck.c,
	src/suauth.c, src/useradd.c, src/userdel.c, src/usermod.c,
	src/vipw.c: Complete the switch from the `' quotation style to ''.
	Do it also in SYSLOG messages. Quote some parameters. All this
	permits to merge some messages.
2008-08-06 15:51:52 +00:00
nekral-guest
2ebd2a08ff Added Lukáš Kuklínek. 2008-07-31 16:50:59 +00:00
nekral-guest
6713942f83 * src/groupmems.c: Only check if the adduser user exists when an
user is specified with -a.
2008-07-30 14:11:09 +00:00
nekral-guest
c6f5ce280f * src/groupmems.c: Fix the groupmems' usage message. The -D option
is in fact -p.
2008-07-30 00:27:55 +00:00
nekral-guest
9aad7a3783 * src/groupmems.c: Replace an if test by an else. 2008-07-27 22:30:47 +00:00
nekral-guest
a22551d56b * src/groupmems.c: Ignore the return value of fputs(). 2008-07-27 22:30:39 +00:00
nekral-guest
d6f96fa07e * src/groupmems.c (whoami): Make sure usr and grp are not NULL
before dereferencing them.
2008-07-27 22:30:31 +00:00
nekral-guest
5a0715fd6c * src/groupmems.c: Use xstrdup() rather than strdup(). 2008-07-27 22:30:22 +00:00
nekral-guest
717110d355 * src/groupmems.c: Add parenthesis.
* src/groupmems.c: Avoid implicit conversion of pointers / chars to
	booleans.
2008-07-27 22:30:12 +00:00
nekral-guest
d5c6257ac2 * NEWS, src/groupmems.c: Allow everybody to list the users of a group.
This information is publicly available in /etc/group.
	* NEWS, src/groupmems.c: Open /etc/group read only for the -l option.
2008-07-27 02:33:37 +00:00
nekral-guest
88fce52fbf * man/groupmems.8.xml: Sort options alphabetically. 2008-07-27 02:11:32 +00:00
nekral-guest
8f3ee46325 Harmonize error messages and add the prototypes for whoami(), members(), and usage(). 2008-07-27 01:47:56 +00:00
nekral-guest
aa035f9853 * src/groupmems.c (check_perms): Simplify. Always call pam_end()
at the end of the authentication.
2008-07-27 01:41:07 +00:00
nekral-guest
b2f5629de8 * src/groupmems.c: Add fail_exit() to remove the group lock file
in case of failure. Replace the calls to exit() by fail_exit().
2008-07-27 01:35:08 +00:00
nekral-guest
db98798134 * src/groupmems.c: Reduce the number of checks. Isolate the
parameters setting and permissions checking.
2008-07-27 01:16:13 +00:00
nekral-guest
d4227e75cd * src/groupmems.c: Add functions process_flags() and check_perms()
from code of main().
	* src/groupmems.c: Harmonize the failure message in case of PAM
	failure with the other programs.
2008-07-27 00:59:42 +00:00
nekral-guest
e6c015e0d0 * src/groupmems.c: Remove isgroup(), which always returns TRUE. 2008-07-27 00:35:04 +00:00
nekral-guest
44db9db053 * src/groupmems.c: Reuse the functions from libmisc/list.c to deal
with user lists. addtogroup() was broken when realloc() move the
	memory area.
	* src/groupmems.c: Report failures with the name of the program.
2008-07-27 00:21:42 +00:00
nekral-guest
4c2ed7b52e * src/groupmems.c: EXIT_READ_GROUP changed to EXIT_INVALID_GROUP.
* src/groupmems.c: EXIT_INVALID_USERNAME changed to EXIT_INVALID_USER.
	* src/groupmems.c: Fix typos.
2008-07-27 00:11:25 +00:00
nekral-guest
6f571dbfc6 * src/groupmems.c: Really use booleans.
* src/groupmems.c: Change isroot() to a macro that returns a
	boolean.
2008-07-26 16:24:27 +00:00
nekral-guest
a363e1c51f * lib/defines.h: Make sure the booleans are defined before using
them.
2008-07-26 16:13:29 +00:00
nekral-guest
b684ea837d 2008-07-26 Nicolas François <nicolas.francois@centraliens.net>
* src/groupmems.c: Added Prog global variable to indicate the name
	of the program in error messages.

2008-07-22  Lukáš Kuklínek  <lkukline@redhat.com>

	* NEWS, src/groupmems.c: Check if the user added to group actually
	exist. RedHat bug #455603
	* NEWS, src/groupmems.c: Check if the group exists in the group
	local database (/etc/group). RedHat bug #456088
2008-07-26 16:11:49 +00:00
nekral-guest
d4eced9b84 * lib/prototypes.h: Fix getrange prototype. 2008-07-21 22:45:49 +00:00
nekral-guest
a674a2e6fd Re-indent. 2008-07-21 22:45:08 +00:00
nekral-guest
276e406c0f * README, NEWS, configure.in, lib/pam_defs.h, src/login.c: Add
support for OpenPAM.
2008-07-21 21:14:06 +00:00
nekral-guest
7ac0323c7b * src/chage.c: Ignore the return value of pam_end() before exiting.
* src/chage.c: Ignore return values of strftime(), snprintf(),
	puts(), printf(), and fputs().
	* src/chage.c: Check the return value of asctime().
2008-07-11 22:31:43 +00:00
nekral-guest
95c78ce92b * lib/gshadow.c: Avoid assignments in comparison. 2008-07-11 22:23:42 +00:00
nekral-guest
21c692d23f Re-inject the changes from 4.1.2.1. 2008-07-11 22:20:43 +00:00
nekral-guest
5b194e290c Fix typo. 2008-07-11 22:04:02 +00:00
nekral-guest
22fb4fe019 * src/usermod.c: Do not call usr_update() if it will have no
effects. This avoid checking if the user exists in the local passwd
	file if not necessary, and thus allow to add LDAP users to local
	groups. (The user is already checked against the system
	configuration with getpwnam()). Thanks to Dan Kopecek.
2008-07-11 21:50:05 +00:00
nekral-guest
62c8e79676 * src/usermod.c: Split update_files() into update_lastlog() and
update_faillog(). Report errors (but don't fail) if the file
	exist, but open(), lseek(), read(), write(), or close() fails.
	* src/usermod.c: Add brackets and parenthesis.
	* src/usermod.c: Ignore the return value of pam_end() before
	exiting.
	* src/usermod.c: Ignore the return value of strftime(),
	snprintf(), and puts().
	* src/usermod.c: Check the return value of gmtime() and asctime(),
	and output the raw time_t on failures.
2008-07-11 20:52:44 +00:00
nekral-guest
e4e3bd5175 * libmisc/setugid.c: Add brackets. 2008-07-11 20:23:07 +00:00
nekral-guest
eb18ee624f Re-indent. 2008-06-17 22:00:36 +00:00
nekral-guest
6298ca94cb * libmisc/env.c: Avoid implicit conversion of pointers / chars to
booleans.
	* libmisc/env.c: Add brackets and parenthesis.
	* libmisc/env.c: Ignore the return value of puts() and fputs().
	* libmisc/env.c: Avoid multi-statements lines.
2008-06-17 21:58:46 +00:00
nekral-guest
7c9270d7a5 Re-indent. 2008-06-17 21:17:45 +00:00
nekral-guest
5f9226b14b * libmisc/utmp.c: Avoid implicit conversion of pointers / chars to
booleans.
	* libmisc/utmp.c: Add brackets and parenthesis.
	* libmisc/utmp.c: Exit with the EXIT_FAILURE status code in case
	of failure.
	* libmisc/utmp.c: Avoid assignments in comparisons.
	* lib/prototypes.h, libmisc/utmp.c: Change setutmp()'s prototype
	to return an int because pututline() and pututxline() may fail.
2008-06-17 21:13:30 +00:00
nekral-guest
9320075030 * libmisc/audit_help.c: Added one string for translation.
* po/POTFILES.in: Added libmisc/audit_help.c,
	libmisc/find_new_gid.c, libmisc/find_new_uid.c, libmisc/getlong.c,
	libmisc/getrange.c, libmisc/xgetXXbyYY.c, and libmisc/yesno.c.
	Removed libmisc/find_new_ids.c
2008-06-17 20:52:19 +00:00
nekral-guest
ca032792bd * src/useradd.c: If the faillog file exist, warn in case of
failure when open(), lssek(), write() or close() fails when the
	new user's faillog entry is reset.
	* src/useradd.c: Ditto for the lastlog entry.
2008-06-15 22:25:51 +00:00
nekral-guest
abb95d5aab * libmisc/limits.c: Add brackets and parenthesis.
* libmisc/limits.c: Avoid implicit conversion of pointers /
	integers to booleans.
	* libmisc/limits.c: Ignore the return value of umask(). We will
	never return to the original umask.
	* libmisc/limits.c: Avoid multi-statements lines.
	* libmisc/limits.c: Added default to a switch(). Report invalid
	limit strings to syslog.
	* libmisc/limits.c: Ignore the return value of fclose().
	/etc/limits is open read-only.
	* libmisc/limits.c: Ignore the return value of fputs() and
	sleep().
	* libmisc/limits.c: Check the return value of nice() and
	set_filesize_limit(), and report errors to syslog.

	* libmisc/ulimit.c, lib/prototypes.h: Return failures of
	set_filesize_limit(). Change the prototype to return an int
	instead of void.
2008-06-15 21:59:41 +00:00
nekral-guest
dcd480ffd9 * libmisc/failure.c: Try to close the open file if a failure
occured during lseek(), read() or write().
2008-06-15 19:16:34 +00:00
nekral-guest
68cdac68cb * libmisc/log.c: Check return values. If lseek() failed, avoid
reading or writing at an unspecified location. Log to syslog in
	case of failure.
	* libmisc/log.c: Use the right casts.
2008-06-15 19:15:15 +00:00
nekral-guest
e1307ea789 * libmisc/find_new_ids.c, libmisc/find_new_gid.c,
libmisc/find_new_uid.c, libmisc/Makefile.am, lib/prototypes.h:
	Split find_new_ids.c into find_new_gid.c and find_new_uid.c to
	ease the description of login.defs variables in the different
	tools.
2008-06-15 18:33:52 +00:00
nekral-guest
52fe9f62f6 * libmisc/failure.c: Ignore the return value of strftime() and
printf().
	* libmisc/failure.c: Fix syslog call. The UID is not available.
	User the username specified in the utmp/utmpx entry.
2008-06-15 00:01:46 +00:00
nekral-guest
f42160862a * lib/defines.h: Avoid implicit conversion of pointers to
booleans.
	* lib/defines.h: Ignore return values of setlocale() except the
	first call.
	* lib/defines.h: Fix a splint observer warning by using an
	intermediate variable (old_locale).
2008-06-14 23:41:38 +00:00
nekral-guest
1b631c42ef * libmisc/failure.c: Check return values. If lseek() failed, avoid
reading or writing at an unspecified location. Log to syslog in
	case of failure when reading a faillog entry or writing in
	faillog or btmp.
	* libmisc/failure.c: Check if the file exist before opening it.
	* libmisc/failure.c: Log failures of open() and close() when
	necessary.
2008-06-14 23:38:43 +00:00
nekral-guest
0afd6a8312 * lib/prototypes.h: Add the getrange() prototype.
* lib/prototypes.h: Fix the valid_field() prototype (does not
	return an bool).
	* lib/prototypes.h: Fix the valid() prototype (it does return a
	bool).
2008-06-14 21:11:19 +00:00
nekral-guest
4ac21ca652 * lib/getdef.c: Fix the getdef_ulong() prototype.
* lib/getdef.h: Fix the getdef_ulong() prototype.
2008-06-14 21:09:33 +00:00
nekral-guest
dbbae8dcd3 * src/lastlog.c: Use getrange to parse the range of users.
* src/lastlog.c: umin and umax do not need to be signed long. Use
	an unsigned long which might be needed to parse a GID or UID. Add
	the has_umin and has_umax to replace the -1 values.
	* src/lastlog.c: Cast dates to time_t.
	* src/lastlog.c: Prefix lastlog errors with "lastlog: ".
2008-06-14 21:06:53 +00:00
nekral-guest
eed5fc7179 * libmisc/getlong.c: Reset errno before calling strtol().
Otherwise, errno could be already set to ERANGE.
2008-06-14 21:02:52 +00:00
nekral-guest
b8c5483b85 * libmisc/Makefile.am, libmisc/getrange.c: Added function to parse
a range (useful for lastlog).
2008-06-14 21:01:11 +00:00
nekral-guest
4f12c31e3b * src/chsh.c: <signal.h> is not needed. 2008-06-14 15:03:58 +00:00
nekral-guest
53543b9b6a * lib/prototypes.h: Define AUDIT_NO_ID to (unsigned int) -1. This
value should be used when the ID should not be considered.
	* lib/prototypes.h: Fix the prototype of do_rlogin() according to
	earlier changes.
2008-06-13 21:57:47 +00:00
nekral-guest
afafd0f683 * lib/shadow.c: Use SHADOW_SP_FLAG_UNSET for the initial
value of spwd.sp_flag.
	* lib/shadow.c: Add brackets.
	* lib/shadow.c: Avoid implicit conversion of pointers to
	booleans.
	* lib/shadow.c: The size argument of fgets is an int, not a
	size_t.
2008-06-13 21:55:51 +00:00
nekral-guest
d65354efcf * lib/commonio.c: len should be typed ssize_t as it is the return
of read(), and is compared to 0. Cast to size_t when necessary.
2008-06-13 21:53:41 +00:00
nekral-guest
d3abd86df5 * libmisc/find_new_ids.c: Use getdef_ulong to retrieve UIDs/GIDs
from login.defs. Type constants to long integers.
2008-06-13 21:49:57 +00:00
nekral-guest
838f39d0fd * lib/gshadow.c: Use a bool when possible instead of int integers.
* lib/gshadow.c: Remove __setsgNIS() -never used).
	* lib/gshadow.c: Avoid multi-statements lines.
	* lib/gshadow.c: Avoid assignments in comparisons.
	* lib/gshadow.c: ptr[nelem] is a string. Initialize it to NULL
	instead of '\0'.
	* lib/gshadow.c: Add brackets and parenthesis.
	* lib/gshadow.c: The size argument of strncpy is a size_t and the
	size argument of fgets is an int.
2008-06-13 21:45:47 +00:00
nekral-guest
4589ba350f * lib/groupio.c: Add brackets.
* lib/groupio.c: Make sure malloc receives a size_t.
	* lib/groupio.c: Avoid multi-statements lines.
2008-06-13 21:39:24 +00:00
nekral-guest
92143eb7b9 * lib/sgetspent.c: Use SHADOW_SP_FLAG_UNSET for the initial
value of spwd.sp_flag.
2008-06-13 21:36:41 +00:00
nekral-guest
c9679b7954 * lib/getdef.h, lib/getdef.c: Add getdef_ulong().
* lib/getdef.c: Added TODOs because of lack of error checking.
	* lib/getdef.c: The size argument of fgets is an int, not a
	size_t.
	* lib/getdef.c: Avoid multi-statements lines.
2008-06-13 21:35:22 +00:00
nekral-guest
5fc99a117b * src/id.c: Make sure malloc receives a size_t.
* src/id.c: Use a %lu format and cast group and user IDs to
	unsigned long integers.
2008-06-13 21:31:23 +00:00
nekral-guest
87ba782106 * src/sulogin.c: Ignore the return value of signal(). 2008-06-13 21:30:09 +00:00
nekral-guest
dd8a09ce8d * src/groups.c: sys_ngroups is only used when HAVE_GETGROUPS is
defined.
2008-06-13 21:29:13 +00:00
nekral-guest
ba7dde0168 * src/faillog.c: Ignore return value of time() when use with a
non NULL argument.
	* src/faillog.c: Use a %lu format and cast number of days to
	unsigned long integers.
	* src/faillog.c: Cast dates to time_t.
2008-06-13 21:28:11 +00:00
nekral-guest
3a03794bb6 * src/login.c: Ignore the return value of signal().
* src/login.c: Use a %lu format and cast group and user IDs to
	unsigned long integers.
	* src/login.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-13 21:25:15 +00:00
nekral-guest
fe753e24a3 * src/chage.c: Add the arguments' names in the functions
prototypes.
	* src/chage.c: The ID argument of audit_logger is an unsigned
	int. Use AUDIT_NO_ID instead of -1.
	* src/chage.c: print_date() received a time_t.
	* src/chage.c: Use SHADOW_SP_FLAG_UNSET for the initial
	value of spwent.sp_flag.
2008-06-13 21:23:09 +00:00
nekral-guest
42a4604461 * src/groupadd.c: The ID argument of audit_logger is an unsigned
int. Use AUDIT_NO_ID instead of -1.
	* src/groupadd.c: Cast the parsed GID/UID to a gid_t/uid_t.
2008-06-13 21:19:07 +00:00
nekral-guest
a70898fc28 * src/pwck.c: Use a %lu format and cast group and user IDs to
unsigned long integers.
	* src/pwck.c: Cast number of days to a long integer.
	* src/pwck.c: Use the SCALE macro instead of (24L * 3600L)
	for the values to be set in /etc/shadow.
	* src/pwck.c: Use SHADOW_SP_FLAG_UNSET for the initial
	value of spent.sp_flag.
2008-06-13 21:16:01 +00:00
nekral-guest
186eef69dc * src/passwd.c: Ignore return value of time() when use with a
non NULL argument.
	* src/passwd.c: Cast number of days to a long integer.
2008-06-13 21:09:14 +00:00
nekral-guest
c3a380ade8 * src/groupmod.c: The ID argument of audit_logger is an unsigned
int. Use AUDIT_NO_ID instead of -1.
	* src/groupmod.c:  Use a %lu format and cast group and user IDs to
	unsigned long integers.
	* src/groupmod.c: Cast the parsed GID/UID to a gid_t/uid_t.
2008-06-13 21:08:06 +00:00
nekral-guest
936bd6a191 * src/useradd.c: The ID argument of audit_logger is an unsigned
int. Use AUDIT_NO_ID instead of -1.
	* src/useradd.c: Cast the parsed GID/UID to a gid_t/uid_t.
	* src/useradd.c: The size argument of fgets is an int, not a
	size_t.
	* src/useradd.c: Cast number of days to a long integer.
	* src/useradd.c: Use SHADOW_SP_FLAG_UNSET for the initial
	value of spent.sp_flag.
	* src/useradd.c: Use a %lu format and cast group and user IDs to
	unsigned long integers.
2008-06-13 21:06:04 +00:00
nekral-guest
73d36f5ece Fix typo. 2008-06-13 21:02:26 +00:00
nekral-guest
00431d772e * src/su.c: fork() and waitpid() return a pid_t, not an int.
* src/su.c: Add brackets and parenthesis.
	* src/su.c: Ignore the return value of signal().
2008-06-13 21:02:07 +00:00
nekral-guest
a22c7e731a * src/groupdel.c: The ID argument of audit_logger is an unsigned
int. Use AUDIT_NO_ID instead of -1.
2008-06-13 20:59:04 +00:00
nekral-guest
398cf8ee6f * src/expiry.c: Ignore the return value of signal(). 2008-06-13 20:57:20 +00:00
nekral-guest
e50ff5c7b5 * src/newusers.c: Fix the check for GID/UID validity.
* src/newusers.c: Comment why we use both getgrgid() and
	gr_locate_gid().
	* src/newusers.c: Cast the parsed GID/UID to a gid_t/uid_t.
	* src/newusers.c: Cast the number of days to a long integer.
	* src/newusers.c: Use SHADOW_SP_FLAG_UNSET for the initial
	value of spent.sp_flag.
	* src/newusers.c: The size argument of fgets is an int, not a
	size_t.
2008-06-13 20:56:44 +00:00
nekral-guest
906e8c0001 * src/usermod.c: Cast dates to time_t, and number of days to a
long integer.
	* src/usermod.c: Cast UIDs and GIDs to uid_t and gid_t after
	checking the ranges.
	* src/usermod.c: The ID argument of audit_logger is an unsigned
	int.
	* src/usermod.c: read() returns a ssize_t.
	* src/usermod.c: Cast the return value of malloc and make sure it
	receives a size_t.
2008-06-13 20:40:04 +00:00
nekral-guest
2fa4cedb1e * src/logoutd.c: Ignore return value of time() when use with a
non NULL argument.
2008-06-13 20:34:46 +00:00
nekral-guest
47210d9a1a * src/pwconv.c: Use SHADOW_SP_FLAG_UNSET for the initial
value of sp.sp_flag.
	* src/pwconv.c: Cast number of days to a long integer.
2008-06-13 20:33:38 +00:00
nekral-guest
d1881d1b56 * src/gpasswd.c: The ID argument of audit_logger is an unsigned
int.
	* src/gpasswd.c: Ignore the return value of signal(). The signal
	handlers are only changed for the last steps of gpasswd, and there
	is no need to restore them.
2008-06-13 20:29:58 +00:00
nekral-guest
6713a2ce67 * src/userdel.c: The ID argument of audit_logger is an unsigned
int.
	* src/userdel.c: fork() and wait() return a pid_t, not an int.
2008-06-13 20:23:26 +00:00
nekral-guest
f626317e90 * src/newgrp.c: Use a %lu format and cast group and user IDs to
unsigned long integers.
	* src/newgrp.c: The ID argument of audit_logger is an unsigned
	int.
	* src/newgrp.c: Ignore the return value of signal() (the signal
	handlers are assumed to be the default one and are restored
	later).
	* src/newgrp.c: Do not checl if a pid_t is < 0, check if equal
	to (pid_t)-1.
2008-06-13 20:21:24 +00:00
nekral-guest
56327f6298 * libmisc/isexpired.c: Cast number of days to a long integer.
* libmisc/isexpired.c: Add brackets and parenthesis.
2008-06-13 20:12:03 +00:00
nekral-guest
7d05c4a2b0 * libmisc/copydir.c: Do not specify a size of arrays in the
prototypes.
	* libmisc/copydir.c: Use a size_t for the length of strings.
	* libmisc/copydir.c: Cast the return value of malloc().
	* libmisc/copydir.c: The size argument of write() is a size_t.
2008-06-13 20:10:53 +00:00
nekral-guest
232bcafd7c * libmisc/pwd2spwd.c: Cast number of days to a long integer.
* libmisc/pwd2spwd.c: Use SHADOW_SP_FLAG_UNSET for the initial
	value of sp.sp_flag.
2008-06-13 20:08:33 +00:00
nekral-guest
c82cfebd5e * lib/defines.h: Include <config.h> since it uses the macro that
might be defined in this header file.
	* lib/defines.h: Prefer checking if HAVE_LOCALE_H or ENABLE_NLS
	are defined (rather than set to non 0).
	* lib/defines.h: The dummy implementations of bindtextdomain() and
	textdomain() should return a pointer. Return NULL instead of
	/* empty */
	* lib/defines.h: Define SHADOW_SP_FLAG_UNSET, to be used for the
	initialization of sp_flag field of the shadow structures.
	* lib/defines.h: Define LC_ALL, needed even if HAVE_LOCALE_H is
	not defined.
2008-06-13 20:05:51 +00:00
nekral-guest
07a6bcaa77 * libmisc/sulog.c: Ignore the return value of umask() when the
mask is restored.
	* libmisc/sulog.c: Add brackets.
	* libmisc/sulog.c: Ignore return value of time() when use with a
	non NULL argument.
2008-06-13 19:52:58 +00:00
nekral-guest
fe0e4f635e * libmisc/log.c: Avoid assignments in comparisons.
* libmisc/log.c: Add brackets and parenthesis.
	* libmisc/log.c: read() returns a ssize_t (note size_t).
	* libmisc/log.c: Avoid implicit conversion of pointers to
	booleans.
	* libmisc/log.c: Ignore return value of time() when use with a
	non NULL argument.
2008-06-13 19:50:49 +00:00
nekral-guest
815ffb7d3e * libmisc/strtoday.c: Avoid implicit conversion of pointers to
booleans.
	* libmisc/strtoday.c: Add brackets and parenthesis.
2008-06-13 19:48:11 +00:00
nekral-guest
7f8c48834f * libmisc/salt.c: Use a size_t for the size of strings instead of
unsigned int.
	* libmisc/salt.c: Add brackets and parenthesis.
	* libmisc/salt.c: Avoid assignments in comparisons.
2008-06-13 19:37:15 +00:00
nekral-guest
0a6ce91369 * libmisc/age.c: fork() and wait return a pid_t, not an int.
* libmisc/age.c: Avoid implicit conversion of pointers to
	booleans.
	* libmisc/age.c: Avoid assignments in comparisons.
	* libmisc/age.c: Ignore the return value of printf(), puts(),
	fputs() and fflush().
	* libmisc/age.c: Add brackets and parenthesis.
	* libmisc/age.c: Cast the return value of time() to long and
	converted to a date.
2008-06-13 19:24:27 +00:00
nekral-guest
71dda8b648 * libmisc/rlogin.c: The size argument of read() is a size_t.
Propagate this time to the callers (the get_remote_string() and
	do_rlogin() functions).
	* libmisc/rlogin.c: Add brackets and parenthesis.
	* libmisc/rlogin.c: Avoid multi-statements lines.
	* libmisc/rlogin.c: Avoid assignments in comparisons.
	* libmisc/rlogin.c: Avoid implicit conversion of pointers to
	booleans.
2008-06-13 18:34:27 +00:00
nekral-guest
2296db3db6 * libmisc/failure.c: Avoid assignments in comparisons.
* libmisc/failure.c: read() returns a ssize_t.
	* libmisc/failure.c: Add brackets and parenthesis.
	* libmisc/failure.c: Ignore return value of time() when use with a
	non NULL argument.
2008-06-13 18:31:13 +00:00
nekral-guest
1e798b640d * libmisc/chowntty.c: Avoid assignments in comparisons.
* libmisc/chowntty.c: Avoid implicit conversion of pointers to
	booleans.
	* libmisc/chowntty.c: Add brackets and parenthesis.
2008-06-13 18:29:02 +00:00
nekral-guest
e91899c0da * libmisc/audit_help.c: Add brackets. 2008-06-13 18:24:37 +00:00
nekral-guest
6099bda088 * libmisc/addgrps.c: Avoid implicit conversion of pointers to
booleans.
	* libmisc/addgrps.c: Add brackets.
2008-06-13 18:19:34 +00:00
nekral-guest
43e4d608ae * libmisc/utmp.c: Avoid implicit conversion of pointers to
booleans
+ add missing changelog from last commit.
2008-06-13 18:17:10 +00:00
nekral-guest
ef32209fd7 * libmisc/console.c, libmisc/hushed.c, libmisc/yesno.c,
libmisc/loginprompt.c, libmisc/ttytype.c, libmisc/tz.c,
	src/login_nopam.c, src/chpasswd.c, src/chgpasswd.c, lib/port.c:
	The size argument of fgets is an int, not a size_t.
	* libmisc/loginprompt.c: Ignore the return value from signal()
	when the signal handlers are restored.
	* src/chpasswd.c: Cast the return value of time() to a long
	integer.
	* src/chpasswd.c: Use the SCALE macro instead of (24L * 3600L)
	for the values to be set in /etc/shadow.
2008-06-13 18:11:09 +00:00
nekral-guest
55b2e44814 Avoid implicit conversion of pointers to booleans. 2008-06-10 22:10:47 +00:00
nekral-guest
6bb86709ee Add brackets. 2008-06-10 22:10:21 +00:00
nekral-guest
ce6dca81bc * src/pwck.c: Use a bool when possible instead of int integers.
* src/pwck.c: Avoid implicit conversion of integers to booleans.
2008-06-10 22:09:12 +00:00
nekral-guest
d7ffaf94b1 * src/su.c: Use a bool when possible instead of int integers.
* src/su.c: Add brackets and parenthesis.
	* src/su.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/su.c: Ignore the return value of pam_end() before
	exiting.
	* src/su.c: Avoid assignments in comparisons.
	* src/su.c: Avoid multi-statements lines.
2008-06-10 22:07:51 +00:00
nekral-guest
c573f432fe * lib/prototypes.h, libmisc/valid.c: Change the prototype of
valid() to return a bool.
	* libmisc/valid.c: Add parenthesis.
2008-06-10 21:52:34 +00:00
nekral-guest
7cb33ba636 Avoid implicit conversion of integer to boolean. 2008-06-10 20:34:25 +00:00
nekral-guest
182731d6eb * lib/commonio.c: Add brackets and parenthesis.
* lib/commonio.c: Check the result of fgets().
	* lib/commonio.c: Avoid implicit conversion of pointers to
	booleans.
2008-06-10 20:27:16 +00:00
nekral-guest
f79fd32208 * lib/prototypes.h: Fix the prototypes to match earlier changes. 2008-06-10 20:02:47 +00:00
nekral-guest
b3c68f1692 Fix typo. Compil fix. 2008-06-10 20:02:12 +00:00
nekral-guest
ef1a2a82dd * lib/nscd.c: Include defines.h.
* lib/nscd.c: Always warn when the nscd cache cannot be flushed.
	* lib/nscd.c: Avoid assignments in comparisons.
	* lib/nscd.c: Ignore the return value of fputs() when printing
	errors.
2008-06-10 20:01:55 +00:00
nekral-guest
269d4c55dd * lib/port.c: Add brackets and parenthesis.
* lib/port.c: Change isttytime() prototype to return a bool.
	* lib/port.c: Ignore the return value of fclose () (file open
	read-only).
	* lib/port.c: Avoid multi-statements lines.
2008-06-10 19:59:26 +00:00
nekral-guest
91c8e1bf0d * src/id.c: Ignore the return value of fputs(), puts(), putchar(),
and printf().
	* src/id.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/id.c: Add brackets and parenthesis.
	* src/id.c: Avoid implicit conversion of pointers / integers
	to booleans.
2008-06-10 19:45:06 +00:00
nekral-guest
c8626c09af * src/chsh.c: Use a bool when possible instead of int integers.
* src/chsh.c: restricted_shell() renamed is_restricted_shell().
	check_shell() renamed shell_is_listed().
	* src/chsh.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/chsh.c: Avoid implicit conversion of pointers / integers
	to booleans.
	* src/chsh.c: Ignore the return value of pam_end() before
	exiting.
2008-06-10 19:42:22 +00:00
nekral-guest
cac7d1a495 * src/grpunconv.c: Use a bool when possible instead of int
integers.
	* src/grpunconv.c: Add brackets and parenthesis.
	* src/grpunconv.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/grpunconv.c: Avoid implicit conversion of pointers / integers
	to booleans.
2008-06-10 19:39:18 +00:00
nekral-guest
3cbda4157b * src/sulogin.c: Ignore return value of setlocale(),
bindtextdomain(), and textdomain().
	* src/sulogin.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/sulogin.c: Avoid assignments in comparisons.
	* src/sulogin.c: Ignore the return value of alarm().
2008-06-10 19:36:05 +00:00
nekral-guest
46ce06791a * src/groups.c: Use a bool when possible instead of int integers.
* src/groups.c: Add brackets and parenthesis.
	* src/groups.c: Avoid implicit conversion of pointers / integers
	to booleans.
	* src/groups.c: Avoid assignments in comparisons.
	* src/groups.c: Ignore the return value of putchar(), printf()
	* src/groups.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-10 19:29:54 +00:00
nekral-guest
462e8a3d90 re-indent. 2008-06-10 19:18:44 +00:00
nekral-guest
cd9e4d1b2b * src/grpconv.c: Use a bool when possible instead of int integers.
* src/grpconv.c: Add brackets and parenthesis.
	* src/grpconv.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/grpconv.c: Avoid implicit conversion of pointers / integers
	to booleans.
2008-06-10 19:18:34 +00:00
nekral-guest
e31af5f255 * src/faillog.c: Use a bool when possible instead of int integers.
* src/faillog.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/faillog.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/faillog.c: Add brackets and parenthesis.
2008-06-10 19:16:02 +00:00
nekral-guest
a0dae7557c * src/login.c: Avoid multi-statements lines.
* src/login.c: Ignore the return value of pam_end() before
	exiting.
	* src/login.c: Use a bool when possible instead of int integers.
	* src/login.c: Add brackets and parenthesis.
	* src/login.c: Ignore the return values of fflush(), putchar(), puts().
	* src/login.c: Ignore the return value of fclose() for read-only
	files.
	* src/login.c: Avoid assignments in comparisons.
	* src/login.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-10 18:56:23 +00:00
nekral-guest
836bf643b0 * src/chage.c: Use a bool when possible instead of int integers.
* src/chage.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-10 17:56:53 +00:00
nekral-guest
f9e4c7ca02 * src/groupadd.c: Use a bool when possible instead of int
integers.
	* src/groupadd.c: Add brackets and parenthesis.
	* src/groupadd.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/groupadd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/groupadd.c: Ignore the return value of pam_end() before
	exiting.
2008-06-10 17:53:35 +00:00
nekral-guest
a31782497c * src/pwck.c: Use a bool when possible instead of int integers.
* src/pwck.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-10 17:51:30 +00:00
nekral-guest
47f937ac13 * src/passwd.c: Use a bool when possible instead of int integers.
* src/passwd.c: Avoid assignments in comparisons.
	* src/passwd.c: Add brackets and parenthesis.
	* src/passwd.c: Avoid implicit conversion of pointers / integers /
	chars to booleans.
	* src/passwd.c: Move the "context_t c" declaration at the
	beginning check_selinux_access.
	* src/passwd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-10 17:50:21 +00:00
nekral-guest
be8d08fda6 * src/groupmod.c: Use a bool when possible instead of int
integers.
	* src/groupmod.c: Avoid assignments in comparisons.
	* src/groupmod.c: Add brackets and parenthesis.
	* src/groupmod.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/groupmod.c: Use a %lu format to print GIDs, and cast the GID
	to (unsigned long int).
	* src/groupmod.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/groupmod.c: Ignore the return value of pam_end() before
	exiting.
2008-06-10 17:45:08 +00:00
nekral-guest
7dea133b55 * src/su.c: Ignore return value of setlocale(),
bindtextdomain(), and textdomain().
2008-06-09 22:28:16 +00:00
nekral-guest
63f0e5e2c0 * src/useradd.c: Use a bool when possible instead of int integers.
* src/useradd.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/useradd.c: Add brackets and parenthesis.
	* src/useradd.c: Avoid assignments in comparisons.
	* src/useradd.c: Ignore the return value of fclose() for read-only
	files.
	* src/useradd.c: Ignore the return value of fflush() before
	closing the files.
	* src/useradd.c: Avoid multi-statements lines.
	* src/useradd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/useradd.c: Ignore the return value of pam_end() before
	exiting.
2008-06-09 22:08:08 +00:00
nekral-guest
fdb577e0a0 * src/vipw.c: Use a bool when possible instead of int integers.
* src/vipw.c: Ignore the return value of umask(), when the mask is
	set again to the old value.
	* src/vipw.c: Avoid implicit conversion of pointers / integers to
	booleans.
	* src/vipw.c: Add brackets and parenthesis.
	* src/vipw.c: Avoid assignments in comparisons.
	* src/vipw.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/vipw.c: Add missing termination of the longopts parameter
	for getopt_long().
2008-06-09 21:18:28 +00:00
nekral-guest
45544f42b9 * src/chgpasswd.c: Use a bool when possible instead of int
integers.
	* src/chgpasswd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/chgpasswd.c: Avoid implicit conversion of integers to
	booleans.
2008-06-09 20:56:03 +00:00
nekral-guest
0452fa2458 * src/groupdel.c: Use a bool when possible instead of int
integers.
	* src/groupdel.c: Avoid implicit conversion of pointers / integers to
	booleans.
	* src/groupdel.c: Avoid assignments in comparisons.
	* src/groupdel.c: Ignore the return value of pam_end() before
	exiting.
	* src/groupdel.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 20:54:04 +00:00
nekral-guest
2b92b0f305 * src/expiry.c: Ignore return value of setlocale(),
bindtextdomain(), and textdomain().
	* src/expiry.c: Add brackets and parenthesis.
	* src/expiry.c: Avoid assignments in comparisons.
	* src/expiry.c: Avoid implicit conversion of pointers to booleans.
2008-06-09 20:36:24 +00:00
nekral-guest
e43c3aed67 Add brackets and parenthesis. 2008-06-09 20:32:17 +00:00
nekral-guest
6aa98c17bd * src/pwunconv.c: Use a bool when possible instead of int
integers.
	* src/pwunconv.c: Add brackets and parenthesis.
	* src/pwunconv.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/pwunconv.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/pwunconv.c: Avoid assignments in comparisons.
2008-06-09 20:30:34 +00:00
nekral-guest
a9f1ce0db1 * src/usermod.c: Use a bool when possible instead of int integers.
* src/usermod.c: Add brackets and parenthesis.
	* src/usermod.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/usermod.c: Avoid assignments in comparisons.
	* src/usermod.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/usermod.c: Ignore the return value of pam_end() before
	exiting.
2008-06-09 20:17:48 +00:00
nekral-guest
d48973bbc8 * src/groupmems.c: Move the declaration of option_index and
long_options before the blocks of code.
	* src/groupmems.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/groupmems.c: Ignore the return value of pam_end() before
	exiting.
2008-06-09 20:09:38 +00:00
nekral-guest
3879f07fa8 * src/chfn.c: Use a bool when possible instead of int integers.
* src/chfn.c: Avoid implicit conversion of integers / chars to
	booleans.
	* src/chfn.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 20:05:13 +00:00
nekral-guest
3ea7f76c17 * src/logoutd.c: Use a bool when possible instead of int integers.
* src/logoutd.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/logoutd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/logoutd.c: Add brackets and parenthesis.
2008-06-09 20:02:46 +00:00
nekral-guest
827f8882bc * src/chpasswd.c: Use a bool when possible instead of int
integers.
	* src/chpasswd.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/chpasswd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 19:46:11 +00:00
nekral-guest
24a7015f64 * src/pwconv.c: Use a bool when possible instead of int integers.
* src/pwconv.c: Add brackets and parenthesis.
	* src/pwconv.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/pwconv.c: Avoid implicit conversion of pointers / integers /
	chars to booleans.
2008-06-09 19:43:22 +00:00
nekral-guest
2a267ca05f * NEWS, src/newusers.c: Implement the -r, --system option.
* src/newusers.c: Use a bool when possible instead of int
	integers.
	* src/newusers.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/newusers.c: Ignore the return value of pam_end() before
	exiting.
	* src/newusers.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/newusers.c: Avoid multi-statements lines.
	* src/newusers.c: Add brackets and parenthesis.
2008-06-09 19:36:08 +00:00
nekral-guest
e41460cae5 * src/gpasswd.c: Use a bool when possible instead of int integers.
* src/gpasswd.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/gpasswd.c: Ignore the return value of putchar() and fflush()
	before exiting.
	* src/gpasswd.c: check_list() renamed is_valid_user_list(), and
	return a bool.
	* src/gpasswd.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 19:26:19 +00:00
nekral-guest
5e2b49dad4 * src/grpck.c: Use a bool when possible instead of int integers.
* src/grpck.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 19:20:00 +00:00
nekral-guest
5038f6687b * src/lastlog.c: Use a bool when possible instead of int integers.
* src/lastlog.c: Avoid implicit conversion of pointers / integers
	/ chars to booleans.
	* src/lastlog.c: Add brackets and parenthesis.
	* src/lastlog.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
2008-06-09 19:15:27 +00:00
nekral-guest
8b98a2e829 * src/userdel.c: Use a bool for the is_shadow_pwd, is_shadow_grp,
deleted_user_group, was_member, was_admin, and the
	options' flags.
	* src/userdel.c: Change path_prefix() prototype to return a bool.
	* src/userdel.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/userdel.c: Ignore the return value from pam_end() since we
	are exiting anyway just afterwards.
	* src/userdel.c: Avoid implicit conversion of pointers /
	integers / chars to booleans.
	* src/userdel.c: Add brackets and parenthesis.
	* src/userdel.c: Avoid assignments in comparisons.
	* src/userdel.c: Do not ignore the return value of the *_unlock()
	functions.
2008-06-09 19:10:44 +00:00
nekral-guest
46466a8fcc * src/login_nopam.c: Do not use the YES and NO macros. Use the
booleans true and false instead. Change the prototypes of
	list_match(), user_match(), from_match(), and string_match()
	accordingly. Also use booleans internally.
	* src/login_nopam.c: Add brackets and parenthesis.
	* src/login_nopam.c: Avoid implicit conversion of pointers /
	integers / chars to booleans.
	* src/login_nopam.c: Avoid assignments in comparisons.
2008-06-09 18:35:32 +00:00
nekral-guest
4e0d734598 * src/newgrp.c: Use a bool for is_newgrp, notfound, needspasswd,
initflag, and cflag.
	* src/newgrp.c: Add brackets and parenthesis.
	* src/newgrp.c: Avoid implicit conversion of pointers / integers /
	chars to booleans.
	* src/newgrp.c: Avoid multi-statements lines.
	* src/newgrp.c: Ignore return value of setlocale(),
	bindtextdomain(), and textdomain().
	* src/newgrp.c: Avoid assignments in comparisons.
2008-06-09 18:23:23 +00:00
nekral-guest
8cfe8db1fb * libmisc/list.c: Change is_on_list() prototype to return a bool. 2008-06-09 18:13:52 +00:00
nekral-guest
5ae74603da * libmisc/find_new_ids.c: Change find_new_uid() and find_new_gid()
prototypes to use a bool for their first argument (sys_user /
	sys_group).
2008-06-09 18:13:09 +00:00
nekral-guest
747664ad4f * libmisc/console.c: Change is_listed() prototype to return a bool.
The default parameter should also be a bool.
	* libmisc/console.c: Add brackets and parenthesis.
	* libmisc/console.c: Avoid assignments in comparisons.
	* libmisc/console.c: Change console() prototype to return a bool.
2008-06-09 18:11:20 +00:00
nekral-guest
9e31065b5e * lib/sgetspent.c: Add brackets and parenthesis.
* lib/sgetspent.c: Avoid assignments in comparisons.
	* lib/sgetspent.c: Avoid implicit conversion of pointers / chars to booleans.
	* lib/sgetspent.c: Avoid multi-statements lines.
2008-05-26 09:39:29 +00:00
nekral-guest
004fb5f9c2 Avoid assignments in comparisons.
Add note about possible bug.
2008-05-26 09:22:44 +00:00
nekral-guest
da62edb4e0 Do not check twice if fields[2] and fields[3] are not empty. 2008-05-26 09:17:17 +00:00
nekral-guest
adc4729ffa * lib/sgetpwent.c: Avoid implicit conversion of pointers / chars to booleans.
* lib/sgetpwent.c: Add brackets and parenthesis.
	* lib/sgetpwent.c: Return NULL instead of 0.
2008-05-26 09:15:02 +00:00
nekral-guest
64d0313c5b * Avoid implicit conversion of pointers to booleans.
* Add parenthesis.
2008-05-26 09:12:34 +00:00
nekral-guest
94b414861d * libmisc/getdate.y: abbrev is a bool.
* libmisc/getdate.y: Avoid implicit conversion of pointers / chars / integers to booleans.
2008-05-26 08:59:54 +00:00
nekral-guest
9305161183 * lib/prototypes.h: Fix prototypes according to earlier changes (usage of the bool type).
* lib/prototypes.h: Add the arguments' name to the prototypes.
2008-05-26 08:56:34 +00:00
nekral-guest
297fa24b90 Add protection against multiple inclusions. 2008-05-26 08:53:56 +00:00
nekral-guest
3ca3362283 Indicate that defines.h is included for the definition of the "bool" type. 2008-05-26 08:52:34 +00:00
nekral-guest
4f38c8d201 The changed, isopen, locked, and readonly fields of the db are booleans. 2008-05-26 08:51:45 +00:00
nekral-guest
964f68630a * lib/pwio.h: Add protection against multiple inclusions.
* lib/pwio.c: The changed, isopen, locked, and readonly fields of the db are booleans.
2008-05-26 08:49:44 +00:00
nekral-guest
caed1add3a * lib/sgroupio.c: Avoid assignments in comparisons.
* lib/sgroupio.c: Add brackets.
	* lib/sgroupio.c: Avoid implicit conversion of pointers / integers to booleans.
	* lib/sgroupio.c: The changed, isopen, locked, and readonly fields of the db are booleans.
	* lib/sgroupio.h, lib/sgroupio.c: sgr_file_present returns a bool.
	* lib/sgroupio.h: Add protection against multiple inclusions.
2008-05-26 08:46:41 +00:00
nekral-guest
77020623ed * lib/shadowio.h, lib/shadowio.c: spw_file_present returns a bool.
* lib/shadowio.h: Add protection against multiple inclusions.
2008-05-26 08:45:34 +00:00
nekral-guest
d264017684 * lib/sgroupio.c: Avoid assignments in comparisons.
* lib/sgroupio.c: Add brackets.
	* lib/sgroupio.c: Avoid implicit conversion of pointers / integers to booleans.
	* lib/sgroupio.c: The changed, isopen, locked, and readonly fields of the db are booleans.
	* lib/sgroupio.h, lib/sgroupio.c: sgr_file_present returns a bool.
	* lib/sgroupio.h: Add protection against multiple inclusions.
2008-05-26 08:43:50 +00:00
nekral-guest
383ea561f8 * lib/gshadow.c: nis_used and nis_bound are booleans.
* lib/gshadow.c: Avoid implicit conversion of pointers / integers to booleans.
	* lib/gshadow.c: Avoid assignments in comparisons.
	* lib/gshadow.c: Add brackets.
2008-05-26 08:40:04 +00:00
nekral-guest
ef5e803875 Add protection against multiple inclusion 2008-05-26 08:35:13 +00:00
nekral-guest
22de221c21 The changed, isopen, locked, and readonly fields of the db are booleans. 2008-05-26 08:34:04 +00:00
nekral-guest
6f88bcf581 * lib/sgetgrent.c: implicit conversion of pointers / chars to booleans.
* lib/sgetgrent.c: Avoid assignments in comparisons.
	* lib/sgetgrent.c: Add brackets.
2008-05-26 08:31:14 +00:00
nekral-guest
6ce26e12f5 * lib/encrypt.c: Avoid implicit conversion of pointers to booleans.
* lib/encrypt.c: Add parenthesis.
2008-05-26 01:07:13 +00:00
nekral-guest
09869159f7 * lib/port.c: Avoid implicit conversion of pointers / integers / chars to booleans.
* lib/port.c: Avoid multiple statement on the same line.
	* lib/port.c: Add brackets and parenthesis.
	* lib/port.c: Avoid assignments in comparisons.
	* lib/port.c: Fix typo comparision -> comparison (in comment).
2008-05-26 01:05:04 +00:00
nekral-guest
14839257ac * lib/fputsx.c: Add brackets.
* lib/fputsx.c: Avoid assignments in comparisons.
	* lib/fputsx.c: Avoid implicit conversion of pointers / integers / chars to booleans.
2008-05-26 00:59:42 +00:00
nekral-guest
f16c6bd7dd * lib/commonio.h: commonio_entry.changed, commonio_db.changed, commonio_db.isopen, commonio_db.locked, and commonio_db.readonly are no booleans.
* lib/commonio.h: Include defines.h to get the definition of bool.
	* lib/commonio.h: commonio_present returns a bool
	* lib/commonio.c: Implement above changes.
	* lib/commonio.c: add argument names in prototypes.
	* lib/commonio.c: name_is_nis returns a bool.
	* lib/commonio.c: nscd_need_reload is a bool.
	* lib/commonio.c: Improve types (use size_t / pid_t when needed instead of int).
	* lib/commonio.c: Avoid assignments in comparisons.
	* lib/commonio.c: Add brackets and parenthesis.
	* lib/commonio.c: Avoid implicit conversion of pointers / integers to booleans
	* lib/commonio.c: The return values of utime is not checked on purpose.
2008-05-26 00:46:25 +00:00
nekral-guest
a24aff2148 checkutmp is implemented twice. I only changed the second one. Now fix the
first one.
2008-05-26 00:26:33 +00:00
nekral-guest
fc6d8e933b * libmisc/isexpired.c: ARGSUSED is no more needed (shadow is always supported).
* libmisc/isexpired.c: Avoid implicit conversion of pointers to booleans.
	* libmisc/isexpired.c: Add brackets and parenthesis.
2008-05-26 00:14:10 +00:00
nekral-guest
c6364944d4 * libmisc/sulog.c (sulog): The success argument is a bool.
* libmisc/sulog.c: The return values of fflush is not checked on purpose.
	* libmisc/sulog.c: Indicate that some return values should be checked.
2008-05-26 00:09:24 +00:00
nekral-guest
70ef747a56 Updated copyright dates. 2008-05-26 00:04:30 +00:00
nekral-guest
3d7aa44c8e * libmisc/ttytype.c: Avoid implicit conversion of pointers / integers to booleans.
* libmisc/ttytype.c: Avoid assignments in comparisons.
	* libmisc/ttytype.c: Add brackets and parenthesis.
	* libmisc/ttytype.c: The return values of fclose is not checked on purpose.
2008-05-26 00:02:15 +00:00
nekral-guest
c249832df1 * libmisc/mail.c: Avoid implicit conversion of pointers to booleans.
* libmisc/mail.c: Avoid assignments in comparisons.
2008-05-25 23:59:05 +00:00
nekral-guest
3169455653 * libmisc/loginprompt.c: Avoid implicit conversion of pointers / chars to booleans.
* libmisc/loginprompt.c: Add brackets.
	* libmisc/loginprompt.c: Avoid assignments in comparisons.
	* libmisc/loginprompt.c: The return values of fclose and fflush are not checked on purpose.
2008-05-25 23:57:41 +00:00
nekral-guest
f7122499a6 Avoid implicit conversion of chars to booleans. 2008-05-25 23:50:03 +00:00
nekral-guest
cc7ac94641 selinux_checked, selinux_enabled, and set_orig are now booleans. 2008-05-25 23:45:21 +00:00
nekral-guest
7f9dfde0dc * libmisc/setugid.c (setup_uid_gid): The is_console argument is now a bool.
* libmisc/setugid.c: Avoid implicit conversion of integers / pointers to booleans.
	* libmisc/setugid.c: Add brackets.
2008-05-25 23:42:39 +00:00
nekral-guest
2533c87bd6 * libmisc/setugid.c (setup_uid_gid): The is_console argument is no a bool.
* libmisc/setugid.c: Avoid implicit conversion of integers / pointers to booleans.
	* libmisc/setugid.c: Add brackets.
2008-05-25 23:39:59 +00:00
nekral-guest
6fef9f5178 * libmisc/pam_pass.c (do_pam_passwd): The silent and
change_expired are no booleans instead of int.
	* libmisc/pam_pass.c: The return value of pam_end is not checked
	on purpose.
2008-05-25 23:38:05 +00:00
nekral-guest
f9ac07f455 Updated copyright dates. 2008-05-25 23:32:41 +00:00
nekral-guest
175e361a4d Updated copyright dates. 2008-05-25 23:31:10 +00:00
nekral-guest
53bedaa4c1 * libmisc/getlong.c: Avoid implicit conversion of pointers / chars to booleans.
* libmisc/getlong.c: Add brackets.
2008-05-25 23:25:33 +00:00
nekral-guest
1ebf7842f5 * libmisc/valid.c: Avoid implicit conversion of pointers /chars to booleans.
* libmisc/valid.c: Add brackets.
2008-05-25 23:22:15 +00:00
nekral-guest
f14452ec3c * libmisc/yesno.c: yes_or_no returns a bool instead of int.
* libmisc/yesno.c: Avoid implicit conversion of pointers to booleans.
	* libmisc/yesno.c: The return value of fflush is not checked on purpose.
2008-05-25 23:01:14 +00:00
nekral-guest
78c0edb7c1 (failcheck): The failed argument is a bool. 2008-05-25 22:54:20 +00:00
nekral-guest
f2b4efff20 Avoid implicit conversion of integers to booleans. 2008-05-25 22:51:46 +00:00
nekral-guest
11003f5842 * libmisc/rlogin.c: Avoid assignments in comparisons.
* libmisc/rlogin.c: Avoid implicit conversion of integers to booleans.
	* libmisc/rlogin.c: Add brackets.
2008-05-25 22:49:41 +00:00
nekral-guest
c638c3cc3d * libmisc/failure.c (failcheck): The failed argument is a bool.
* libmisc/failure.c (too_many_failures): too_many_failures returns
	a bool.
	* libmisc/failure.c: Add notes about unchecked return values.
	* libmisc/failure.c: Avoid assignments in comparisons.
	* libmisc/failure.c: Add brackets.
2008-05-25 22:44:44 +00:00
nekral-guest
a2982f0d4e * libmisc/myname.c: Avoid assignments in comparisons.
* libmisc/myname.c: Avoid implicit conversion of pointers / chars
	to booleans.
	* libmisc/myname.c: Add brackets.
2008-05-25 22:15:28 +00:00
nekral-guest
639b2bd8e5 2008-05-25 22:14:19 +00:00
nekral-guest
7069324a20 * libmisc/utmp.c (checkutmp): Change picky argument's type to
bool.
	* libmisc/utmp.c: Use bool when possible (found_utmpx,
	found_utmp).
	* libmisc/utmp.c: Add note about unchecked return values.
2008-05-25 22:11:12 +00:00
nekral-guest
9d331bb32b * Change type of added to bool.
* Avoid implicit conversion of pointers to booleans.
2008-05-25 22:03:09 +00:00
nekral-guest
bc0657d13c * hushed returns a bool instead of int.
* Avoid assignments in comparisons.
* (hushed) Change type of found to bool.
* Add brackets.
* Always check if the user or the shell is in
  the file. Do not check the first character of the line first. This
  is simpler and match better with the HUSHLOGIN_FILE documentation.
2008-05-25 21:52:14 +00:00
nekral-guest
712ed48a62 * lib/getdef.h, lib/getdef.c: getdef_bool returns a bool instead
of int.
	* lib/getdef.c: Change typo of def_loaded to bool.
	* lib/getdef.c: Add brackets.
	* lib/getdef.c: Avoid assignment in comparisons.
2008-05-25 21:43:05 +00:00
nekral-guest
66afec21d1 Allow usage of booleans in the source. 2008-05-25 21:34:38 +00:00
nekral-guest
b94825bbad * is_my_tty returns a bool.
* Avoid implicit conversion of integers to booleans.
* Add brackets.
2008-05-25 21:33:38 +00:00
nekral-guest
06d2a32a3e * Avoid assignment in comparisons, implicit comparison of integers to booleans.
* The return value of closedir is not checked on purpose.
* Add brackets.
2008-05-25 21:23:28 +00:00
nekral-guest
623d9e2ab3 * libmisc/chkname.h, libmisc/chkname.c: check_group_name (resp.
check_user_name) renamed to is_valid_user_name (resp.
	is_valid_group_name). is_valid_user_name and is_valid_group_name
	return a bool.
	* src/grpck.c, src/newusers.c, src/usermod.c, src/useradd.c,
	src/groupmod.c, src/pwck.c, src/groupadd.c: Use is_valid_user_name
	and is_valid_group_name, following above change.
	* libmisc/chkname.c: Avoid implicit conversion of chars to
	booleans. Add brackets and parenthesis.
2008-05-25 20:58:16 +00:00
nekral-guest
cb8d416b37 Avoid implicit conversion of integers / pointers to booleans. 2008-05-25 20:41:13 +00:00
nekral-guest
de9bee0354 Avoid implicit conversion of integers / pointers to booleans. 2008-05-25 20:39:31 +00:00
nekral-guest
ae75a8c0c1 Allow usage of booleans in the source. 2008-05-25 20:37:51 +00:00
nekral-guest
8098f63998 Allow --disable-man and --enable-man=no. 2008-05-25 20:30:45 +00:00
303 changed files with 95065 additions and 47534 deletions

47
.gitignore vendored Normal file
View File

@@ -0,0 +1,47 @@
*~
lib*.a
*.o
*.lo
*.la
*.gmo
.deps
.libs
*.patch
*.rej
*.orig
Makefile
Makefile.in
/ABOUT-NLS
/aclocal.m4
/autom4te.cache
/config.guess
/config.h
/config.h.in
/config.log
/config.rpath
/config.status
/config.sub
/configure
/depcomp
/install-sh
/libtool
/ltmain.sh
/m4
/missing
/stamp-h1
/ylwrap
/po/*.header
/po/*.sed
/po/*.sin
/po/Makefile.in.in
/po/Makevars.template
/po/POTFILES
/po/Rules-quot
/po/stamp-po
/shadow.spec
/libmisc/getdate.c

4055
ChangeLog

File diff suppressed because it is too large Load Diff

236
NEWS
View File

@@ -1,5 +1,241 @@
$Id$
shadow-4.1.4.1 -> shadow-4.1.4.2 2009-07-24
- general
* Improved support for large groups (impacts most user/group management
tools).
- addition of system users or groups
* Speed improvement. This should be noticeable in case of LDAP configured
systems. This should impact useradd, groupadd, and newusers
* Since system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
reverse order, accounts are packed close to SYS_?ID_MAX if SYS_?ID_MIN
is already used but there are still dome gaps.
- login
* Add support for shells being a shell script without a shebang.
- su
* Preserve the DISPLAY and XAUTHORITY environment variables. This was
only the case in the non PAM enabled versions.
* Add support for shells being a shell script without a shebang.
*** translation
* The Finnish translation of passwd(1) was outdated and is no more
distributed.
shadow-4.1.4 -> shadow-4.1.4.1 2009-05-22
- login
* Fix failures with empty usernames on non PAM versions.
* Fix CONSOLE (securetty) support on non PAM versions.
- newgrp
* Return the exit status of the child.
- userdel
* On Linux, do not check if an user is logged in with utmp, but check if
the user is running some processes.
* If not on Linux, continue to search for an utmp record, but make sure
the process recorded in the utmp entry is still running.
* Report failures to remove the user's mailbox
* When USERGROUPS_ENAB is enabled, remove the user's group when the
user was the only member.
* Do not fail when -r is used and the home directory does not exist.
- usermod
* Check if the user is busy when the user's UID, name or home directory
is changed.
shadow-4.1.3.1 -> shadow-4.1.4 2009-05-10
- packaging
* Enable --enable-account-tools-setuid by default for PAM builds.
* Add configure option --enable-utmpx, disabled by default to mimic
the previous behavior on Linux (where utmp and utmpx are identical).
* Fix build failure on non-PAM systems when --without-pam is not
specified.
- chpasswd
* Change the passwords using PAM. This permits to define the password
policy in a central place. The -c/--crypt-method, -e/--encrypted,
-m/--md5 and -s/--sha-rounds options are no more supported on PAM
enabled systems.
- grpck
* Warn if a group has an entry in group and gshadow, and the password
field in group is not 'x'.
- login
* Do not trust the current utmp entry's ut_line to set PAM_TTY. This could
lead to DOS attacks.
* (PAM) Even if the user was already authenticated (-f flag), ask the
user to update his authentication token if needed.
- lastlog
* Fix regression causing empty reports.
- newusers
* Change the passwords using PAM. This permits to define the password
policy in a central place. The -c/--crypt-method and -s/--sha-rounds
options are no more supported on PAM enabled systems.
- pwck
* Warn if an user has an entry in passwd and shadow, and the password
field in passwd is not 'x'.
*** translation
- Updated Czech translation
- Updated French translation
- Updated German translation
- Updated Japanese translation
- Updated Korean translation
- Updated Portuguese translation
- Updated Russian translation
shadow-4.1.3 -> shadow-4.1.3.1 2009-04-15
*** security:
- Due to bad parsing of octal permissions, the permissions on tty (login)
but also UMASK were set wrongly (and weirdly). Only shadow-4.1.3 was
affected.
*** general
- login
* Fix regression when no user is specified on the command line.
- userdel
* Fixed SE Linux support
- vipw
* SE Linux: Set the default context to the context of the file being
edited. This ensures that the backup file inherit from the file's
context.
*** translation
- Updated Norwegian Bokmål translation
shadow-4.1.2.2 -> shadow-4.1.3 2009-04-12
*** general:
- packaging
* Fixed support for OpenPAM.
* Fixed support for uclibc.
* Added configure --enable-account-tools-setuid (default) /
--disable-account-tools-setuid options. This permits to disable the
PAM authentication of the caller for chage, chgpasswd, chpasswd,
groupadd, groupdel, groupmod, newusers, useradd, userdel, and usermod.
This authentication is not necessary when these tools are not
installed setuid root.
* Added configure --with-group-name-max-length (default) /
--without-group-name-max-length options. This permits to configure the maximum length allowed for group names:
<no option> -> default of 16 (like today)
--with-group-name-max-length -> default of 16
--without-group-name-max-length -> no max length
--with-group-name-max-length=n > max is set to n
No sanity checking is performed on n so people could do
something neat like --with-group-name-max-length=MAX_INT
- addition of users or groups
* Speed improvement in case UID_MAX/SYS_UID_MAX/GID_MAX/SYS_GID_MAX is
used for an user/group. This should be noticeable in case of LDAP
configured systems. This should impact useradd, groupadd, and newusers
- error handling improvement
* Make sure errors and incomplete changes are reported to syslog and
audit in case of unexpected failures.
* Report system inconsistencies to syslog and audit.
* Only report success to syslog and audit if the changes are really
performed in the system databases.
This is still not complete.
- /etc/login.defs
* New CREATE_HOME variable to tell useradd to create a home directory by
default.
- Translations
* New Kazakh translation.
* Spanish manpages are no more distributed. They are outdated. Please
contact pkg-shadow-devel@lists.alioth.debian.org if you wish to
provide updates.
- faillog
* Accept users specified as a numerical UID, or ranges of users (-user,
user-, user1-user2).
* -l, -m, and -r now apply not only to existing users, but to all the
specified UIDs.
* Options can be specified in any order.
- gpasswd
* Added support for long options --add (-a), --delete (-d),
--remove-password (-r), --restrict (-R), --administrators (-A), and
--members (-M).
* Added support for usernames with arbitrary length.
* audit logging improvements.
* error handling improvement (see above).
* Log permission denied to syslog and audit.
- groupadd
* audit logging improvements.
* error handling improvement (see above).
* Speedup (see "addition of users or groups" above).
* do not create groups with GID set to (gid_t)-1.
* Allocate system group GIDs in reverse order. This could be useful
later to increase the static IDs range.
- groupdel
* audit logging improvements.
* error handling improvement (see above).
- groupmems
* Check if user exist before they are added to groups.
* Avoid segfault in case the specified group does not exist in /etc/group.
* Everybody is allowed to list the users of a group.
* /etc/group is open readonly when one just wants to list the users of a
group.
* Added syslog support.
* Use the groupmems PAM service name instead of groupmod.
* Fix segmentation faults when adding or removing users from a group.
* Added support for shadow groups.
* Added support long options --add (-a), --delete (-d), --purge (-p),
--list (-l), --group (-g).
- groupmod
* audit logging improvements.
* error handling improvement (see above).
* do not create groups with GID set to (gid_t)-1.
- grpck
* warn for groups with GID set to (gid_t)-1.
- login
* Restore the echoctl, echoke, onclr flags to the terminal termio flags.
Reset echoprt, noflsh, tostop. This behavior seems to have change by
mistake in earlier releases (4.0.8, for no obvious reason).
- newusers
* Implement the -r, --system option.
* Speedup (see "addition of users or groups" above).
* do not create users with UID set to (gid_t)-1.
* do not create groups with GID set to (gid_t)-1.
* Allocate system account UIDs/GIDs in reverse order. This could be useful
later to increase the static IDs range.
- passwd
* For compatibility with other passwd version, the --lock an --unlock
options do not lock or unlock the user account anymore. They only
lock or unlock the user's password.
- pwck
* warn for users with UID set to (uid_t)-1.
- su
* Preserve COLORTERM in addition to TERM when su is called with the -l
option.
- useradd
* audit logging improvements.
* Speedup (see "addition of users or groups" above).
* See CREATE_HOME above.
* New -M/--no-create-home option to disable CREATE_HOME.
* do not create users with UID set to (gid_t)-1.
* Added -Z option to map SELinux user for user's login.
* Allocate system user UIDs in reverse order. This could be useful
later to increase the static IDs range.
- userdel
* audit logging improvements.
* Do not fail if the removed user is not in the shadow database.
* When the user's group shall be removed, do not fail if this group is
not in the gshadow file.
* Delete the SELinux user mapping for user's login.
- usermod
* Allow adding LDAP users (or any user not present in the local passwd
file) to local groups
* do not create users with UID set to (gid_t)-1.
* Added -Z option to map SELinux user for user's login.
shadow-4.1.2.1 -> shadow-4.1.2.2 23-11-2008
*** security
- Fix a race condition in login that could lead to gaining ownership or
changing mode of arbitrary files.
- Fix a possible login DOS, which could be caused by injecting forged
entries in utmp.
shadow-4.1.2 -> shadow-4.1.2.1 26-06-2008
*** security

17
README
View File

@@ -1,14 +1,19 @@
Shadow SITES
============
Homepage
http://pkg-shadow.alioth.debian.org/
FTP site
ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow
SVN repository
anonymous read only access: svn://svn.debian.org/pkg-shadow/
anonymous read only access: svn://svn.debian.org/pkg-shadow/upstream
SVN web interface
http://svn.debian.org/wsvn/pkg-shadow
http://svn.debian.org/wsvn/pkg-shadow/upstream
or
http://svn.debian.org/viewsvn/pkg-shadow/upstream
Mailing lists
for general discuss: pkg-shadow-devel@lists.alioth.debian.org
@@ -51,6 +56,7 @@ Calle Karlsson <ckn@kash.se>
Chip Rosenthal <chip@unicom.com>
Chris Evans <lady0110@sable.ox.ac.uk>
Cristian Gafton <gafton@sorosis.ro>
Dan Walsh <dwalsh@redhat.com>
Darcy Boese <possum@chardonnay.niagara.com>
Dave Hagewood <admin@arrowweb.com>
David A. Holland <dholland@hcs.harvard.edu>
@@ -77,12 +83,14 @@ Juha Virtanen <jiivee@iki.fi>
Julianne Frances Haugh <jockgrrl@ix.netcom.com>
Leonard N. Zubkoff <lnz@dandelion.com>
Luca Berra <bluca@www.polimi.it>
Lukáš Kuklínek <lkukline@redhat.com>
Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
Marc Ewing <marc@redhat.com>
Martin Bene <mb@sime.com>
Martin Mares <mj@gts.cz>
Michael Meskes <meskes@topsystem.de>
Michael Talbot-Wilson <mike@calypso.bns.com.au>
Mike Frysinger <vapier@gentoo.org>
Mike Pakovic <mpakovic@users.southeast.net>
Nicolas François <nicolas.francois@centraliens.net>
Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
@@ -91,6 +99,8 @@ Phillip Street
Rafał Maszkowski <rzm@icm.edu.pl>
Rani Chouha <ranibey@smartec.com>
Sami Kerola <kerolasa@rocketmail.com>
Sebastian Rick Rijkers <srrijkers@gmail.com>
Seraphim Mellos <mellos@ceid.upatras.gr>
Shane Watts <shane@nexus.mlckew.edu.au>
Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
Thorsten Kukuk <kukuk@suse.de>
@@ -102,5 +112,6 @@ Werner Fink <werner@suse.de>
Maintainers
===========
Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2006)
Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
Nicolas François <nicolas.francois@centraliens.net> (2007-now)

110
TODO
View File

@@ -1,11 +1,38 @@
passwd -l should lock the password, not the account.
/etc/default/useradd
* GROUP=1000 should accept a group name.
vipw: Test SHADOWGRP support before using gshadow features.
Check when RLOGIN is enabled if ruserok() exists
PAM: add support for customization of the PAM support (i.e. support the
Debian PAM configuration)
Move selinux_file_context out of libmisc/copydir.c
PAM: check if a non-interactive conversation function could be used to
Review hardcoded root account?
review all call to strto
libmisc/cleanup_user.c
cleanup needed (cleanup_report_add_user* not used)
libxcrypt support
* http://wiki.linuxfromscratch.org/patches/browser/trunk/shadow/shadow-4.0.18.1-owl_blowfish-1.patch
implement getlong, getulong.
avoid atoi, atol, atoul, strtol, strtoul, ...
manpages: comment the RLOGIN parts
Replace build_list (in lib/gshadow.c) and list (in lib/sgetgrent.c) by
comma_to_list()
Revert the modified files if all files could not be changed.
* or warn and indicate which files were modified and which were not.
* check the order the files are modified.
report nscd_flush_cache failures?
call nscd from the programs or from lib (commonio?)
PAM: check if a non-interactive conversation function could be used to set
the password in chpasswd and newusers
WITH_SELINUX
- review all tools to check that the strategies are consistent
@@ -13,33 +40,20 @@ WITH_SELINUX
chage, chfn, chsh: same change needed as in passwd.
- probably need moving check_selinux_access to a separate file.
man useradd
document default behavior for GROUP
remove "The default group number is 1 or whatever is..."
useradd manpage
- add -k option
- mention that -o require -u
testsuite
- newgrp
- test with unknown user's GID
newusers
- add logging to SYSLOG & AUDIT
faillog
- accept numerical user and range of users
- use CREATE_HOME
- Add a -Z option (see useradd / usermod)
Document when/where option appeared, document whether an option is standard
or not.
depends rules for the manpages
Check all the expiry semantics
Add options --crypt-method and --sha-rounds to gpasswd
ALL:
- move base passwd/shadow/group/gshadow operation to module for allow write
different backend modules for db, NIS, LDAP and others. Default backend it
@@ -49,38 +63,52 @@ ALL:
passwd have old piece of code with handling -r option and it will be good
finish this and propagate on other shadow tools for allow operate on other
user databases by well known tools.
- Protect against signals. Register do_cleanups in a signal handler.
- login.defs
- generate depending on configuration
- useradd:
- add handle create user mail spool in maildir format.
- add handle -n switch in groups and id command for allow query is
group/user with specified id/gid exist - this will be very usable
on automation in packages for query/check is group/user exist in system
or not,
- groupmems:
- need some work on add PAM and i18n support.
- Add support for -k in -D mode
- Add support for -K in -D mode
- Add option to create or not the mail spool (and set the default in -D
mode)
- Change -l to reset the entry if an entry was already there
- set the mask in mkdir?
- userdel:
- add backup option for the removal of user resources,
- add lookop and remove per user group.
- user_busy: check that the user is not running any processes.
- missing "deleting group" FAILED
- home dir removed, but userdel may fail and may leave the user
=> warning needed
- usermod
- add an option equivalent to useradd's -l (only when uid is changed)
- the mode of new home directories should be set according to the
original mode. Does copy_tree does this?
- user renamed, order is not kept in /etc/group (see
47_usermod-l_no_shadow_file). This is a problem when the first user is
considered as the admin.
- see mail "user ID change" on April, 15
+ fix call to chown (combination of -m and -u/-g)
+ add tests
- passwd:
- check combination of options (e.g. -u/-l)
- when -u refuse to unlock because it would create an empty password, it
should not display "Password changed."
exit instead?
- newgrp: check the USE_PAM section.
- groupmems: check reason for isgroup
- pwck
- Add check to move passwd passwords to shadow if there is a shadow
entry (with a password).
- Add check to move passwd passwords to shadow if there is a shadow
file.
- newusers: doc for pw_gid not clear. Differentiate
pw_gid specified and exist
pw_gid specified but does not exist
* name
* number
pw_gid not specified.
- newusers: document what happens when no uid is specified.
- newusers: add option --system?
-Documentation:
* document when options were added.
- su
- add a login.defs configuration parameter to add variables to keep in
the environment with "su -l" (TERM/TERMCOLOR/...

View File

@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT
AM_INIT_AUTOMAKE(shadow, 4.1.2.1)
AM_INIT_AUTOMAKE(shadow, 4.1.4.2)
AC_CONFIG_HEADERS([config.h])
dnl Some hacks...
@@ -28,6 +28,7 @@ dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_STDBOOL
AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
@@ -37,10 +38,10 @@ AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
AC_CHECK_FUNCS(l64a fchmod fchown fsync getgroups gethostname getspnam \
AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \
memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r)
lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo)
AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -51,41 +52,39 @@ AC_TYPE_PID_T
AC_TYPE_MODE_T
AC_HEADER_STAT
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_MEMBERS([struct stat.st_atim])
AC_CHECK_MEMBERS([struct stat.st_atimensec])
AC_CHECK_MEMBERS([struct stat.st_mtim])
AC_CHECK_MEMBERS([struct stat.st_mtimensec])
AC_HEADER_TIME
AC_STRUCT_TM
if test "$ac_cv_header_utmp_h" = "yes"; then
AC_CACHE_CHECK(for ut_host in struct utmp,
ac_cv_struct_utmp_ut_host,
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([#include <utmp.h>],
[struct utmp ut; char *cp = ut.ut_host;]
)],
[ac_cv_struct_utmp_ut_host=yes],
[ac_cv_struct_utmp_ut_host=no]
)
)
if test "$ac_cv_struct_utmp_ut_host" = "yes"; then
AC_DEFINE(UT_HOST, 1, [Define if you have ut_host in struct utmp.])
fi
AC_CACHE_CHECK(for ut_user in struct utmp,
ac_cv_struct_utmp_ut_user,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <utmp.h>],
[struct utmp ut; char *cp = ut.ut_user;]
)],
[ac_cv_struct_utmp_ut_user=yes],
[ac_cv_struct_utmp_ut_user=no]
)
)
if test "$ac_cv_struct_utmp_ut_user" = "no"; then
AC_DEFINE(ut_user, ut_name,
[Define to ut_name if struct utmp has ut_name (not ut_user).])
fi
AC_CHECK_MEMBERS([struct utmp.ut_type,
struct utmp.ut_id,
struct utmp.ut_name,
struct utmp.ut_user,
struct utmp.ut_host,
struct utmp.ut_syslen,
struct utmp.ut_addr,
struct utmp.ut_addr_v6,
struct utmp.ut_time,
struct utmp.ut_xtime,
struct utmp.ut_tv],,,[[#include <utmp.h>]])
dnl There are dependencies:
dnl If UTMPX has to be used, the utmp structure shall have a ut_id field.
if test "$ac_cv_header_utmpx_h" = "yes" &&
test "$ac_cv_member_struct_utmp_ut_id" != "yes"; then
AC_MSG_ERROR(Systems with UTMPX and no ut_id field in the utmp structure are not supported)
fi
AC_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_host,
struct utmpx.ut_syslen,
struct utmpx.ut_addr,
struct utmpx.ut_addr_v6,
struct utmpx.ut_time,
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
if test "$ac_cv_header_lastlog_h" = "yes"; then
AC_CACHE_CHECK(for ll_host in struct lastlog,
ac_cv_struct_lastlog_ll_host,
@@ -212,8 +211,31 @@ AC_ARG_ENABLE(shadowgrp,
AC_ARG_ENABLE(man,
[AC_HELP_STRING([--enable-man],
[regenerate roff man pages from Docbook @<:@default=no@:>@])],
[enable_man=yes],
[enable_man=no]
[enable_man="${enableval}"],
[enable_man="no"]
)
AC_ARG_ENABLE(account-tools-setuid,
[AC_HELP_STRING([--enable-account-tools-setuid],
[Install the user and group management tools setuid and authenticate the callers. This requires --with-pam.])],
[case "${enableval}" in
yes) enable_acct_tools_setuid="yes" ;;
no) enable_acct_tools_setuid="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-account-tools-setuid)
;;
esac],
[enable_acct_tools_setuid="maybe"]
)
AC_ARG_ENABLE(utmpx,
[AC_HELP_STRING([--enable-utmpx],
[enable loggin in utmpx / wtmpx @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_utmpx="yes" ;;
no) enable_utmpx="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-utmpx) ;;
esac],
[enable_utmpx="no"]
)
AC_ARG_WITH(audit,
@@ -234,10 +256,31 @@ AC_ARG_WITH(libcrack,
AC_ARG_WITH(sha-crypt,
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
[with_sha_crypt=$withval], [with_sha_crypt=yes])
AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
AC_ARG_WITH(group-name-max-length,
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
if test "$with_group_name_max_length" = "no" ; then
with_group_name_max_length=0
elif test "$with_group_name_max_length" = "yes" ; then
with_group_name_max_length=16
fi
AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max group name length])
AC_SUBST(GROUP_NAME_MAX_LENGTH)
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
fi
if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
[AC_MSG_ERROR([posix_spawn is needed for nscd support])])
fi
dnl Check for some functions in libc first, only if not found check for
@@ -268,7 +311,7 @@ if test "$enable_man" = "yes"; then
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets >= 1.70.1], [], enable_man=no)
fi
AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test x$enable_man != xno)
AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test "x$enable_man" != "xno")
AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
@@ -280,6 +323,15 @@ if test "$with_audit" != "no"; then
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([libaudit.h is missing])
elif test "$audit_header" = "yes"; then
AC_CHECK_DECL(AUDIT_ADD_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_ADD_GROUP,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_GROUP,,[audit_header="no"],[#include <libaudit.h>])
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([AUDIT_ADD_USER AUDIT_DEL_USER AUDIT_ADD_GROUP or AUDIT_DEL_GROUP missing from libaudit.h])
fi
fi
if test "$audit_header" = "yes"; then
AC_CHECK_LIB(audit, audit_log_acct_message,
[audit_lib="yes"], [audit_lib="no"])
if test "$audit_lib$with_audit" = "noyes" ; then
@@ -339,23 +391,55 @@ if test "$with_libpam" != "no"; then
AC_MSG_ERROR(libpam not found)
fi
AC_CHECK_LIB(pam_misc, main,
[pam_misc_lib="yes"], [pam_misc_lib="no"])
if test "$pam_misc_lib$with_libpam" = "noyes" ; then
AC_MSG_ERROR(libpam_misc not found)
LIBPAM="-lpam"
pam_conv_function="no"
AC_CHECK_LIB(pam, openpam_ttyconv,
[pam_conv_function="openpam_ttyconv"],
AC_CHECK_LIB(pam_misc, misc_conv,
[pam_conv_function="misc_conv"; LIBPAM="$LIBPAM -lpam_misc"])
)
if test "$pam_conv_function$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM conversation function not found)
fi
if test "$pam_lib$pam_misc_lib" = "yesyes" ; then
pam_headers_found=no
AC_CHECK_HEADERS( [security/openpam.h security/pam_misc.h],
[ pam_headers_found=yes ; break ], [],
[ #include <security/pam_appl.h> ] )
if test "$pam_headers_found$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM headers not found)
fi
if test "$pam_lib$pam_headers_found" = "yesyes" -a "$pam_conv_function" != "no" ; then
with_libpam="yes"
else
with_libpam="no"
unset LIBPAM
fi
fi
dnl Now with_libpam is either yes or no
if test "$with_libpam" = "yes"; then
AC_CHECK_DECLS([PAM_ESTABLISH_CRED,
PAM_DELETE_CRED,
PAM_NEW_AUTHTOK_REQD,
PAM_DATA_SILENT],
[], [], [#include <security/pam_appl.h>])
save_libs=$LIBS
LIBS="$LIBS $LIBPAM"
# We do not use AC_CHECK_FUNCS to avoid duplicated definition with
# Linux PAM.
AC_CHECK_FUNC(pam_fail_delay, [AC_DEFINE(HAS_PAM_FAIL_DELAY, 1, [Define to 1 if you have the declaration of 'pam_fail_delay'])])
LIBS=$save_libs
AC_DEFINE(USE_PAM, 1, [Define to support Pluggable Authentication Modules])
AC_DEFINE_UNQUOTED(SHADOW_PAM_CONVERSATION, [$pam_conv_function],[PAM converstation to use])
AM_CONDITIONAL(USE_PAM, [true])
LIBPAM="-lpam -lpam_misc"
AC_MSG_CHECKING(use login and su access checking if PAM not used)
AC_MSG_RESULT(no)
else
@@ -365,6 +449,24 @@ else
AC_MSG_RESULT(yes)
fi
if test "$enable_acct_tools_setuid" != "no"; then
if test "$with_libpam" != "yes"; then
if test "$enable_acct_tools_setuid" = "yes"; then
AC_MSG_ERROR(PAM support is required for --enable-account-tools-setuid)
else
enable_acct_tools_setuid="no"
fi
else
enable_acct_tools_setuid="yes"
fi
if test "$enable_acct_tools_setuid" = "yes"; then
AC_DEFINE(ACCT_TOOLS_SETUID,
1,
[Define if account management tools should be installed setuid and authenticate the callers])
fi
fi
AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
AC_SUBST(LIBSKEY)
AC_SUBST(LIBMD)
if test "$with_skey" = "yes"; then
@@ -380,6 +482,17 @@ if test "$with_skey" = "yes"; then
],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])])
fi
if test "$enable_utmpx" = "yes"; then
if test "$ac_cv_header_utmpx_h" != "yes"; then
AC_MSG_ERROR([The utmpx.h header file is required for utmpx support.])
fi
AC_DEFINE(USE_UTMPX,
1,
[Define if utmpx should be used])
fi
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
AM_GNU_GETTEXT_VERSION(0.16)
AM_GNU_GETTEXT([external], [need-ngettext])
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
@@ -389,6 +502,7 @@ AC_CONFIG_FILES([
po/Makefile.in
doc/Makefile
man/Makefile
man/config.xml
man/po/Makefile.in
man/cs/Makefile
man/de/Makefile
@@ -423,8 +537,12 @@ echo
echo " auditing support: $with_audit"
echo " CrackLib support: $with_libcrack"
echo " PAM support: $with_libpam"
if test "$with_libpam" = "yes"; then
echo " suid account management tools: $enable_acct_tools_setuid"
fi
echo " SELinux support: $with_selinux"
echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
echo " nscd support: $with_nscd"
echo

View File

@@ -230,7 +230,7 @@ void main()
fflush(stdin);
} else
if (dir[strlen(dir)-1]=='/')
sprintf(dir,"%s%s",dir,uname);
sprintf(dir+strlen(dir),"%s",uname);
printf("\nShell [%s]: ",DEFAULT_SHELL);
fflush(stdout);

View File

@@ -296,7 +296,7 @@ main (void)
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
else if (dir[strlen (dir) - 1] == '/')
sprintf (dir, "%s%s", dir, usrname);
sprintf (dir+strlen(dir), "%s", usrname);
}
else
{

View File

@@ -31,8 +31,6 @@ New ideas to add to this list are welcome, too. --marekm
- new option for /etc/suauth: don't load user's environment (force "su -")
suggested by Ulisses Alonso Camaro
- find out why recent releases won't compile on Solaris
- newusers UID/GID selection algorithm should be the same as useradd
(and use UID_MIN, UID_MAX from login.defs)
- newusers should be able to copy /etc/skel to the new home directory
(like useradd)
- add directories where other packages can add hooks for package-specific

View File

@@ -6,6 +6,8 @@
#
# Delay in seconds before being allowed another attempt after a login failure
# Note: When PAM is used, some modules may enfore a minimal delay (e.g.
# pam_unix enforces a 2s delay)
#
FAIL_DELAY 3
@@ -169,7 +171,6 @@ TTYPERM 0600
#
# ERASECHAR Terminal ERASE character ('\010' = backspace).
# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
# UMASK Default "umask" value.
# ULIMIT Default "ulimit" value.
#
# The ERASECHAR and KILLCHAR are used only on System V machines.
@@ -180,9 +181,16 @@ TTYPERM 0600
#
ERASECHAR 0177
KILLCHAR 025
UMASK 022
#ULIMIT 2097152
# Default initial "umask" value for non-PAM enabled systems.
# UMASK is also used by useradd and newusers to set the mode of new home
# directories.
# 022 is the default value, but 027, or even 077, could be considered
# better for privacy. There is no One True Answer here: each sysadmin
# must make up her mind.
UMASK 022
#
# Password aging controls:
#
@@ -215,7 +223,7 @@ CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict
UID_MIN 1000
UID_MAX 60000
# System accounts
SYS_UID_MIN 100
SYS_UID_MIN 101
SYS_UID_MAX 999
#
@@ -224,7 +232,7 @@ SYS_UID_MAX 999
GID_MIN 1000
GID_MAX 60000
# System accounts
SYS_GID_MIN 100
SYS_GID_MIN 101
SYS_GID_MAX 999
#
@@ -367,3 +375,12 @@ USERGROUPS_ENAB yes
# 0 is the default value and disables this feature.
#
#MAX_MEMBERS_PER_GROUP 0
#
# If useradd should create home directories for users by default (non
# system users only)
# This option is overridden with the -M or -m flags on the useradd command
# line.
#
#CREATE_HOME yes

View File

@@ -2,19 +2,21 @@
# and also cooperate to make a distribution for `make dist'
pamd_files = \
chage \
chfn \
chsh \
groupmems \
login \
passwd \
su
pamd_acct_tools_files = \
chage \
chgpasswd \
chpasswd \
chsh \
groupadd \
groupdel \
groupmems \
groupmod \
login \
newusers \
passwd \
su \
useradd \
userdel \
usermod
@@ -22,6 +24,9 @@ pamd_files = \
if USE_PAM
pamddir = $(sysconfdir)/pam.d
pamd_DATA = $(pamd_files)
if ACCT_TOOLS_SETUID
pamd_DATA += $(pamd_acct_tools_files)
endif
endif
EXTRA_DIST = $(pamd_files)
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)

View File

@@ -17,6 +17,11 @@ libshadow_la_SOURCES = \
fputsx.c \
getdef.c \
getdef.h \
get_gid.c \
getlong.c \
get_pid.c \
get_uid.c \
getulong.c \
groupio.c \
groupmem.c \
groupio.h \
@@ -35,6 +40,7 @@ libshadow_la_SOURCES = \
pwmem.c \
sgetgrent.c \
sgetpwent.c \
sgetspent.c \
sgroupio.c \
sgroupio.h\
shadow.c \

File diff suppressed because it is too large Load Diff

View File

@@ -37,14 +37,18 @@
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#include "defines.h" /* bool */
/*
* Linked list entry.
*/
struct commonio_entry {
char *line;
void *eptr; /* struct passwd, struct spwd, ... */
struct commonio_entry *prev, *next;
unsigned int changed:1;
/*@null@*/char *line;
/*@null@*/void *eptr; /* struct passwd, struct spwd, ... */
/*@dependent@*/ /*@null@*/struct commonio_entry *prev;
/*@owned@*/ /*@null@*/struct commonio_entry *next;
bool changed:1;
};
/*
@@ -55,12 +59,12 @@ struct commonio_ops {
* Make a copy of the object (for example, struct passwd)
* and all strings pointed by it, in malloced memory.
*/
void *(*dup) (const void *);
/*@null@*/ /*@only@*/void *(*dup) (const void *);
/*
* free() the object including any strings pointed by it.
*/
void (*free) (void *);
void (*free) (/*@out@*/ /*@only@*/void *);
/*
* Return the name of the object (for example, pw_name
@@ -84,7 +88,7 @@ struct commonio_ops {
* fgets and fputs (can be replaced by versions that
* understand line continuation conventions).
*/
char *(*fgets) (char *, int, FILE *);
/*@null@*/char *(*fgets) (/*@returned@*/ /*@out@*/char *s, int n, FILE *stream);
int (*fputs) (const char *, FILE *);
/*
@@ -93,8 +97,8 @@ struct commonio_ops {
* is open or before it is closed.
* They return 0 on failure and 1 on success.
*/
int (*open_hook) (void);
int (*close_hook) (void);
/*@null@*/int (*open_hook) (void);
/*@null@*/int (*close_hook) (void);
};
/*
@@ -109,40 +113,41 @@ struct commonio_db {
/*
* Operations from above.
*/
struct commonio_ops *ops;
/*@observer@*/const struct commonio_ops *ops;
/*
* Currently open file stream.
*/
FILE *fp;
/*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX
security_context_t scontext;
/*@null@*/security_context_t scontext;
#endif
/*
* Head, tail, current position in linked list.
*/
struct commonio_entry *head, *tail, *cursor;
/*@owned@*/ /*@null@*/struct commonio_entry *head, *tail;
/*@dependent@*/ /*@null@*/struct commonio_entry *cursor;
/*
* Various flags.
*/
unsigned int changed:1;
unsigned int isopen:1;
unsigned int locked:1;
unsigned int readonly:1;
bool changed:1;
bool isopen:1;
bool locked:1;
bool readonly:1;
};
extern int commonio_setname (struct commonio_db *, const char *);
extern int commonio_present (const struct commonio_db *);
extern bool commonio_present (const struct commonio_db *db);
extern int commonio_lock (struct commonio_db *);
extern int commonio_lock_nowait (struct commonio_db *);
extern int commonio_open (struct commonio_db *, int);
extern const void *commonio_locate (struct commonio_db *, const char *);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);
extern int commonio_remove (struct commonio_db *, const char *);
extern int commonio_rewind (struct commonio_db *);
extern const void *commonio_next (struct commonio_db *);
extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *);
extern int commonio_close (struct commonio_db *);
extern int commonio_unlock (struct commonio_db *);
extern void commonio_del_entry (struct commonio_db *,

View File

@@ -4,29 +4,60 @@
#ifndef _DEFINES_H_
#define _DEFINES_H_
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false (0)
# define true (1)
# define __bool_true_false_are_defined 1
#endif
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
/* Take care of NLS matters. */
#if HAVE_LOCALE_H
#ifdef S_SPLINT_S
extern char *setlocale(int categorie, const char *locale);
# define LC_ALL (6)
extern char * bindtextdomain (const char * domainname, const char * dirname);
extern char * textdomain (const char * domainname);
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#else
#ifdef HAVE_LOCALE_H
# include <locale.h>
#else
# undef setlocale
# define setlocale(category, locale) (NULL)
# ifndef LC_ALL
# define LC_ALL 6
# endif
#endif
#define gettext_noop(String) (String)
/* #define gettext_def(String) "#define String" */
#if ENABLE_NLS
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
#else
# undef bindtextdomain
# define bindtextdomain(Domain, Directory) /* empty */
# define bindtextdomain(Domain, Directory) (NULL)
# undef textdomain
# define textdomain(Domain) /* empty */
# define textdomain(Domain) (NULL)
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#endif
#endif
#if STDC_HEADERS
# include <stdlib.h>
@@ -136,7 +167,7 @@ char *strchr (), *strrchr (), *strtok ();
/* cleaner than lots of #ifdefs everywhere - use this as follows:
SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
#if ENABLE_NLS
#ifdef ENABLE_NLS
/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog.
This is a workaround for a more general syslog(d) design problem -
syslogd should log the current system time for each event, and not
@@ -146,17 +177,20 @@ char *strchr (), *strrchr (), *strtok ();
* --Nekral */
#define SYSLOG(x) \
do { \
char *saved_locale = setlocale(LC_ALL, NULL); \
if (saved_locale) \
saved_locale = strdup(saved_locale); \
if (saved_locale) \
setlocale(LC_ALL, "C"); \
syslog x ; \
if (saved_locale) { \
setlocale(LC_ALL, saved_locale); \
free(saved_locale); \
char *old_locale = setlocale(LC_ALL, NULL); \
char *saved_locale = NULL; \
if (NULL != old_locale) { \
saved_locale = strdup (old_locale); \
} \
} while (0)
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, "C"); \
} \
syslog x ; \
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, saved_locale); \
free (saved_locale); \
} \
} while (false)
#else /* !ENABLE_NLS */
#define SYSLOG(x) syslog x
#endif /* !ENABLE_NLS */
@@ -303,6 +337,8 @@ extern char *strerror ();
#define SHADOW_PASSWD_STRING "x"
#endif
#define SHADOW_SP_FLAG_UNSET ((unsigned long int)-1)
#ifdef WITH_AUDIT
#ifdef __u8 /* in case we use pam < 0.80 */
#undef __u8
@@ -321,4 +357,29 @@ extern char *strerror ();
# define unused
#endif
/* ! Arguments evaluated twice ! */
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* Maximum length of usernames */
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
#else
# include <utmp.h>
# ifdef HAVE_STRUCT_UTMP_UT_USER
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
# else
# ifdef HAVE_STRUCT_UTMP_UT_NAME
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
# else
# define USER_NAME_MAX_LENGTH 32
# endif
# endif
#endif
#endif /* _DEFINES_H_ */

View File

@@ -53,12 +53,12 @@ char *pw_encrypt (const char *clear, const char *salt)
* expect us to return NULL, so...
*/
perror ("crypt");
exit (1);
exit (EXIT_FAILURE);
}
/* The GNU crypt does not return NULL if the algorithm is not
* supported, and return a DES encrypted password. */
if (salt && salt[0] == '$' && strlen (cp) <= 13)
if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13))
{
const char *method;
switch (salt[1])
@@ -82,12 +82,15 @@ char *pw_encrypt (const char *clear, const char *salt)
fprintf (stderr,
_("crypt method not supported by libcrypt? (%s)\n"),
method);
exit (1);
exit (EXIT_FAILURE);
}
if (strlen (cp) != 13)
if (strlen (cp) != 13) {
return cp; /* nonstandard crypt() in libc, better bail out */
}
strcpy (cipher, cp);
return cipher;
}

View File

@@ -32,7 +32,12 @@
/*
* Exit codes used by shadow programs
*/
#define E_SUCCESS 0 /* success */
#define E_SUCCESS EXIT_SUCCESS /* success */
/*
* FIXME: other values should differ from EXIT_FAILURE (and EXIT_SUCCESS).
*
* FIXME: reserve EXIT_FAILURE for internal failures.
*/
#define E_NOPERM 1 /* permission denied */
#define E_USAGE 2 /* invalid command syntax */
#define E_BAD_ARG 3 /* invalid argument to option */

View File

@@ -39,23 +39,29 @@
#ident "$Id$"
char *fgetsx (char *buf, int cnt, FILE * f)
/*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *buf, int cnt, FILE * f)
{
char *cp = buf;
char *ep;
while (cnt > 0) {
if (fgets (cp, cnt, f) == 0) {
if (cp == buf)
if (fgets (cp, cnt, f) != cp) {
if (cp == buf) {
return 0;
else
} else {
break;
}
}
if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') {
if ((cnt -= ep - cp) > 0)
*(cp = ep) = '\0';
} else
ep = strrchr (cp, '\\');
if ((NULL != ep) && (*(ep + 1) == '\n')) {
cnt -= ep - cp;
if (cnt > 0) {
cp = ep;
*cp = '\0';
}
} else {
break;
}
}
return buf;
}
@@ -64,9 +70,10 @@ int fputsx (const char *s, FILE * stream)
{
int i;
for (i = 0; *s; i++, s++) {
if (putc (*s, stream) == EOF)
for (i = 0; '\0' != *s; i++, s++) {
if (putc (*s, stream) == EOF) {
return EOF;
}
#if 0 /* The standard getgr*() can't handle that. --marekm */
if (i > (BUFSIZ / 2)) {
@@ -80,3 +87,4 @@ int fputsx (const char *s, FILE * stream)
}
return 0;
}

54
lib/get_gid.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_gid (const char *gidstr, gid_t *gid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (gidstr, &endptr, 10);
if ( ('\0' == *gidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
return 0;
}
*gid = (gid_t)val;
return 1;
}

54
lib/get_pid.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_pid (const char *pidstr, pid_t *pid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (pidstr, &endptr, 10);
if ( ('\0' == *pidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
return 0;
}
*pid = (pid_t)val;
return 1;
}

54
lib/get_uid.c Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_uid (const char *uidstr, uid_t *uid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (uidstr, &endptr, 10);
if ( ('\0' == *uidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
return 0;
}
*uid = (uid_t)val;
return 1;
}

View File

@@ -39,13 +39,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "getdef.h"
/*
* A configuration item definition.
*/
struct itemdef {
const char *name; /* name of the item */
char *value; /* value given, or NULL if no value */
/*@null@*/const char *name; /* name of the item */
/*@null@*/char *value; /* value given, or NULL if no value */
};
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
@@ -131,10 +132,10 @@ static struct itemdef def_table[] = {
#endif
static char def_fname[] = LOGINDEFS; /* login config defs file */
static int def_loaded = 0; /* are defs already loaded? */
static bool def_loaded = false; /* are defs already loaded? */
/* local function prototypes */
static struct itemdef *def_find (const char *);
static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *);
static void def_load (void);
@@ -145,14 +146,16 @@ static void def_load (void);
* defined. First time invoked, will load definitions from the file.
*/
char *getdef_str (const char *item)
/*@observer@*/ /*@null@*/const char *getdef_str (const char *item)
{
struct itemdef *d;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
return ((d = def_find (item)) == NULL ? (char *) NULL : d->value);
d = def_find (item);
return ((NULL == d)? (const char *) NULL : d->value);
}
@@ -162,15 +165,18 @@ char *getdef_str (const char *item)
* Return TRUE if specified item is defined as "yes", else FALSE.
*/
int getdef_bool (const char *item)
bool getdef_bool (const char *item)
{
struct itemdef *d;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
if ((d = def_find (item)) == NULL || d->value == NULL)
return 0;
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return false;
}
return (strcasecmp (d->value, "yes") == 0);
}
@@ -187,14 +193,27 @@ int getdef_bool (const char *item)
int getdef_num (const char *item, int dflt)
{
struct itemdef *d;
long val;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
if ((d = def_find (item)) == NULL || d->value == NULL)
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
return (int) strtol (d->value, (char **) NULL, 0);
if ( (getlong (d->value, &val) == 0)
|| (val > INT_MAX)
|| (val < INT_MIN)) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return (int) val;
}
@@ -209,14 +228,27 @@ int getdef_num (const char *item, int dflt)
unsigned int getdef_unum (const char *item, unsigned int dflt)
{
struct itemdef *d;
long val;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
if ((d = def_find (item)) == NULL || d->value == NULL)
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
return (unsigned int) strtoul (d->value, (char **) NULL, 0);
if ( (getlong (d->value, &val) == 0)
|| (val < 0)
|| (val > INT_MAX)) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return (unsigned int) val;
}
@@ -231,16 +263,59 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
long getdef_long (const char *item, long dflt)
{
struct itemdef *d;
long val;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
if ((d = def_find (item)) == NULL || d->value == NULL)
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
return strtol (d->value, (char **) NULL, 0);
if (getlong (d->value, &val) == 0) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return val;
}
/*
* getdef_ulong - get unsigned long numerical value from table of definitions
*
* Returns numeric value of specified item, else the "dflt" value if
* the item is not defined. Octal (leading "0") and hex (leading "0x")
* values are handled.
*/
unsigned long getdef_ulong (const char *item, unsigned long dflt)
{
struct itemdef *d;
unsigned long val;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
if (getulong (d->value, &val) == 0) {
/* FIXME: we should have a getulong */
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return val;
}
/*
* putdef_str - override the value read from /etc/login.defs
@@ -252,28 +327,33 @@ int putdef_str (const char *name, const char *value)
struct itemdef *d;
char *cp;
if (!def_loaded)
if (!def_loaded) {
def_load ();
}
/*
* Locate the slot to save the value. If this parameter
* is unknown then "def_find" will print an err message.
*/
if ((d = def_find (name)) == NULL)
d = def_find (name);
if (NULL == d) {
return -1;
}
/*
* Save off the value.
*/
if ((cp = strdup (value)) == NULL) {
fputs (_("Could not allocate space for config info.\n"),
stderr);
cp = strdup (value);
if (NULL == cp) {
(void) fputs (_("Could not allocate space for config info.\n"),
stderr);
SYSLOG ((LOG_ERR, "could not allocate space for config info"));
return -1;
}
if (d->value)
if (NULL != d->value) {
free (d->value);
}
d->value = cp;
return 0;
@@ -287,9 +367,8 @@ int putdef_str (const char *name, const char *value)
* specified configuration option.
*/
static struct itemdef *def_find (const char *name)
static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
{
int n;
struct itemdef *ptr;
@@ -297,9 +376,10 @@ static struct itemdef *def_find (const char *name)
* Search into the table.
*/
for (ptr = def_table; ptr->name; ptr++) {
if (!(n = strcmp (ptr->name, name)))
for (ptr = def_table; NULL != ptr->name; ptr++) {
if (strcmp (ptr->name, name) == 0) {
return ptr;
}
}
/*
@@ -307,9 +387,8 @@ static struct itemdef *def_find (const char *name)
*/
fprintf (stderr,
_
("configuration error - unknown item '%s' (notify administrator)\n"),
name);
_("configuration error - unknown item '%s' (notify administrator)\n"),
name);
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
return (struct itemdef *) NULL;
}
@@ -329,31 +408,35 @@ static void def_load (void)
/*
* Open the configuration definitions file.
*/
if ((fp = fopen (def_fname, "r")) == NULL) {
SYSLOG ((LOG_CRIT, "cannot open login definitions %s [%m]",
def_fname));
exit (1);
fp = fopen (def_fname, "r");
if (NULL == fp) {
int err = errno;
SYSLOG ((LOG_CRIT, "cannot open login definitions %s [%s]",
def_fname, strerror (err)));
exit (EXIT_FAILURE);
}
/*
* Set the initialized flag.
* (do it early to prevent recursion in putdef_str())
*/
++def_loaded;
def_loaded = true;
/*
* Go through all of the lines in the file.
*/
while (fgets (buf, sizeof (buf), fp) != NULL) {
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
/*
* Trim trailing whitespace.
*/
for (i = strlen (buf) - 1; i >= 0; --i) {
if (!isspace (buf[i]))
for (i = (int) strlen (buf) - 1; i >= 0; --i) {
if (!isspace (buf[i])) {
break;
}
}
buf[++i] = '\0';
i++;
buf[i] = '\0';
/*
* Break the line into two fields.
@@ -372,14 +455,19 @@ static void def_load (void)
/*
* Store the value in def_table.
*
* Ignore failures to load the login.defs file.
* The error was already reported to the user and to
* syslog. The tools will just use their default values.
*/
putdef_str (name, value);
(void)putdef_str (name, value);
}
if (ferror (fp)) {
SYSLOG ((LOG_CRIT, "cannot read login definitions %s [%m]",
def_fname));
exit (1);
if (ferror (fp) != 0) {
int err = errno;
SYSLOG ((LOG_CRIT, "cannot read login definitions %s [%s]",
def_fname, strerror (err)));
exit (EXIT_FAILURE);
}
(void) fclose (fp);
@@ -396,18 +484,22 @@ int main (int argc, char **argv)
def_load ();
for (i = 0; i < NUMDEFS; ++i) {
if ((d = def_find (def_table[i].name)) == NULL)
d = def_find (def_table[i].name);
if (NULL == d) {
printf ("error - lookup '%s' failed\n",
def_table[i].name);
else
def_table[i].name);
} else {
printf ("%4d %-24s %s\n", i + 1, d->name, d->value);
}
}
for (i = 1; i < argc; i++) {
if ((cp = getdef_str (argv[1])) != NULL)
cp = getdef_str (argv[1]);
if (NULL != cp) {
printf ("%s `%s'\n", argv[1], cp);
else
} else {
printf ("%s not found\n", argv[1]);
}
}
exit (0);
exit (EXIT_SUCCESS);
}
#endif

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,11 +33,12 @@
#define _GETDEF_H
/* getdef.c */
extern int getdef_bool (const char *);
extern bool getdef_bool (const char *);
extern long getdef_long (const char *, long);
extern int getdef_num (const char *, int);
extern unsigned long getdef_ulong (const char *, unsigned long);
extern unsigned int getdef_unum (const char *, unsigned int);
extern char *getdef_str (const char *);
extern /*@observer@*/ /*@null@*/const char *getdef_str (const char *);
extern int putdef_str (const char *, const char *);
/* default UMASK value if not specified in /etc/login.defs */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,27 @@
#ident "$Id$"
#include <stdlib.h>
#include <errno.h>
#include "prototypes.h"
#include "defines.h"
int getlong(const char *numstr, long int *result)
/*
* getlong - extract a long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*
* Returns 0 on failure, 1 on success.
*/
int getlong (const char *numstr, /*@out@*/long int *result)
{
long val;
char *endptr;
val = strtol (numstr, &endptr, 10);
if (*endptr || errno == ERANGE)
errno = 0;
val = strtol (numstr, &endptr, 0);
if (('\0' == *numstr) || ('\0' != *endptr) || (ERANGE == errno)) {
return 0;
}
*result = val;
return 1;

65
lib/getulong.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: getlong.c 2763 2009-04-23 09:57:03Z nekral-guest $"
#include <stdlib.h>
#include <errno.h>
#include "prototypes.h"
/*
* getulong - extract an unsigned long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*
* Returns 0 on failure, 1 on success.
*/
int getulong (const char *numstr, /*@out@*/unsigned long int *result)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (numstr, &endptr, 0);
if ( ('\0' == *numstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
/*@+ignoresigns@*/
|| (val != (unsigned long int)val)
/*@=ignoresigns@*/
) {
return 0;
}
*result = (unsigned long int)val;
return 1;
}

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
#ident "$Id$"
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
@@ -43,29 +44,24 @@
#include "getdef.h"
#include "groupio.h"
static struct commonio_entry *merge_group_entries (struct commonio_entry *gr1,
struct commonio_entry *gr2);
static /*@null@*/struct commonio_entry *merge_group_entries (
/*@null@*/ /*@returned@*/struct commonio_entry *gr1,
/*@null@*/struct commonio_entry *gr2);
static int split_groups (unsigned int max_members);
static int group_open_hook (void);
static void *group_dup (const void *ent)
static /*@null@*/ /*@only@*/void *group_dup (const void *ent)
{
const struct group *gr = ent;
return __gr_dup (gr);
}
static void group_free (void *ent)
static void group_free (/*@out@*/ /*@only@*/void *ent)
{
struct group *gr = ent;
free (gr->gr_name);
free (gr->gr_passwd);
while (*(gr->gr_mem)) {
free (*(gr->gr_mem));
gr->gr_mem++;
}
free (gr);
gr_free (gr);
}
static const char *group_getname (const void *ent)
@@ -91,8 +87,9 @@ static int group_close_hook (void)
{
unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0);
if (0 == max_members)
if (0 == max_members) {
return 1;
}
return split_groups (max_members);
}
@@ -109,7 +106,7 @@ static struct commonio_ops group_ops = {
group_close_hook
};
static struct commonio_db group_db = {
static /*@owned@*/struct commonio_db group_db = {
GROUP_FILE, /* filename */
&group_ops, /* ops */
NULL, /* fp */
@@ -119,17 +116,22 @@ static struct commonio_db group_db = {
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0 /* readonly */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int gr_name (const char *filename)
int gr_setdbname (const char *filename)
{
return commonio_setname (&group_db, filename);
}
/*@observer@*/const char *gr_dbname (void)
{
return group_db.filename;
}
int gr_lock (void)
{
return commonio_lock (&group_db);
@@ -140,12 +142,12 @@ int gr_open (int mode)
return commonio_open (&group_db, mode);
}
const struct group *gr_locate (const char *name)
/*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name)
{
return commonio_locate (&group_db, name);
}
const struct group *gr_locate_gid (gid_t gid)
/*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid)
{
const struct group *grp;
@@ -172,7 +174,7 @@ int gr_rewind (void)
return commonio_rewind (&group_db);
}
const struct group *gr_next (void)
/*@observer@*/ /*@null@*/const struct group *gr_next (void)
{
return commonio_next (&group_db);
}
@@ -189,15 +191,15 @@ int gr_unlock (void)
void __gr_set_changed (void)
{
group_db.changed = 1;
group_db.changed = true;
}
struct commonio_entry *__gr_get_head (void)
/*@dependent@*/ /*@null@*/struct commonio_entry *__gr_get_head (void)
{
return group_db.head;
}
struct commonio_db *__gr_get_db (void)
/*@observer@*/const struct commonio_db *__gr_get_db (void)
{
return &group_db;
}
@@ -211,20 +213,23 @@ static int gr_cmp (const void *p1, const void *p2)
{
gid_t u1, u2;
if ((*(struct commonio_entry **) p1)->eptr == NULL)
if ((*(struct commonio_entry **) p1)->eptr == NULL) {
return 1;
if ((*(struct commonio_entry **) p2)->eptr == NULL)
}
if ((*(struct commonio_entry **) p2)->eptr == NULL) {
return -1;
}
u1 = ((struct group *) (*(struct commonio_entry **) p1)->eptr)->gr_gid;
u2 = ((struct group *) (*(struct commonio_entry **) p2)->eptr)->gr_gid;
if (u1 < u2)
if (u1 < u2) {
return -1;
else if (u1 > u2)
} else if (u1 > u2) {
return 1;
else
} else {
return 0;
}
}
/* Sort entries by GID */
@@ -238,11 +243,12 @@ static int group_open_hook (void)
unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0);
struct commonio_entry *gr1, *gr2;
if (0 == max_members)
if (0 == max_members) {
return 1;
}
for (gr1 = group_db.head; gr1; gr1 = gr1->next) {
for (gr2 = gr1->next; gr2; gr2 = gr2->next) {
for (gr1 = group_db.head; NULL != gr1; gr1 = gr1->next) {
for (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) {
struct group *g1 = (struct group *)gr1->eptr;
struct group *g2 = (struct group *)gr2->eptr;
if (NULL != g1 &&
@@ -257,11 +263,15 @@ static int group_open_hook (void)
if (NULL == gr1)
return 0;
/* Unlink gr2 */
if (NULL != gr2->next)
if (NULL != gr2->next) {
gr2->next->prev = gr2->prev;
}
/* gr2 does not start with head */
assert (NULL != gr2->prev);
gr2->prev->next = gr2->next;
}
}
assert (NULL != gr1);
}
return 1;
@@ -279,15 +289,16 @@ static int group_open_hook (void)
* the modified first entry on success, or NULL on failure (with errno
* set).
*/
static struct commonio_entry *merge_group_entries (struct commonio_entry *gr1,
struct commonio_entry *gr2)
static /*@null@*/struct commonio_entry *merge_group_entries (
/*@null@*/ /*@returned@*/struct commonio_entry *gr1,
/*@null@*/struct commonio_entry *gr2)
{
struct group *gptr1;
struct group *gptr2;
char **new_members;
int members = 0;
size_t members = 0;
char *new_line;
int new_line_len, i;
size_t new_line_len, i;
if (NULL == gr2 || NULL == gr1) {
errno = EINVAL;
return NULL;
@@ -316,30 +327,36 @@ static struct commonio_entry *merge_group_entries (struct commonio_entry *gr1,
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = gptr1->gr_mem;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i]))
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;
}
if (NULL == *pmember)
if (NULL == *pmember) {
members++;
}
}
new_members = (char **)malloc ( (members+1) * sizeof(char*) );
if (NULL == new_members) {
free (new_line);
errno = ENOMEM;
return NULL;
}
for (i=0; NULL != gptr1->gr_mem[i]; i++)
for (i=0; NULL != gptr1->gr_mem[i]; i++) {
new_members[i] = gptr1->gr_mem[i];
}
members = i;
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = new_members;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i]))
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;
}
if (NULL == *pmember) {
new_members[members++] = gptr2->gr_mem[i];
new_members[members] = gptr2->gr_mem[i];
members++;
new_members[members] = NULL;
}
}
@@ -360,7 +377,7 @@ static int split_groups (unsigned int max_members)
{
struct commonio_entry *gr;
for (gr = group_db.head; gr; gr = gr->next) {
for (gr = group_db.head; NULL != gr; gr = gr->next) {
struct group *gptr = (struct group *)gr->eptr;
struct commonio_entry *new;
struct group *new_gptr;
@@ -382,12 +399,13 @@ static int split_groups (unsigned int max_members)
}
new->eptr = group_dup(gr->eptr);
if (NULL == new->eptr) {
free (new);
errno = ENOMEM;
return 0;
}
new_gptr = (struct group *)new->eptr;
new->line = NULL;
new->changed = 1;
new->changed = true;
/* Enforce the maximum number of members on gptr */
gptr->gr_mem[max_members] = NULL;

View File

@@ -31,17 +31,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _GROUPIO_H
#define _GROUPIO_H
#include <sys/types.h>
#include <grp.h>
extern int gr_close (void);
extern const struct group *gr_locate (const char *);
extern const struct group *gr_locate_gid (gid_t gid);
extern /*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name);
extern /*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid);
extern int gr_lock (void);
extern int gr_name (const char *);
extern const struct group *gr_next (void);
extern int gr_open (int);
extern int gr_remove (const char *);
extern int gr_setdbname (const char *filename);
extern /*@observer@*/const char *gr_dbname (void);
extern /*@observer@*/ /*@null@*/const struct group *gr_next (void);
extern int gr_open (int mode);
extern int gr_remove (const char *name);
extern int gr_rewind (void);
extern int gr_unlock (void);
extern int gr_update (const struct group *);
extern int gr_update (const struct group *gr);
extern int gr_sort (void);
#endif

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,29 +39,51 @@
#include "defines.h"
#include "groupio.h"
struct group *__gr_dup (const struct group *grent)
/*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent)
{
struct group *gr;
int i;
if (!(gr = (struct group *) malloc (sizeof *gr)))
gr = (struct group *) malloc (sizeof *gr);
if (NULL == gr) {
return NULL;
}
*gr = *grent;
if (!(gr->gr_name = strdup (grent->gr_name)))
gr->gr_name = strdup (grent->gr_name);
if (NULL == gr->gr_name) {
return NULL;
if (!(gr->gr_passwd = strdup (grent->gr_passwd)))
}
gr->gr_passwd = strdup (grent->gr_passwd);
if (NULL == gr->gr_passwd) {
return NULL;
}
for (i = 0; grent->gr_mem[i]; i++);
gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
if (!gr->gr_mem)
if (NULL == gr->gr_mem) {
return NULL;
}
for (i = 0; grent->gr_mem[i]; i++) {
gr->gr_mem[i] = strdup (grent->gr_mem[i]);
if (!gr->gr_mem[i])
if (NULL == gr->gr_mem[i]) {
return NULL;
}
}
gr->gr_mem[i] = NULL;
return gr;
}
void gr_free (/*@out@*/ /*@only@*/struct group *grent)
{
free (grent->gr_name);
memzero (grent->gr_passwd, strlen (grent->gr_passwd));
free (grent->gr_passwd);
while (*(grent->gr_mem)) {
free (*(grent->gr_mem));
grent->gr_mem++;
}
free (grent);
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,21 +40,20 @@
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
static FILE *shadow;
static char sgrbuf[BUFSIZ * 4];
static char **members = NULL;
static /*@null@*/FILE *shadow;
static /*@null@*//*@only@*/char **members = NULL;
static size_t nmembers = 0;
static char **admins = NULL;
static /*@null@*//*@only@*/char **admins = NULL;
static size_t nadmins = 0;
static struct sgrp sgroup;
#define FIELDS 4
#ifdef USE_NIS
static int nis_used;
static int nis_ignore;
static bool nis_used;
static bool nis_ignore;
static enum { native, start, middle, native2 } nis_state;
static int nis_bound;
static bool nis_bound;
static char *nis_domain;
static char *nis_key;
static int nis_keylen;
@@ -65,19 +64,6 @@ static int nis_vallen;
#endif
#ifdef USE_NIS
/*
* __setsgNIS - turn on or off NIS searches
*/
void __setsgNIS (int flag)
{
nis_ignore = !flag;
if (nis_ignore)
nis_used = 0;
}
/*
* bind_nis - bind to NIS server
*/
@@ -87,29 +73,35 @@ static int bind_nis (void)
if (yp_get_default_domain (&nis_domain))
return -1;
nis_bound = 1;
nis_bound = true;
return 0;
}
#endif
static char **build_list (char *s, char **list[], size_t * nlist)
static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
{
char **ptr = *list;
size_t nelem = *nlist, size;
while (s != NULL && *s != '\0') {
size = (nelem + 1) * sizeof (ptr);
if ((ptr = realloc (*list, size)) != NULL) {
ptr[nelem++] = s;
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = s;
nelem++;
*list = ptr;
*nlist = nelem;
if ((s = strchr (s, ',')))
*s++ = '\0';
s = strchr (s, ',');
if (NULL != s) {
*s = '\0';
s++;
}
}
}
size = (nelem + 1) * sizeof (ptr);
if ((ptr = realloc (*list, size)) != NULL) {
ptr[nelem] = '\0';
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = NULL;
*list = ptr;
}
return ptr;
@@ -120,41 +112,60 @@ void setsgent (void)
#ifdef USE_NIS
nis_state = native;
#endif
if (shadow)
if (NULL != shadow) {
rewind (shadow);
else
} else {
shadow = fopen (SGROUP_FILE, "r");
}
}
void endsgent (void)
{
if (shadow)
if (NULL != shadow) {
(void) fclose (shadow);
}
shadow = (FILE *) 0;
}
struct sgrp *sgetsgent (const char *string)
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
{
static char *sgrbuf = NULL;
static size_t sgrbuflen = 0;
char *fields[FIELDS];
char *cp;
int i;
size_t len = strlen (string) + 1;
strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1);
sgrbuf[sizeof sgrbuf - 1] = '\0';
if (len > sgrbuflen) {
char *buf = (char *) realloc (sgrbuf, sizeof (char) * len);
if (NULL == buf) {
return NULL;
}
sgrbuf = buf;
sgrbuflen = len;
}
if ((cp = strrchr (sgrbuf, '\n')))
strncpy (sgrbuf, string, len);
sgrbuf[len-1] = '\0';
cp = strrchr (sgrbuf, '\n');
if (NULL != cp) {
*cp = '\0';
}
/*
* There should be exactly 4 colon separated fields. Find
* all 4 of them and save the starting addresses in fields[].
*/
for (cp = sgrbuf, i = 0; i < FIELDS && cp; i++) {
for (cp = sgrbuf, i = 0; (i < FIELDS) && (NULL != cp); i++) {
fields[i] = cp;
if ((cp = strchr (cp, ':')))
cp = strchr (cp, ':');
if (NULL != cp) {
*cp++ = '\0';
}
}
/*
@@ -162,24 +173,26 @@ struct sgrp *sgetsgent (const char *string)
* the line is invalid.
*/
if (cp || i != FIELDS)
if ((NULL != cp) || (i != FIELDS)) {
#ifdef USE_NIS
if (!IS_NISCHAR (fields[0][0]))
if (!IS_NISCHAR (fields[0][0])) {
return 0;
else
nis_used = 1;
} else {
nis_used = true;
}
#else
return 0;
#endif
}
sgroup.sg_name = fields[0];
sgroup.sg_passwd = fields[1];
if (nadmins) {
if (0 != nadmins) {
nadmins = 0;
free (admins);
admins = NULL;
}
if (nmembers) {
if (0 != nmembers) {
nmembers = 0;
free (members);
members = NULL;
@@ -197,44 +210,76 @@ struct sgrp *sgetsgent (const char *string)
* converts it to a (struct sgrp). NULL is returned on EOF.
*/
struct sgrp *fgetsgent (FILE * fp)
/*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE * fp)
{
char buf[sizeof sgrbuf];
char *cp;
static size_t buflen = 0;
static char *buf = NULL;
if (!fp)
return (0);
char *cp;
struct sgrp *ret;
if (0 == buflen) {
buf = (char *) malloc (BUFSIZ);
if (NULL == buf) {
return NULL;
}
}
if (NULL == fp) {
return NULL;
}
#ifdef USE_NIS
while (fgetsx (buf, sizeof buf, fp) != (char *) 0)
while (fgetsx (buf, (int) sizeof buf, fp) == buf)
#else
if (fgetsx (buf, sizeof buf, fp) != (char *) 0)
if (fgetsx (buf, (int) sizeof buf, fp) == buf)
#endif
{
if ((cp = strchr (buf, '\n')))
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (fp) == 0)) {
size_t len;
cp = (char *) realloc (buf, buflen*2);
if (NULL == cp) {
return NULL;
}
buf = cp;
buflen *= 2;
len = strlen (buf);
if (fgetsx (&buf[len],
(int) (buflen - len),
fp) != &buf[len]) {
return NULL;
}
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0]))
if (nis_ignore && IS_NISCHAR (buf[0])) {
continue;
}
#endif
return (sgetsgent (buf));
}
return 0;
return NULL;
}
/*
* getsgent - get a single shadow group entry
*/
struct sgrp *getsgent (void)
/*@observer@*//*@null@*/struct sgrp *getsgent (void)
{
#ifdef USE_NIS
int nis_1_group = 0;
bool nis_1_group = false;
struct sgrp *val;
char buf[BUFSIZ];
#endif
if (!shadow)
if (NULL == shadow) {
setsgent ();
}
#ifdef USE_NIS
again:
@@ -249,8 +294,10 @@ struct sgrp *getsgent (void)
* NULL right away if there is none.
*/
if (!(val = fgetsgent (shadow)))
val = fgetsgent (shadow);
if (NULL == val) {
return 0;
}
/*
* If this entry began with a NIS escape character, we have
@@ -259,10 +306,11 @@ struct sgrp *getsgent (void)
*/
if (IS_NISCHAR (val->sg_name[0])) {
if (val->sg_name[1])
nis_1_group = 1;
else
if ('\0' != val->sg_name[1]) {
nis_1_group = true;
} else {
nis_state = start;
}
}
/*
@@ -270,16 +318,18 @@ struct sgrp *getsgent (void)
* use a NIS map, it must be a regular local group.
*/
if (nis_1_group == 0 && nis_state != start)
if (!nis_1_group && (nis_state != start)) {
return val;
}
/*
* If this is an escape to use an NIS map, switch over to
* that bunch of code.
*/
if (nis_state == start)
if (nis_state == start) {
goto again;
}
/*
* NEEDSWORK. Here we substitute pieces-parts of this entry.
@@ -287,7 +337,7 @@ struct sgrp *getsgent (void)
return 0;
} else {
if (nis_bound == 0) {
if (!nis_bound) {
if (bind_nis ()) {
nis_state = native2;
goto again;
@@ -319,12 +369,11 @@ struct sgrp *getsgent (void)
* getsgnam - get a shadow group entry by name
*/
struct sgrp *getsgnam (const char *name)
/*@observer@*//*@null@*/struct sgrp *getsgnam (const char *name)
{
struct sgrp *sgrp;
#ifdef USE_NIS
char buf[BUFSIZ];
static char save_name[16];
int nis_disabled = 0;
#endif
@@ -339,8 +388,9 @@ struct sgrp *getsgnam (const char *name)
* Search the gshadow.byname map for this group.
*/
if (!nis_bound)
if (!nis_bound) {
bind_nis ();
}
if (nis_bound) {
char *cp;
@@ -348,11 +398,14 @@ struct sgrp *getsgnam (const char *name)
if (yp_match (nis_domain, "gshadow.byname", name,
strlen (name), &nis_val,
&nis_vallen) == 0) {
if (cp = strchr (nis_val, '\n'))
cp = strchr (nis_val, '\n');
if (NULL != cp) {
*cp = '\0';
}
nis_state = middle;
if (sgrp = sgetsgent (nis_val)) {
sgrp = sgetsgent (nis_val);
if (NULL != sgrp) {
strcpy (save_name, sgrp->sg_name);
nis_key = save_name;
nis_keylen = strlen (save_name);
@@ -365,20 +418,19 @@ struct sgrp *getsgnam (const char *name)
#endif
#ifdef USE_NIS
if (nis_used) {
nis_ignore++;
nis_disabled++;
nis_ignore = true;
nis_disabled = true;
}
#endif
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
if (strcmp (name, sgrp->sg_name) == 0)
if (strcmp (name, sgrp->sg_name) == 0) {
break;
}
}
#ifdef USE_NIS
nis_ignore--;
nis_ignore = false;
#endif
if (sgrp)
return sgrp;
return (0);
return sgrp;
}
/*
@@ -395,19 +447,23 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
int i;
size_t size;
if (!fp || !sgrp)
if ((NULL == fp) || (NULL == sgrp)) {
return -1;
}
/* calculate the required buffer size */
size = strlen (sgrp->sg_name) + strlen (sgrp->sg_passwd) + 10;
for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++)
for (i = 0; (NULL != sgrp->sg_adm) && (NULL != sgrp->sg_adm[i]); i++) {
size += strlen (sgrp->sg_adm[i]) + 1;
for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++)
}
for (i = 0; (NULL != sgrp->sg_mem) && (NULL != sgrp->sg_mem[i]); i++) {
size += strlen (sgrp->sg_mem[i]) + 1;
}
buf = malloc (size);
if (!buf)
if (NULL == buf) {
return -1;
}
cp = buf;
/*
@@ -427,27 +483,32 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
* with a ",".
*/
for (i = 0; sgrp->sg_adm[i]; i++) {
if (i > 0)
for (i = 0; NULL != sgrp->sg_adm[i]; i++) {
if (i > 0) {
*cp++ = ',';
}
strcpy (cp, sgrp->sg_adm[i]);
cp += strlen (cp);
}
*cp++ = ':';
*cp = ':';
cp++;
/*
* Now do likewise with the group members.
*/
for (i = 0; sgrp->sg_mem[i]; i++) {
if (i > 0)
*cp++ = ',';
for (i = 0; NULL != sgrp->sg_mem[i]; i++) {
if (i > 0) {
*cp = ',';
cp++;
}
strcpy (cp, sgrp->sg_mem[i]);
cp += strlen (cp);
}
*cp++ = '\n';
*cp = '\n';
cp++;
*cp = '\0';
/*

View File

@@ -54,18 +54,18 @@ struct sgrp {
#include <stdio.h> /* for FILE */
#if __STDC__
struct sgrp *getsgent (void);
struct sgrp *getsgnam (const char *);
struct sgrp *sgetsgent (const char *);
struct sgrp *fgetsgent (FILE *);
/*@observer@*//*@null@*/struct sgrp *getsgent (void);
/*@observer@*//*@null@*/struct sgrp *getsgnam (const char *);
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *);
/*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE *);
void setsgent (void);
void endsgent (void);
int putsgent (const struct sgrp *, FILE *);
#else
struct sgrp *getsgent ();
struct sgrp *getsgnam ();
struct sgrp *sgetsgent ();
struct sgrp *fgetsgent ();
/*@observer@*//*@null@*/struct sgrp *getsgent ();
/*@observer@*//*@null@*/struct sgrp *getsgnam ();
/*@observer@*//*@null@*/struct sgrp *sgetsgent ();
/*@observer@*//*@null@*/struct sgrp *fgetsgent ();
void setsgent ();
void endsgent ();
int putsgent ();

View File

@@ -1,7 +1,12 @@
/* Author: Peter Vrabec <pvrabec@redhat.com> */
#include <config.h>
#ifdef USE_NSCD
/* because of TEMP_FAILURE_RETRY */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <features.h>
#include <stdio.h>
@@ -11,8 +16,11 @@
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "defines.h"
#include "nscd.h"
#define MSG_NSCD_FLUSH_CACHE_FAILED "Failed to flush the nscd cache.\n"
/*
* nscd_flush_cache - flush specified service buffer in nscd cache
*/
@@ -24,27 +32,34 @@ int nscd_flush_cache (const char *service)
char *spawnedEnv[] = {NULL};
/* spawn process */
if( (err=posix_spawn(&pid, spawnedArgs[0], NULL, NULL,
spawnedArgs, spawnedEnv)) !=0 )
err = posix_spawn (&pid, spawnedArgs[0], NULL, NULL,
spawnedArgs, spawnedEnv);
if(0 != err)
{
fprintf(stderr, "posix_spawn() error=%d\n", err);
(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
(void) fprintf (stderr, "posix_spawn() error=%d\n", err);
return -1;
}
/* Wait for the spawned process to exit */
/* Wait for the spawned process to exit */
termpid = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
if (termpid == -1)
if (-1 == termpid)
{
(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
perror("waitpid");
return -1;
}
else if (termpid != pid)
{
fprintf(stderr, "waitpid returned %ld != %ld\n",
(long int) termpid, (long int) pid);
(void) fputs (_(MSG_NSCD_FLUSH_CACHE_FAILED), stderr);
(void) fprintf (stderr, "waitpid returned %ld != %ld\n",
(long int) termpid, (long int) pid);
return -1;
}
return 0;
}
#else /* USE_NSCD */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* USE_NSCD */

View File

@@ -4,6 +4,10 @@
/*
* nscd_flush_cache - flush specified service buffer in nscd cache
*/
#ifdef USE_NSCD
extern int nscd_flush_cache (const char *service);
#else
#define nscd_flush_cache(service) (0)
#endif
#endif

View File

@@ -28,24 +28,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#ifdef HAVE_SECURITY_PAM_MISC_H
# include <security/pam_misc.h>
#endif
#ifdef HAVE_SECURITY_OPENPAM_H
# include <security/openpam.h>
#endif
static struct pam_conv conv = {
misc_conv,
SHADOW_PAM_CONVERSATION,
NULL
};
/* compatibility with different versions of Linux-PAM */
#ifndef PAM_ESTABLISH_CRED
#if !HAVE_DECL_PAM_ESTABLISH_CRED
#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH
#endif
#ifndef PAM_DELETE_CRED
#if !HAVE_DECL_PAM_DELETE_CRED
#define PAM_DELETE_CRED PAM_CRED_DELETE
#endif
#ifndef PAM_NEW_AUTHTOK_REQD
#if !HAVE_DECL_PAM_NEW_AUTHTOK_REQD
#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD
#endif
#ifndef PAM_DATA_SILENT
#if !HAVE_DECL_PAM_DATA_SILENT
#define PAM_DATA_SILENT 0
#endif

View File

@@ -57,15 +57,19 @@ static int portcmp (const char *pattern, const char *port)
{
const char *orig = port;
while (*pattern && *pattern == *port)
pattern++, port++;
while (('\0' != *pattern) && (*pattern == *port)) {
pattern++;
port++;
}
if (*pattern == 0 && *port == 0)
if (('\0' == *pattern) && ('\0' == *port)) {
return 0;
if (orig[0] == 'S' && orig[1] == 'U' && orig[2] == '\0')
}
if (('S' == orig[0]) && ('U' == orig[1]) && ('\0' == orig[2])) {
return 1;
}
return *pattern == '*' ? 0 : 1;
return (*pattern == '*') ? 0 : 1;
}
/*
@@ -77,10 +81,11 @@ static int portcmp (const char *pattern, const char *port)
static void setportent (void)
{
if (ports)
if (NULL != ports) {
rewind (ports);
else
} else {
ports = fopen (PORTS, "r");
}
}
/*
@@ -93,8 +98,9 @@ static void setportent (void)
static void endportent (void)
{
if (ports)
fclose (ports);
if (NULL != ports) {
(void) fclose (ports);
}
ports = (FILE *) 0;
}
@@ -125,10 +131,11 @@ static struct port *getportent (void)
* since we want to search from the beginning each time.
*/
if (!ports)
if (NULL == ports) {
setportent ();
}
if (!ports) {
if (NULL == ports) {
errno = saveerr;
return 0;
}
@@ -150,12 +157,13 @@ static struct port *getportent (void)
* is a '\n'. Lines which begin with '#' are all ignored.
*/
if (fgets (buf, sizeof buf, ports) == 0) {
if (fgets (buf, (int) sizeof buf, ports) == 0) {
errno = saveerr;
return 0;
}
if (buf[0] == '#')
if ('#' == buf[0]) {
goto again;
}
/*
* Get the name of the TTY device. It is the first colon
@@ -169,19 +177,24 @@ static struct port *getportent (void)
port.pt_names = ttys;
for (cp = buf, j = 0; j < PORT_TTY; j++) {
port.pt_names[j] = cp;
while (*cp && *cp != ':' && *cp != ',')
while (('\0' != *cp) && (':' != *cp) && (',' != *cp)) {
cp++;
}
if (!*cp)
if ('\0' == *cp) {
goto again; /* line format error */
}
if (*cp == ':') /* end of tty name list */
if (':' == *cp) { /* end of tty name list */
break;
}
if (*cp == ',') /* end of current tty name */
if (',' == *cp) { /* end of current tty name */
*cp++ = '\0';
}
}
*cp++ = 0;
*cp = '\0';
cp++;
port.pt_names[j + 1] = (char *) 0;
/*
@@ -191,24 +204,29 @@ static struct port *getportent (void)
* The last entry in the list is a (char *) 0 pointer.
*/
if (*cp != ':') {
if (':' != *cp) {
port.pt_users = users;
port.pt_users[0] = cp;
for (j = 1; *cp != ':'; cp++) {
if (*cp == ',' && j < PORT_IDS) {
*cp++ = 0;
port.pt_users[j++] = cp;
for (j = 1; ':' != *cp; cp++) {
if ((',' == *cp) && (j < PORT_IDS)) {
*cp = '\0';
cp++;
port.pt_users[j] = cp;
j++;
}
}
port.pt_users[j] = 0;
} else
} else {
port.pt_users = 0;
}
if (*cp != ':')
if (':' != *cp) {
goto again;
}
*cp++ = 0;
*cp = '\0';
cp++;
/*
* Get the list of valid times. The times field is the third
@@ -223,7 +241,7 @@ static struct port *getportent (void)
* the starting time. Days are presumed to wrap at 0000.
*/
if (*cp == '\0') {
if ('\0' == *cp) {
port.pt_times = 0;
return &port;
}
@@ -234,7 +252,7 @@ static struct port *getportent (void)
* Get the next comma separated entry
*/
for (j = 0; *cp && j < PORT_TIMES; j++) {
for (j = 0; ('\0' != *cp) && (j < PORT_TIMES); j++) {
/*
* Start off with no days of the week
@@ -248,7 +266,9 @@ static struct port *getportent (void)
* week or the other two values.
*/
for (i = 0; cp[i] && cp[i + 1] && isalpha (cp[i]); i += 2) {
for (i = 0;
('\0' != cp[i]) && ('\0' != cp[i + 1]) && isalpha (cp[i]);
i += 2) {
switch ((cp[i] << 8) | (cp[i + 1])) {
case ('S' << 8) | 'u':
port.pt_times[j].t_days |= 01;
@@ -287,8 +307,9 @@ static struct port *getportent (void)
* The default is 'Al' if no days were seen.
*/
if (i == 0)
if (0 == i) {
port.pt_times[j].t_days = 0177;
}
/*
* The start and end times are separated from each
@@ -296,19 +317,27 @@ static struct port *getportent (void)
* representing the times of day.
*/
for (dtime = 0; cp[i] && isdigit (cp[i]); i++)
for (dtime = 0; ('\0' != cp[i]) && isdigit (cp[i]); i++) {
dtime = dtime * 10 + cp[i] - '0';
}
if (cp[i] != '-' || dtime > 2400 || dtime % 100 > 59)
if (('-' != cp[i]) || (dtime > 2400) || ((dtime % 100) > 59)) {
goto again;
}
port.pt_times[j].t_start = dtime;
cp = cp + i + 1;
for (dtime = i = 0; cp[i] && isdigit (cp[i]); i++)
for (dtime = 0, i = 0;
('\0' != cp[i]) && isdigit (cp[i]);
i++) {
dtime = dtime * 10 + cp[i] - '0';
}
if ((cp[i] != ',' && cp[i]) || dtime > 2400 || dtime % 100 > 59)
if ( ((',' != cp[i]) && ('\0' != cp[i]))
|| (dtime > 2400)
|| ((dtime % 100) > 59)) {
goto again;
}
port.pt_times[j].t_end = dtime;
cp = cp + i + 1;
@@ -340,24 +369,32 @@ static struct port *getttyuser (const char *tty, const char *user)
setportent ();
while ((port = getportent ())) {
if (port->pt_names == 0 || port->pt_users == 0)
while ((port = getportent ()) != NULL) {
if ( (0 == port->pt_names)
|| (0 == port->pt_users)) {
continue;
}
for (i = 0; port->pt_names[i]; i++)
if (portcmp (port->pt_names[i], tty) == 0)
for (i = 0; NULL != port->pt_names[i]; i++) {
if (portcmp (port->pt_names[i], tty) == 0) {
break;
}
}
if (port->pt_names[i] == 0)
if (port->pt_names[i] == 0) {
continue;
}
for (j = 0; port->pt_users[j]; j++)
if (strcmp (user, port->pt_users[j]) == 0 ||
strcmp (port->pt_users[j], "*") == 0)
for (j = 0; NULL != port->pt_users[j]; j++) {
if ( (strcmp (user, port->pt_users[j]) == 0)
|| (strcmp (port->pt_users[j], "*") == 0)) {
break;
}
}
if (port->pt_users[j] != 0)
if (port->pt_users[j] != 0) {
break;
}
}
endportent ();
return port;
@@ -370,7 +407,7 @@ static struct port *getttyuser (const char *tty, const char *user)
* the user name and TTY given.
*/
int isttytime (const char *id, const char *port, time_t when)
bool isttytime (const char *id, const char *port, time_t when)
{
int i;
int dtime;
@@ -379,24 +416,27 @@ int isttytime (const char *id, const char *port, time_t when)
/*
* Try to find a matching entry for this user. Default to
* letting the user in - there are pleny of ways to have an
* letting the user in - there are plenty of ways to have an
* entry to match all users.
*/
if (!(pp = getttyuser (port, id)))
return 1;
pp = getttyuser (port, id);
if (NULL == pp) {
return true;
}
/*
* The entry is there, but has no time entries - don't
* ever let them login.
*/
if (pp->pt_times == 0)
return 0;
if (0 == pp->pt_times) {
return false;
}
/*
* The current time is converted to HHMM format for
* comparision against the time values in the TTY entry.
* comparison against the time values in the TTY entry.
*/
tm = localtime (&when);
@@ -405,22 +445,25 @@ int isttytime (const char *id, const char *port, time_t when)
/*
* Each time entry is compared against the current
* time. For entries with the start after the end time,
* the comparision is made so that the time is between
* the comparison is made so that the time is between
* midnight and either the start or end time.
*/
for (i = 0; pp->pt_times[i].t_start != -1; i++) {
if (!(pp->pt_times[i].t_days & PORT_DAY (tm->tm_wday)))
if (!(pp->pt_times[i].t_days & PORT_DAY (tm->tm_wday))) {
continue;
}
if (pp->pt_times[i].t_start <= pp->pt_times[i].t_end) {
if (dtime >= pp->pt_times[i].t_start &&
dtime <= pp->pt_times[i].t_end)
return 1;
if ( (dtime >= pp->pt_times[i].t_start)
&& (dtime <= pp->pt_times[i].t_end)) {
return true;
}
} else {
if (dtime >= pp->pt_times[i].t_start ||
dtime <= pp->pt_times[i].t_end)
return 1;
if ( (dtime >= pp->pt_times[i].t_start)
|| (dtime <= pp->pt_times[i].t_end)) {
return true;
}
}
}
@@ -429,5 +472,6 @@ int isttytime (const char *id, const char *port, time_t when)
* be let in right now.
*/
return 0;
return false;
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,11 +43,12 @@
#define _PROTOTYPES_H
#include <sys/stat.h>
#if HAVE_UTMPX_H
#ifdef USE_UTMPX
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <shadow.h>
@@ -56,14 +57,18 @@
#include "defines.h"
#include "commonio.h"
extern char *Prog;
/* addgrps.c */
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
extern int add_groups (const char *);
extern void add_cons_grps (void);
#endif
/* age.c */
extern void agecheck (const struct passwd *, const struct spwd *);
extern int expire (const struct passwd *, const struct spwd *);
extern int isexpired (const struct passwd *, const struct spwd *);
extern void agecheck (/*@null@*/const struct spwd *);
extern int expire (const struct passwd *, /*@null@*/const struct spwd *);
/* isexpired.c */
extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *);
/* basename() renamed to Basename() to avoid libc name space confusion */
/* basename.c */
@@ -73,16 +78,51 @@ extern char *Basename (char *str);
extern int chown_tree (const char *, uid_t, uid_t, gid_t, gid_t);
/* chowntty.c */
extern void chown_tty (const char *, const struct passwd *);
extern void chown_tty (const struct passwd *);
/* cleanup.c */
typedef void (*cleanup_function) (/*@null@*/void *arg);
void add_cleanup (cleanup_function pcf, /*@null@*/void *arg);
void del_cleanup (cleanup_function pcf);
void do_cleanups (void);
/* cleanup_group.c */
struct cleanup_info_mod {
char *audit_msg;
char *action;
char *name;
};
void cleanup_report_add_group (void *group_name);
void cleanup_report_add_group_group (void *group_name);
#ifdef SHADOWGRP
void cleanup_report_add_group_gshadow (void *group_name);
#endif
void cleanup_report_del_group (void *group_name);
void cleanup_report_del_group_group (void *group_name);
#ifdef SHADOWGRP
void cleanup_report_del_group_gshadow (void *group_name);
#endif
void cleanup_report_mod_passwd (void *cleanup_info);
void cleanup_report_mod_group (void *cleanup_info);
void cleanup_report_mod_gshadow (void *cleanup_info);
void cleanup_unlock_group (/*@null@*/void *unused);
#ifdef SHADOWGRP
void cleanup_unlock_gshadow (/*@null@*/void *unused);
#endif
void cleanup_unlock_passwd (/*@null@*/void *unused);
/* console.c */
extern int console (const char *);
extern bool console (const char *);
/* copydir.c */
extern int copy_tree (const char *src_root, const char *dst_root,
long int uid, long int gid);
extern int remove_tree (const char *root);
#ifdef WITH_SELINUX
extern int selinux_file_context (const char *dst_name);
#endif
/* encrypt.c */
extern char *pw_encrypt (const char *, const char *);
@@ -90,7 +130,7 @@ extern char *pw_encrypt (const char *, const char *);
extern void pw_entry (const char *, struct passwd *);
/* env.c */
extern void addenv (const char *, const char *);
extern void addenv (const char *, /*@null@*/const char *);
extern void initenv (void);
extern void set_env (int, char *const *);
extern void sanitize_env (void);
@@ -99,28 +139,55 @@ extern void sanitize_env (void);
extern void change_field (char *, size_t, const char *);
extern int valid_field (const char *, const char *);
/* find_new_ids.c */
extern int find_new_uid (int sys_user, uid_t *uid, uid_t const *preferred_uid);
extern int find_new_gid (int sys_group, gid_t *gid, gid_t const *preferred_gid);
/* find_new_gid.c */
extern int find_new_gid (bool sys_group,
gid_t *gid,
/*@null@*/gid_t const *preferred_gid);
/* find_new_uid.c */
extern int find_new_uid (bool sys_user,
uid_t *uid,
/*@null@*/uid_t const *preferred_uid);
/* get_gid.c */
extern int get_gid (const char *gidstr, gid_t *gid);
/* getgr_nam_gid.c */
extern /*@null@*/struct group *getgr_nam_gid (const char *grname);
/* getlong.c */
extern int getlong(const char *numstr, long int *result);
extern int getlong (const char *numstr, /*@out@*/long int *result);
/* get_pid.c */
extern int get_pid (const char *pidstr, pid_t *pid);
/* getrange */
extern int getrange (char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max);
/* get_uid.c */
extern int get_uid (const char *uidstr, uid_t *uid);
/* getulong.c */
extern int getulong (const char *numstr, /*@out@*/unsigned long int *result);
/* fputsx.c */
extern char *fgetsx (char *, int, FILE *);
extern /*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *, int, FILE *);
extern int fputsx (const char *, FILE *);
/* groupio.c */
extern void __gr_del_entry (const struct commonio_entry *ent);
extern struct commonio_db *__gr_get_db (void);
extern struct commonio_entry *__gr_get_head (void);
extern /*@observer@*/const struct commonio_db *__gr_get_db (void);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__gr_get_head (void);
extern void __gr_set_changed (void);
/* groupmem.c */
extern struct group *__gr_dup (const struct group *grent);
extern /*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent);
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
/* hushed.c */
extern int hushed (const struct passwd *);
extern bool hushed (const char *username);
/* audit_help.c */
#ifdef WITH_AUDIT
@@ -128,25 +195,33 @@ extern int audit_fd;
extern void audit_help_open (void);
/* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */
#define AUDIT_NO_ID ((unsigned int) -1)
typedef enum {
SHADOW_AUDIT_FAILURE = 0,
SHADOW_AUDIT_SUCCESS = 1} shadow_audit_result;
extern void audit_logger (int type, const char *pgname, const char *op,
const char *name, unsigned int id, int result);
const char *name, unsigned int id,
shadow_audit_result result);
void audit_logger_message (const char *message, shadow_audit_result result);
#endif
/* limits.c */
#ifndef USE_PAM
extern void setup_limits (const struct passwd *);
#endif
/* list.c */
extern char **add_list (char **, const char *);
extern char **del_list (char **, const char *);
extern char **dup_list (char *const *);
extern int is_on_list (char *const *, const char *);
extern char **comma_to_list (const char *);
extern /*@only@*/ /*@out@*/char **add_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **del_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **dup_list (char *const *);
extern bool is_on_list (char *const *list, const char *member);
extern /*@only@*/char **comma_to_list (const char *);
/* log.c */
extern void dolastlog (struct lastlog *ll,
const struct passwd *pw,
const char *line,
const char *host);
extern void dolastlog (
struct lastlog *ll,
const struct passwd *pw,
/*@unique@*/const char *line,
/*@unique@*/const char *host);
/* login_nopam.c */
extern int login_access (const char *user, const char *from);
@@ -161,22 +236,37 @@ extern void mailcheck (void);
extern void motd (void);
/* myname.c */
extern struct passwd *get_my_pwent (void);
extern /*@null@*/struct passwd *get_my_pwent (void);
/* pam_pass_non_interractive.c */
#ifdef USE_PAM
extern int do_pam_passwd_non_interractive (const char *pam_service,
const char *username,
const char* password);
#endif /* USE_PAM */
/* obscure.c */
#ifndef USE_PAM
extern int obscure (const char *, const char *, const struct passwd *);
#endif
/* pam_pass.c */
extern void do_pam_passwd (const char *, int, int);
#ifdef USE_PAM
extern void do_pam_passwd (const char *user, bool silent, bool change_expired);
#endif
/* port.c */
extern int isttytime (const char *, const char *, time_t);
extern bool isttytime (const char *, const char *, time_t);
/* pwd2spwd.c */
#ifndef USE_PAM
extern struct spwd *pwd_to_spwd (const struct passwd *);
#endif
/* pwdcheck.c */
#ifndef USE_PAM
extern void passwd_check (const char *, const char *, const char *);
#endif
/* pwd_init.c */
extern void pwd_init (void);
@@ -184,21 +274,27 @@ extern void pwd_init (void);
/* pwio.c */
extern void __pw_del_entry (const struct commonio_entry *ent);
extern struct commonio_db *__pw_get_db (void);
extern struct commonio_entry *__pw_get_head (void);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__pw_get_head (void);
/* pwmem.c */
extern struct passwd *__pw_dup (const struct passwd *pwent);
extern /*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent);
extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
/* rlogin.c */
extern int do_rlogin (const char *, char *, int, char *, int);
extern int do_rlogin (const char *remote_host, char *name, size_t namelen,
char *term, size_t termlen);
/* salt.c */
extern char *crypt_make_salt (const char *meth, void *arg);
extern /*@observer@*/const char *crypt_make_salt (/*@null@*/const char *meth, /*@null@*/void *arg);
/* setugid.c */
extern int setup_groups (const struct passwd *);
extern int change_uid (const struct passwd *);
extern int setup_uid_gid (const struct passwd *, int);
extern int setup_groups (const struct passwd *info);
extern int change_uid (const struct passwd *info);
#if (defined HAVE_INITGROUPS) && (! defined USE_PAM)
extern int setup_uid_gid (const struct passwd *info, bool is_console);
#else
extern int setup_uid_gid (const struct passwd *info);
#endif
/* setup.c */
extern void setup (struct passwd *);
@@ -212,21 +308,34 @@ extern struct group *sgetgrent (const char *buf);
/* sgetpwent.c */
extern struct passwd *sgetpwent (const char *buf);
/* sgetspent.c */
#ifndef HAVE_SGETSPENT
extern struct spwd *sgetspent (const char *string);
#endif
/* sgroupio.c */
extern void __sgr_del_entry (const struct commonio_entry *ent);
extern struct sgrp *__sgr_dup (const struct sgrp *sgent);
extern struct commonio_entry *__sgr_get_head (void);
extern /*@null@*/ /*@only@*/struct sgrp *__sgr_dup (const struct sgrp *sgent);
extern void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__sgr_get_head (void);
extern void __sgr_set_changed (void);
/* shadowio.c */
extern struct commonio_entry *__spw_get_head (void);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__spw_get_head (void);
extern void __spw_del_entry (const struct commonio_entry *ent);
/* shadowmem.c */
extern struct spwd *__spw_dup (const struct spwd *spent);
extern /*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent);
extern void spw_free (/*@out@*/ /*@only@*/struct spwd *spent);
/* shell.c */
extern int shell (const char *, const char *, char *const *);
extern int shell (const char *file, /*@null@*/const char *arg, char *const envp[]);
/* system.c */
extern int safe_system (const char *command,
const char *argv[],
const char *env[],
int ignore_stderr);
/* strtoday.c */
extern long strtoday (const char *);
@@ -235,7 +344,10 @@ extern long strtoday (const char *);
extern int check_su_auth (const char *actual_id, const char *wanted_id);
/* sulog.c */
extern void sulog (const char *, int, const char *, const char *);
extern void sulog (const char *tty,
bool success,
const char *oldname,
const char *name);
/* sub.c */
extern void subsystem (const struct passwd *);
@@ -244,34 +356,51 @@ extern void subsystem (const struct passwd *);
extern void ttytype (const char *);
/* tz.c */
#ifndef USE_PAM
extern char *tz (const char *);
#endif
/* ulimit.c */
extern void set_filesize_limit (int);
extern int set_filesize_limit (int blocks);
/* user_busy.c */
extern int user_busy (const char *name, uid_t uid);
/* utmp.c */
extern void checkutmp (int);
extern void setutmp (const char *, const char *, const char *);
extern /*@null@*/struct utmp *get_current_utmp (void);
extern struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut);
extern int setutmp (struct utmp *ut);
#ifdef USE_UTMPX
extern struct utmpx *prepare_utmpx (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut);
extern int setutmpx (struct utmpx *utx);
#endif /* USE_UTMPX */
/* valid.c */
extern int valid (const char *, const struct passwd *);
extern bool valid (const char *, const struct passwd *);
/* xmalloc.c */
extern char *xmalloc (size_t);
extern char *xstrdup (const char *);
extern /*@maynotreturn@*/ /*@out@*//*@only@*/char *xmalloc (size_t size)
/*@ensures MaxSet(result) == (size - 1); @*/;
extern /*@maynotreturn@*/ /*@only@*/char *xstrdup (const char *);
/* xgetpwnam.c */
extern struct passwd *xgetpwnam (const char *);
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
/* xgetpwuid.c */
extern struct passwd *xgetpwuid (uid_t);
extern /*@null@*/ /*@only@*/struct passwd *xgetpwuid (uid_t);
/* xgetgrnam.c */
extern struct group *xgetgrnam (const char *);
extern /*@null@*/ /*@only@*/struct group *xgetgrnam (const char *);
/* xgetgrgid.c */
extern struct group *xgetgrgid (gid_t);
extern /*@null@*/ /*@only@*/struct group *xgetgrgid (gid_t);
/* xgetspnam.c */
extern struct spwd *xgetspnam(const char *);
extern /*@null@*/ /*@only@*/struct spwd *xgetspnam(const char *);
/* yesno.c */
extern int yes_or_no (int read_only);
extern bool yes_or_no (bool read_only);
#endif /* _PROTOTYPES_H */

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1992 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,8 @@ static const char *PROMPT = gettext_noop ("Password: ");
static const char *PROMPT = gettext_noop ("%s's Password: ");
#endif
int wipe_clear_pass = 1;
char *clear_pass = NULL;
bool wipe_clear_pass = true;
/*@null@*/char *clear_pass = NULL;
/*
* pw_auth - perform getpass/crypt authentication
@@ -65,8 +65,10 @@ char *clear_pass = NULL;
* compared.
*/
int
pw_auth (const char *cipher, const char *user, int reason, const char *input)
int pw_auth (const char *cipher,
const char *user,
int reason,
/*@null@*/const char *input)
{
char prompt[1024];
char *clear = NULL;
@@ -74,7 +76,7 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
int retval;
#ifdef SKEY
int use_skey = 0;
bool use_skey = false;
char challenge_info[40];
struct skey skey;
#endif
@@ -83,15 +85,17 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
* There are programs for adding and deleting authentication data.
*/
if (reason == PW_ADD || reason == PW_DELETE)
if ((PW_ADD == reason) || (PW_DELETE == reason)) {
return 0;
}
/*
* There are even programs for changing the user name ...
*/
if (reason == PW_CHANGE && input != (char *) 0)
if ((PW_CHANGE == reason) && (NULL != input)) {
return 0;
}
/*
* WARNING:
@@ -102,8 +106,9 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
* revisited.
*/
if (reason == PW_CHANGE && getuid () == 0)
if ((PW_CHANGE == reason) && (getuid () == 0)) {
return 0;
}
/*
* WARNING:
@@ -114,8 +119,9 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
* matter.
*/
if (cipher == (char *) 0 || *cipher == '\0')
if ((NULL == cipher) || ('\0' == *cipher)) {
return 0;
}
#ifdef SKEY
/*
@@ -132,8 +138,9 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
# define skeychallenge(s,u,c) skeychallenge(s,u,c,sizeof(c))
# endif
if (skeychallenge (&skey, user, challenge_info) == 0)
use_skey = 1;
if (skeychallenge (&skey, user, challenge_info) == 0) {
use_skey = true;
}
#endif
/*
@@ -141,17 +148,20 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
* get the cleartext password for us.
*/
if (reason != PW_FTP && reason != PW_REXEC && !input) {
if (!(cp = getdef_str ("LOGIN_STRING")))
if ((PW_FTP != reason) && (PW_REXEC != reason) && (NULL == input)) {
cp = getdef_str ("LOGIN_STRING");
if (NULL == cp) {
cp = _(PROMPT);
}
#ifdef SKEY
if (use_skey)
if (use_skey) {
printf ("[%s]\n", challenge_info);
}
#endif
snprintf (prompt, sizeof prompt, cp, user);
clear = getpass (prompt);
if (!clear) {
if (NULL == clear) {
static char c[1];
c[0] = '\0';
@@ -177,9 +187,9 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
* ...Re-prompt, with echo on.
* -- AR 8/22/1999
*/
if (retval && !input[0] && (use_skey)) {
if ((0 != retval) && ('\0' == input[0]) && use_skey) {
clear = getpass (prompt);
if (!clear) {
if (NULL == clear) {
static char c[1];
c[0] = '\0';
@@ -188,13 +198,15 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
input = clear;
}
if (retval && use_skey) {
if ((0 != retval) && use_skey) {
int passcheck = -1;
if (skeyverify (&skey, input) == 0)
if (skeyverify (&skey, input) == 0) {
passcheck = skey.n;
if (passcheck > 0)
}
if (passcheck > 0) {
retval = 0;
}
}
#endif
@@ -206,8 +218,9 @@ pw_auth (const char *cipher, const char *user, int reason, const char *input)
*/
clear_pass = clear;
if (wipe_clear_pass && clear && *clear)
if (wipe_clear_pass && (NULL != clear) && ('\0' != *clear)) {
strzero (clear);
}
return retval;
}
#else /* !USE_PAM */

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1992 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,7 +35,10 @@
*/
#ifndef USE_PAM
int pw_auth (const char *cipher, const char *user, int flag, const char *input);
int pw_auth (const char *cipher,
const char *user,
int flag,
/*@null@*/const char *input);
#endif /* !USE_PAM */
/*

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,23 +42,18 @@
#include "commonio.h"
#include "pwio.h"
static void *passwd_dup (const void *ent)
static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)
{
const struct passwd *pw = ent;
return __pw_dup (pw);
}
static void passwd_free (void *ent)
static void passwd_free (/*@out@*/ /*@only@*/void *ent)
{
struct passwd *pw = ent;
free (pw->pw_name);
free (pw->pw_passwd);
free (pw->pw_gecos);
free (pw->pw_dir);
free (pw->pw_shell);
free (pw);
pw_free (pw);
}
static const char *passwd_getname (const void *ent)
@@ -102,17 +97,22 @@ static struct commonio_db passwd_db = {
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0 /* readonly */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int pw_name (const char *filename)
int pw_setdbname (const char *filename)
{
return commonio_setname (&passwd_db, filename);
}
/*@observer@*/const char *pw_dbname (void)
{
return passwd_db.filename;
}
int pw_lock (void)
{
return commonio_lock (&passwd_db);
@@ -123,12 +123,12 @@ int pw_open (int mode)
return commonio_open (&passwd_db, mode);
}
const struct passwd *pw_locate (const char *name)
/*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name)
{
return commonio_locate (&passwd_db, name);
}
const struct passwd *pw_locate_uid (uid_t uid)
/*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid)
{
const struct passwd *pwd;
@@ -155,7 +155,7 @@ int pw_rewind (void)
return commonio_rewind (&passwd_db);
}
const struct passwd *pw_next (void)
/*@observer@*/ /*@null@*/const struct passwd *pw_next (void)
{
return commonio_next (&passwd_db);
}
@@ -170,7 +170,7 @@ int pw_unlock (void)
return commonio_unlock (&passwd_db);
}
struct commonio_entry *__pw_get_head (void)
/*@null@*/struct commonio_entry *__pw_get_head (void)
{
return passwd_db.head;
}

View File

@@ -31,17 +31,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _PWIO_H
#define _PWIO_H
#include <sys/types.h>
#include <pwd.h>
extern int pw_close (void);
extern const struct passwd *pw_locate (const char *);
extern const struct passwd *pw_locate_uid (uid_t uid);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid);
extern int pw_lock (void);
extern int pw_name (const char *);
extern const struct passwd *pw_next (void);
extern int pw_open (int);
extern int pw_remove (const char *);
extern int pw_setdbname (const char *filename);
extern /*@observer@*/const char *pw_dbname (void);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_next (void);
extern int pw_open (int mode);
extern int pw_remove (const char *name);
extern int pw_rewind (void);
extern int pw_unlock (void);
extern int pw_update (const struct passwd *);
extern int pw_update (const struct passwd *pw);
extern int pw_sort (void);
#endif

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,29 +35,52 @@
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#include "pwio.h"
struct passwd *__pw_dup (const struct passwd *pwent)
/*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent)
{
struct passwd *pw;
if (!(pw = (struct passwd *) malloc (sizeof *pw)))
pw = (struct passwd *) malloc (sizeof *pw);
if (NULL == pw) {
return NULL;
}
*pw = *pwent;
if (!(pw->pw_name = strdup (pwent->pw_name)))
pw->pw_name = strdup (pwent->pw_name);
if (NULL == pw->pw_name) {
return NULL;
if (!(pw->pw_passwd = strdup (pwent->pw_passwd)))
}
pw->pw_passwd = strdup (pwent->pw_passwd);
if (NULL == pw->pw_passwd) {
return NULL;
if (!(pw->pw_gecos = strdup (pwent->pw_gecos)))
}
pw->pw_gecos = strdup (pwent->pw_gecos);
if (NULL == pw->pw_gecos) {
return NULL;
if (!(pw->pw_dir = strdup (pwent->pw_dir)))
}
pw->pw_dir = strdup (pwent->pw_dir);
if (NULL == pw->pw_dir) {
return NULL;
if (!(pw->pw_shell = strdup (pwent->pw_shell)))
}
pw->pw_shell = strdup (pwent->pw_shell);
if (NULL == pw->pw_shell) {
return NULL;
}
return pw;
}
void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent)
{
free (pwent->pw_name);
memzero (pwent->pw_passwd, strlen (pwent->pw_passwd));
free (pwent->pw_passwd);
free (pwent->pw_gecos);
free (pwent->pw_dir);
free (pwent->pw_shell);
free (pwent);
}

View File

@@ -35,6 +35,7 @@
#ident "$Id$"
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
#include "defines.h"
#include "prototypes.h"
@@ -87,10 +88,12 @@ static char **list (char *s)
if (!s || s[0] == '\0')
break;
members[i++] = s;
while (*s && *s != ',')
while (('\0' != *s) && (',' != *s)) {
s++;
if (*s)
}
if ('\0' != *s) {
*s++ = '\0';
}
}
members[i] = (char *) 0;
return members;
@@ -120,22 +123,32 @@ struct group *sgetgrent (const char *buf)
}
strcpy (grpbuf, buf);
if ((cp = strrchr (grpbuf, '\n')))
cp = strrchr (grpbuf, '\n');
if (NULL != cp) {
*cp = '\0';
for (cp = grpbuf, i = 0; i < NFIELDS && cp; i++) {
grpfields[i] = cp;
if ((cp = strchr (cp, ':')))
*cp++ = 0;
}
if (i < (NFIELDS - 1) || *grpfields[2] == '\0')
return 0;
for (cp = grpbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) {
grpfields[i] = cp;
cp = strchr (cp, ':');
if (NULL != cp) {
*cp = '\0';
cp++;
}
}
if (i < (NFIELDS - 1) || *grpfields[2] == '\0') {
return (struct group *) 0;
}
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
grent.gr_gid = atoi (grpfields[2]);
if (get_gid (grpfields[2], &grent.gr_gid) == 0) {
return (struct group *) 0;
}
grent.gr_mem = list (grpfields[3]);
if (!grent.gr_mem)
if (NULL == grent.gr_mem) {
return (struct group *) 0; /* out of memory */
}
return &grent;
}

View File

@@ -60,7 +60,6 @@ struct passwd *sgetpwent (const char *buf)
static char pwdbuf[1024];
register int i;
register char *cp;
char *ep;
char *fields[NFIELDS];
/*
@@ -77,15 +76,18 @@ struct passwd *sgetpwent (const char *buf)
* field. The fields are converted into NUL terminated strings.
*/
for (cp = pwdbuf, i = 0; i < NFIELDS && cp; i++) {
for (cp = pwdbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) {
fields[i] = cp;
while (*cp && *cp != ':')
++cp;
while (('\0' != *cp) && (':' != *cp)) {
cp++;
}
if (*cp)
*cp++ = '\0';
else
cp = 0;
if ('\0' != *cp) {
*cp = '\0';
cp++;
} else {
cp = NULL;
}
}
/*
@@ -94,7 +96,7 @@ struct passwd *sgetpwent (const char *buf)
*/
if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
return 0;
return NULL;
/*
* Each of the fields is converted the appropriate data type
@@ -105,13 +107,11 @@ struct passwd *sgetpwent (const char *buf)
pwent.pw_name = fields[0];
pwent.pw_passwd = fields[1];
if (fields[2][0] == '\0' ||
((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) {
return 0;
if (get_uid (fields[2], &pwent.pw_uid) == 0) {
return NULL;
}
if (fields[3][0] == '\0' ||
((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) {
return 0;
if (get_gid (fields[3], &pwent.pw_gid) == 0) {
return NULL;
}
pwent.pw_gecos = fields[4];
pwent.pw_dir = fields[5];
@@ -119,3 +119,4 @@ struct passwd *sgetpwent (const char *buf)
return &pwent;
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,9 @@
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#ifndef HAVE_SGETSPENT
#ident "$Id$"
#include <sys/types.h>
@@ -56,32 +60,41 @@ struct spwd *sgetspent (const char *string)
* have to do that to our private copy.
*/
if (strlen (string) >= sizeof spwbuf)
if (strlen (string) >= sizeof spwbuf) {
return 0; /* fail if too long */
}
strcpy (spwbuf, string);
if ((cp = strrchr (spwbuf, '\n')))
cp = strrchr (spwbuf, '\n');
if (NULL != cp) {
*cp = '\0';
}
/*
* Tokenize the string into colon separated fields. Allow up to
* FIELDS different fields.
*/
for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) {
for (cp = spwbuf, i = 0; ('\0' != *cp) && (i < FIELDS); i++) {
fields[i] = cp;
while (*cp && *cp != ':')
while (('\0' != *cp) && (':' != *cp)) {
cp++;
}
if (*cp)
*cp++ = '\0';
if ('\0' != *cp) {
*cp = '\0';
cp++;
}
}
if (i == (FIELDS - 1))
if (i == (FIELDS - 1)) {
fields[i++] = cp;
}
if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
if ( ((NULL != cp) && ('\0' != *cp)) ||
((i != FIELDS) && (i != OFIELDS)) ) {
return 0;
}
/*
* Start populating the structure. The fields are all in
@@ -97,28 +110,34 @@ struct spwd *sgetspent (const char *string)
* incorrectly formatted number.
*/
if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[2][0] == '\0')
if (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else if ( (getlong (fields[2], &spwd.sp_lstchg) == 0)
|| (spwd.sp_lstchg < 0)) {
return 0;
}
/*
* Get the minimum period between password changes.
*/
if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[3][0] == '\0')
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else if ( (getlong (fields[3], &spwd.sp_min) == 0)
|| (spwd.sp_min < 0)) {
return 0;
}
/*
* Get the maximum number of days a password is valid.
*/
if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[4][0] == '\0')
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else if ( (getlong (fields[4], &spwd.sp_max) == 0)
|| (spwd.sp_max < 0)) {
return 0;
}
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
@@ -126,8 +145,10 @@ struct spwd *sgetspent (const char *string)
*/
if (i == OFIELDS) {
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
spwd.sp_flag = -1;
spwd.sp_warn = -1;
spwd.sp_inact = -1;
spwd.sp_expire = -1;
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
return &spwd;
}
@@ -136,40 +157,52 @@ struct spwd *sgetspent (const char *string)
* Get the number of days of password expiry warning.
*/
if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[5][0] == '\0')
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else if ( (getlong (fields[5], &spwd.sp_warn) == 0)
|| (spwd.sp_warn < 0)) {
return 0;
}
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[6][0] == '\0')
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else if ( (getlong (fields[6], &spwd.sp_inact) == 0)
|| (spwd.sp_inact < 0)) {
return 0;
}
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[7][0] == '\0')
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else if ( (getlong (fields[7], &spwd.sp_expire) == 0)
|| (spwd.sp_expire < 0)) {
return 0;
}
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else if (getlong (fields[8], &spwd.sp_flag) == 0) {
/* FIXME: add a getulong function */
return 0;
} else if (fields[8][0] == '\0')
spwd.sp_flag = -1;
}
return (&spwd);
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@@ -42,66 +42,113 @@
#include "commonio.h"
#include "sgroupio.h"
struct sgrp *__sgr_dup (const struct sgrp *sgent)
/*@null@*/ /*@only@*/struct sgrp *__sgr_dup (const struct sgrp *sgent)
{
struct sgrp *sg;
int i;
if (!(sg = (struct sgrp *) malloc (sizeof *sg)))
sg = (struct sgrp *) malloc (sizeof *sg);
if (NULL == sg) {
return NULL;
}
*sg = *sgent;
if (!(sg->sg_name = strdup (sgent->sg_name)))
sg->sg_name = strdup (sgent->sg_name);
if (NULL == sg->sg_name) {
free (sg);
return NULL;
if (!(sg->sg_passwd = strdup (sgent->sg_passwd)))
}
sg->sg_passwd = strdup (sgent->sg_passwd);
if (NULL == sg->sg_passwd) {
free (sg->sg_name);
free (sg);
return NULL;
}
for (i = 0; sgent->sg_adm[i]; i++);
for (i = 0; NULL != sgent->sg_adm[i]; i++);
sg->sg_adm = (char **) malloc ((i + 1) * sizeof (char *));
if (!sg->sg_adm)
if (NULL == sg->sg_adm) {
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
for (i = 0; sgent->sg_adm[i]; i++) {
}
for (i = 0; NULL != sgent->sg_adm[i]; i++) {
sg->sg_adm[i] = strdup (sgent->sg_adm[i]);
if (!sg->sg_adm[i])
if (NULL == sg->sg_adm[i]) {
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
}
sg->sg_adm[i] = NULL;
for (i = 0; sgent->sg_mem[i]; i++);
for (i = 0; NULL != sgent->sg_mem[i]; i++);
sg->sg_mem = (char **) malloc ((i + 1) * sizeof (char *));
if (!sg->sg_mem)
if (NULL == sg->sg_mem) {
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
for (i = 0; sgent->sg_mem[i]; i++) {
}
for (i = 0; NULL != sgent->sg_mem[i]; i++) {
sg->sg_mem[i] = strdup (sgent->sg_mem[i]);
if (!sg->sg_mem[i])
if (NULL == sg->sg_mem[i]) {
for (i = 0; NULL != sg->sg_mem[i]; i++) {
free (sg->sg_mem[i]);
}
free (sg->sg_mem);
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
}
sg->sg_mem[i] = NULL;
return sg;
}
static void *gshadow_dup (const void *ent)
static /*@null@*/ /*@only@*/void *gshadow_dup (const void *ent)
{
const struct sgrp *sg = ent;
return __sgr_dup (sg);
}
static void gshadow_free (void *ent)
static void gshadow_free (/*@out@*/ /*@only@*/void *ent)
{
struct sgrp *sg = ent;
free (sg->sg_name);
free (sg->sg_passwd);
while (*(sg->sg_adm)) {
free (*(sg->sg_adm));
sg->sg_adm++;
sgr_free (sg);
}
void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent)
{
free (sgent->sg_name);
memzero (sgent->sg_passwd, strlen (sgent->sg_passwd));
free (sgent->sg_passwd);
while (NULL != *(sgent->sg_adm)) {
free (*(sgent->sg_adm));
sgent->sg_adm++;
}
while (*(sg->sg_mem)) {
free (*(sg->sg_mem));
sg->sg_mem++;
while (NULL != *(sgent->sg_mem)) {
free (*(sgent->sg_mem));
sgent->sg_mem++;
}
free (sg);
free (sgent);
}
static const char *gshadow_getname (const void *ent)
@@ -145,18 +192,23 @@ static struct commonio_db gshadow_db = {
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0 /* readonly */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int sgr_name (const char *filename)
int sgr_setdbname (const char *filename)
{
return commonio_setname (&gshadow_db, filename);
}
int sgr_file_present (void)
/*@observer@*/const char *sgr_dbname (void)
{
return gshadow_db.filename;
}
bool sgr_file_present (void)
{
return commonio_present (&gshadow_db);
}
@@ -171,7 +223,7 @@ int sgr_open (int mode)
return commonio_open (&gshadow_db, mode);
}
const struct sgrp *sgr_locate (const char *name)
/*@observer@*/ /*@null@*/const struct sgrp *sgr_locate (const char *name)
{
return commonio_locate (&gshadow_db, name);
}
@@ -191,7 +243,7 @@ int sgr_rewind (void)
return commonio_rewind (&gshadow_db);
}
const struct sgrp *sgr_next (void)
/*@null@*/const struct sgrp *sgr_next (void)
{
return commonio_next (&gshadow_db);
}
@@ -208,10 +260,10 @@ int sgr_unlock (void)
void __sgr_set_changed (void)
{
gshadow_db.changed = 1;
gshadow_db.changed = true;
}
struct commonio_entry *__sgr_get_head (void)
/*@dependent@*/ /*@null@*/struct commonio_entry *__sgr_get_head (void)
{
return gshadow_db.head;
}

View File

@@ -31,16 +31,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _SGROUPIO_H
#define _SGROUPIO_H
extern int sgr_close (void);
extern int sgr_file_present (void);
extern const struct sgrp *sgr_locate (const char *);
extern bool sgr_file_present (void);
extern /*@null@*/const struct sgrp *sgr_locate (const char *name);
extern int sgr_lock (void);
extern int sgr_name (const char *);
extern const struct sgrp *sgr_next (void);
extern int sgr_open (int);
extern int sgr_remove (const char *);
extern int sgr_setdbname (const char *filename);
extern /*@observer@*/const char *sgr_dbname (void);
extern /*@null@*/const struct sgrp *sgr_next (void);
extern int sgr_open (int mode);
extern int sgr_remove (const char *name);
extern int sgr_rewind (void);
extern int sgr_unlock (void);
extern int sgr_update (const struct sgrp *);
extern int sgr_update (const struct sgrp *sg);
extern int sgr_sort (void);
#endif

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,8 +56,6 @@ static int nis_vallen;
#endif
static FILE *shadow;
static char spwbuf[BUFSIZ];
static struct spwd spwd;
#define FIELDS 9
#define OFIELDS 5
@@ -72,8 +70,9 @@ void __setspNIS (int flag)
{
nis_ignore = !flag;
if (nis_ignore)
if (nis_ignore) {
nis_used = 0;
}
}
/*
@@ -124,6 +123,8 @@ void endspent (void)
static struct spwd *my_sgetspent (const char *string)
{
static char spwbuf[BUFSIZ];
static struct spwd spwd;
char *fields[FIELDS];
char *cp;
char *cpp;
@@ -182,52 +183,58 @@ static struct spwd *my_sgetspent (const char *string)
* incorrectly formatted number, unless we are using NIS.
*/
spwd.sp_lstchg = strtol (fields[2], &cpp, 10);
if ((spwd.sp_lstchg == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_lstchg = -1;
#else
return 0;
#endif
} else if (fields[2][0] == '\0')
if (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else {
if (getlong (fields[2], &spwd.sp_lstchg) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_lstchg = -1;
} else
#endif
return 0;
} else if (spwd.sp_lstchg < 0) {
return 0;
}
}
/*
* Get the minimum period between password changes.
*/
spwd.sp_min = strtol (fields[3], &cpp, 10);
if ((spwd.sp_min == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_min = -1;
#else
return 0;
#endif
} else if (fields[3][0] == '\0')
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else {
if (getlong (fields[3], &spwd.sp_min) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_min = -1;
} else
#endif
return 0;
} else if (spwd.sp_min < 0) {
return 0;
}
}
/*
* Get the maximum number of days a password is valid.
*/
spwd.sp_max = strtol (fields[4], &cpp, 10);
if ((spwd.sp_max == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_max = -1;
#else
return 0;
#endif
} else if (fields[4][0] == '\0')
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else {
if (getlong (fields[4], &spwd.sp_max) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_max = -1;
} else
#endif
return 0;
} else if (spwd.sp_max < 0) {
return 0;
}
}
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
@@ -235,8 +242,10 @@ static struct spwd *my_sgetspent (const char *string)
*/
if (i == OFIELDS) {
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
spwd.sp_flag = -1;
spwd.sp_warn = -1;
spwd.sp_inact = -1;
spwd.sp_expire = -1;
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
return &spwd;
}
@@ -245,72 +254,81 @@ static struct spwd *my_sgetspent (const char *string)
* Get the number of days of password expiry warning.
*/
spwd.sp_warn = strtol (fields[5], &cpp, 10);
if ((spwd.sp_warn == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_warn = -1;
#else
return 0;
#endif
} else if (fields[5][0] == '\0')
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else {
if (getlong (fields[5], &spwd.sp_warn) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_warn = -1;
} else
#endif
return 0;
} else if (spwd.sp_warn < 0) {
return 0;
}
}
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
spwd.sp_inact = strtol (fields[6], &cpp, 10);
if ((spwd.sp_inact == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_inact = -1;
#else
return 0;
#endif
} else if (fields[6][0] == '\0')
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else {
if (getlong (fields[6], &spwd.sp_inact) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_inact = -1;
} else
#endif
return 0;
} else if (spwd.sp_inact < 0) {
return 0;
}
}
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
spwd.sp_expire = strtol (fields[7], &cpp, 10);
if ((spwd.sp_expire == 0) && *cpp) {
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_expire = -1;
#else
return 0;
#endif
} else if (fields[7][0] == '\0')
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else {
if (getlong (fields[7], &spwd.sp_expire) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_expire = -1;
} else
#endif
return 0;
} else if (spwd.sp_expire < 0) {
return 0;
}
}
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
spwd.sp_flag = strtol (fields[8], &cpp, 10);
if ((spwd.sp_flag == 0) && *cpp) {
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else {
if (getlong (fields[8], &spwd.sp_flag) == 0) {
/* FIXME: add a getulong function */
#ifdef USE_NIS
if (!nis_used)
return 0;
else
spwd.sp_flag = -1;
#else
return 0;
if (nis_used) {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else
#endif
} else if (fields[8][0] == '\0')
spwd.sp_flag = -1;
return 0;
} else if (spwd.sp_flag < 0) {
return 0;
}
}
return (&spwd);
}
@@ -324,21 +342,24 @@ struct spwd *fgetspent (FILE * fp)
char buf[BUFSIZ];
char *cp;
if (!fp)
if (NULL == fp) {
return (0);
}
#ifdef USE_NIS
while (fgets (buf, sizeof buf, fp) != (char *) 0)
while (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#else
if (fgets (buf, sizeof buf, fp) != (char *) 0)
if (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#endif
{
cp = strchr (buf, '\n');
if (NULL != cp)
if (NULL != cp) {
*cp = '\0';
}
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0]))
if (nis_ignore && IS_NISCHAR (buf[0])) {
continue;
}
#endif
return my_sgetspent (buf);
}
@@ -513,3 +534,4 @@ struct spwd *getspnam (const char *name)
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,20 +42,18 @@
#include "commonio.h"
#include "shadowio.h"
static void *shadow_dup (const void *ent)
static /*@null@*/ /*@only@*/void *shadow_dup (const void *ent)
{
const struct spwd *sp = ent;
return __spw_dup (sp);
}
static void shadow_free (void *ent)
static void shadow_free (/*@out@*//*@only@*/void *ent)
{
struct spwd *sp = ent;
free (sp->sp_namp);
free (sp->sp_pwdp);
free (sp);
spw_free (sp);
}
static const char *shadow_getname (const void *ent)
@@ -99,18 +97,23 @@ static struct commonio_db shadow_db = {
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0 /* readonly */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int spw_name (const char *filename)
int spw_setdbname (const char *filename)
{
return commonio_setname (&shadow_db, filename);
}
int spw_file_present (void)
/*@observer@*/const char *spw_dbname (void)
{
return shadow_db.filename;
}
bool spw_file_present (void)
{
return commonio_present (&shadow_db);
}
@@ -125,7 +128,7 @@ int spw_open (int mode)
return commonio_open (&shadow_db, mode);
}
const struct spwd *spw_locate (const char *name)
/*@observer@*/ /*@null@*/const struct spwd *spw_locate (const char *name)
{
return commonio_locate (&shadow_db, name);
}
@@ -145,7 +148,7 @@ int spw_rewind (void)
return commonio_rewind (&shadow_db);
}
const struct spwd *spw_next (void)
/*@observer@*/ /*@null@*/const struct spwd *spw_next (void)
{
return commonio_next (&shadow_db);
}

View File

@@ -30,16 +30,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _SHADOWIO_H
#define _SHADOWIO_H
#include "defines.h"
extern int spw_close (void);
extern int spw_file_present (void);
extern const struct spwd *spw_locate (const char *);
extern bool spw_file_present (void);
extern /*@observer@*/ /*@null@*/const struct spwd *spw_locate (const char *name);
extern int spw_lock (void);
extern int spw_name (const char *);
extern const struct spwd *spw_next (void);
extern int spw_open (int);
extern int spw_remove (const char *);
extern int spw_setdbname (const char *filename);
extern /*@observer@*/const char *spw_dbname (void);
extern /*@observer@*/ /*@null@*/const struct spwd *spw_next (void);
extern int spw_open (int mode);
extern int spw_remove (const char *name);
extern int spw_rewind (void);
extern int spw_unlock (void);
extern int spw_update (const struct spwd *);
extern int spw_update (const struct spwd *sp);
extern int spw_sort (void);
#endif

View File

@@ -3,7 +3,7 @@
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,17 +41,32 @@
#include <stdio.h>
#include "shadowio.h"
struct spwd *__spw_dup (const struct spwd *spent)
/*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent)
{
struct spwd *sp;
if (!(sp = (struct spwd *) malloc (sizeof *sp)))
sp = (struct spwd *) malloc (sizeof *sp);
if (NULL == sp) {
return NULL;
}
*sp = *spent;
if (!(sp->sp_namp = strdup (spent->sp_namp)))
sp->sp_namp = strdup (spent->sp_namp);
if (NULL == sp->sp_namp) {
return NULL;
if (!(sp->sp_pwdp = strdup (spent->sp_pwdp)))
}
sp->sp_pwdp = strdup (spent->sp_pwdp);
if (NULL == sp->sp_pwdp) {
return NULL;
}
return sp;
}
void spw_free (/*@out@*/ /*@only@*/struct spwd *spent)
{
free (spent->sp_namp);
memzero (spent->sp_pwdp, strlen (spent->sp_pwdp));
free (spent->sp_pwdp);
free (spent);
}

View File

@@ -14,6 +14,9 @@ libmisc_a_SOURCES = \
chkname.h \
chowndir.c \
chowntty.c \
cleanup.c \
cleanup_group.c \
cleanup_user.c \
console.c \
copydir.c \
entry.c \
@@ -21,10 +24,12 @@ libmisc_a_SOURCES = \
failure.c \
failure.h \
fields.c \
find_new_ids.c \
find_new_gid.c \
find_new_uid.c \
getdate.h \
getdate.y \
getlong.c \
getgr_nam_gid.c \
getrange.c \
hushed.c \
isexpired.c \
limits.c \
@@ -35,6 +40,7 @@ libmisc_a_SOURCES = \
myname.c \
obscure.c \
pam_pass.c \
pam_pass_non_interractive.c \
pwd2spwd.c \
pwdcheck.c \
pwd_init.c \
@@ -43,12 +49,14 @@ libmisc_a_SOURCES = \
setugid.c \
setupenv.c \
shell.c \
system.c \
strtoday.c \
sub.c \
sulog.c \
ttytype.c \
tz.c \
ulimit.c \
user_busy.c \
utmp.c \
valid.c \
xgetpwnam.c \

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
#include <config.h>
#ifdef HAVE_SETGROUPS
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
#include "prototypes.h"
#include "defines.h"
@@ -52,7 +52,9 @@
int add_groups (const char *list)
{
GETGROUPS_T *grouplist, *tmp;
int i, ngroups, added;
size_t i;
int ngroups;
bool added;
char *token;
char buf[1024];
@@ -65,11 +67,13 @@ int add_groups (const char *list)
i = 16;
for (;;) {
grouplist = (gid_t *) malloc (i * sizeof (GETGROUPS_T));
if (!grouplist)
if (NULL == grouplist) {
return -1;
}
ngroups = getgroups (i, grouplist);
if (i > ngroups)
if ((-1 == ngroups) || (i > (size_t)ngroups)) {
break;
}
/* not enough room, so try allocating a larger buffer */
free (grouplist);
i *= 2;
@@ -79,40 +83,45 @@ int add_groups (const char *list)
return -1;
}
added = 0;
for (token = strtok (buf, SEP); token; token = strtok (NULL, SEP)) {
added = false;
for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) {
struct group *grp;
grp = getgrnam (token); /* local, no need for xgetgrnam */
if (!grp) {
if (NULL == grp) {
fprintf (stderr, _("Warning: unknown group %s\n"),
token);
continue;
}
for (i = 0; i < ngroups && grouplist[i] != grp->gr_gid; i++);
for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
if (i < ngroups)
if (i < (size_t)ngroups) {
continue;
}
if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
fputs (_("Warning: too many groups\n"), stderr);
break;
}
tmp = (gid_t *) realloc (grouplist, (ngroups + 1) * sizeof (GETGROUPS_T));
if (!tmp) {
tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T));
if (NULL == tmp) {
free (grouplist);
return -1;
}
tmp[ngroups++] = grp->gr_gid;
tmp[ngroups] = grp->gr_gid;
ngroups++;
grouplist = tmp;
added++;
added = true;
}
if (added)
return setgroups (ngroups, grouplist);
if (added) {
return setgroups ((size_t)ngroups, grouplist);
}
return 0;
}
#endif
#else /* HAVE_SETGROUPS && !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* HAVE_SETGROUPS && !USE_PAM */

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -53,31 +53,33 @@
* expire() calls /bin/passwd to change the user's password
* if it has expired.
*/
int expire (const struct passwd *pw, const struct spwd *sp)
int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
{
int status;
int child;
int pid;
pid_t child;
pid_t pid;
if (!sp)
sp = pwd_to_spwd (pw);
if (NULL == sp) {
return 0;
}
/*
* See if the user's password has expired, and if so
* force them to change their password.
*/
switch (status = isexpired (pw, sp)) {
status = isexpired (pw, sp);
switch (status) {
case 0:
return 0;
case 1:
fputs (_("Your password has expired."), stdout);
(void) fputs (_("Your password has expired."), stdout);
break;
case 2:
fputs (_("Your password is inactive."), stdout);
(void) fputs (_("Your password is inactive."), stdout);
break;
case 3:
fputs (_("Your login has expired."), stdout);
(void) fputs (_("Your login has expired."), stdout);
break;
}
@@ -88,12 +90,12 @@ int expire (const struct passwd *pw, const struct spwd *sp)
* change that password.
*/
if (status > 1 || sp->sp_max < sp->sp_min) {
puts (_(" Contact the system administrator."));
exit (1);
if ((status > 1) || (sp->sp_max < sp->sp_min)) {
(void) puts (_(" Contact the system administrator."));
exit (EXIT_FAILURE);
}
puts (_(" Choose a new password."));
fflush (stdout);
(void) puts (_(" Choose a new password."));
(void) fflush (stdout);
/*
* Close all the files so that unauthorized access won't
@@ -115,7 +117,8 @@ int expire (const struct passwd *pw, const struct spwd *sp)
* change their password before being able to use the account.
*/
if ((pid = fork ()) == 0) {
pid = fork ();
if (0 == pid) {
int err;
/*
@@ -123,24 +126,32 @@ int expire (const struct passwd *pw, const struct spwd *sp)
* passwd to work just like it would had they executed
* it from the command line while logged in.
*/
if (setup_uid_gid (pw, 0))
#if defined(HAVE_INITGROUPS) && ! defined(USE_PAM)
if (setup_uid_gid (pw, false) != 0)
#else
if (setup_uid_gid (pw) != 0)
#endif
{
_exit (126);
}
execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
err = errno;
perror ("Can't execute " PASSWD_PROGRAM);
_exit (err == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
} else if (pid == -1) {
_exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
} else if ((pid_t) -1 == pid) {
perror ("fork");
exit (1);
exit (EXIT_FAILURE);
}
while ((child = wait (&status)) != pid && child != -1);
if (child == pid && status == 0)
while (((child = wait (&status)) != pid) && (child != (pid_t)-1));
if ((child == pid) && (0 == status)) {
return 1;
}
exit (1);
/*NOTREACHED*/}
exit (EXIT_FAILURE);
/*@notreached@*/}
/*
* agecheck - see if warning is needed for password expiration
@@ -149,30 +160,42 @@ int expire (const struct passwd *pw, const struct spwd *sp)
* to expire and warns the user of the pending password expiration.
*/
void agecheck (const struct passwd *pw, const struct spwd *sp)
void agecheck (/*@null@*/const struct spwd *sp)
{
long now = time ((long *) 0) / SCALE;
long now = (long) time ((time_t *) 0) / SCALE;
long remain;
if (!sp)
sp = pwd_to_spwd (pw);
if (NULL == sp) {
return;
}
/*
* The last, max, and warn fields must be supported or the
* warning period cannot be calculated.
*/
if (sp->sp_lstchg == -1 || sp->sp_max == -1 || sp->sp_warn == -1)
if ( (-1 == sp->sp_lstchg)
|| (-1 == sp->sp_max)
|| (-1 == sp->sp_warn)) {
return;
if ((remain = (sp->sp_lstchg + sp->sp_max) - now) <= sp->sp_warn) {
}
if (0 == sp->sp_lstchg) {
(void) puts (_("You must change your password."));
return;
}
remain = sp->sp_lstchg + sp->sp_max - now;
if (remain <= sp->sp_warn) {
remain /= DAY / SCALE;
if (remain > 1)
printf (_
("Your password will expire in %ld days.\n"),
remain);
else if (remain == 1)
puts (_("Your password will expire tomorrow."));
else if (remain == 0)
puts (_("Your password will expire today."));
if (remain > 1) {
(void) printf (_("Your password will expire in %ld days.\n"),
remain);
} else if (1 == remain) {
(void) puts (_("Your password will expire tomorrow."));
} else if (remain == 0) {
(void) puts (_("Your password will expire today."));
}
}
}

View File

@@ -53,11 +53,14 @@ void audit_help_open (void)
if (audit_fd < 0) {
/* You get these only when the kernel doesn't have
* audit compiled in. */
if (errno == EINVAL || errno == EPROTONOSUPPORT ||
errno == EAFNOSUPPORT)
if ( (errno == EINVAL)
|| (errno == EPROTONOSUPPORT)
|| (errno == EAFNOSUPPORT)) {
return;
fprintf (stderr, "Cannot open audit interface - aborting.\n");
exit (1);
}
(void) fputs (_("Cannot open audit interface - aborting.\n"),
stderr);
exit (EXIT_FAILURE);
}
}
@@ -72,16 +75,32 @@ void audit_help_open (void)
* name - user's account or group name. If not available use NULL.
* id - uid or gid that the operation is being performed on. This is used
* only when user is NULL.
* result - 1 is "success" and 0 is "failed"
*/
void audit_logger (int type, const char *pgname, const char *op,
const char *name, unsigned int id, int result)
const char *name, unsigned int id,
shadow_audit_result result)
{
if (audit_fd < 0)
if (audit_fd < 0) {
return;
else
} else {
audit_log_acct_message (audit_fd, type, NULL, op, name, id,
NULL, NULL, NULL, result);
NULL, NULL, NULL, (int) result);
}
}
void audit_logger_message (const char *message, shadow_audit_result result)
{
if (audit_fd < 0) {
return;
} else {
audit_log_user_message (audit_fd,
AUDIT_USYS_CONFIG,
message,
NULL, /* hostname */
NULL, /* addr */
NULL, /* tty */
(int) result);
}
}
#else /* WITH_AUDIT */

View File

@@ -31,8 +31,11 @@
*/
/*
* check_user_name(), check_group_name() - check the new user/group
* name for validity; return value: 1 - OK, 0 - bad name
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
* return values:
* true - OK
* false - bad name
*/
#include <config.h>
@@ -42,57 +45,55 @@
#include <ctype.h>
#include "defines.h"
#include "chkname.h"
#if HAVE_UTMPX_H
#include <utmpx.h>
#else
#include <utmp.h>
#endif
static int good_name (const char *name)
static bool is_valid_name (const char *name)
{
/*
* User/group names must match [a-z_][a-z0-9_-]*[$]
*/
if (!*name || !((*name >= 'a' && *name <= 'z') || *name == '_'))
return 0;
while (*++name) {
if (!((*name >= 'a' && *name <= 'z') ||
(*name >= '0' && *name <= '9') ||
*name == '_' || *name == '-' ||
(*name == '$' && *(name + 1) == '\0')))
return 0;
if (('\0' == *name) ||
!((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
return false;
}
return 1;
while ('\0' != *++name) {
if (!(( ('a' <= *name) && ('z' >= *name) ) ||
( ('0' <= *name) && ('9' >= *name) ) ||
('_' == *name) ||
('-' == *name) ||
( ('$' == *name) && ('\0' == *(name + 1)) )
)) {
return false;
}
}
return true;
}
int check_user_name (const char *name)
bool is_valid_user_name (const char *name)
{
#if HAVE_UTMPX_H
struct utmpx ut;
#else
struct utmp ut;
#endif
/*
* User names are limited by whatever utmp can
* handle (usually max 8 characters).
* handle.
*/
if (strlen (name) > sizeof (ut.ut_user))
return 0;
if (strlen (name) > USER_NAME_MAX_LENGTH) {
return false;
}
return good_name (name);
return is_valid_name (name);
}
int check_group_name (const char *name)
bool is_valid_group_name (const char *name)
{
/*
* Arbitrary limit for group names - max 16
* characters (same as on HP-UX 10).
* Arbitrary limit for group names.
* HP-UX 10 limits to 16 characters
*/
if (strlen (name) > 16)
return 0;
if ( (GROUP_NAME_MAX_LENGTH > 0)
&& (strlen (name) > GROUP_NAME_MAX_LENGTH)) {
return false;
}
return good_name (name);
return is_valid_name (name);
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1997 - 2000, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,13 +35,16 @@
#define _CHKNAME_H_
/*
* check_user_name(), check_group_name() - check the new user/group
* name for validity; return value: 1 - OK, 0 - bad name
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
* return values:
* true - OK
* false - bad name
*/
#include "defines.h"
extern int check_user_name (const char *);
extern int check_group_name (const char *name);
extern bool is_valid_user_name (const char *name);
extern bool is_valid_group_name (const char *name);
#endif

View File

@@ -104,9 +104,11 @@ chown_tree (const char *root, uid_t old_uid, uid_t new_uid, gid_t old_gid,
* Do the entire subdirectory.
*/
if ((rc = chown_tree (new_name, old_uid, new_uid,
old_gid, new_gid)))
rc = chown_tree (new_name, old_uid, new_uid,
old_gid, new_gid);
if (0 != rc) {
break;
}
}
#ifndef HAVE_LCHOWN
/* don't use chown (follows symbolic links!) */
@@ -117,16 +119,18 @@ chown_tree (const char *root, uid_t old_uid, uid_t new_uid, gid_t old_gid,
LCHOWN (new_name, new_uid,
sb.st_gid == old_gid ? new_gid : sb.st_gid);
}
closedir (dir);
(void) closedir (dir);
/*
* Now do the root of the tree
*/
if (!stat (root, &sb)) {
if (sb.st_uid == old_uid)
if (stat (root, &sb) == 0) {
if (sb.st_uid == old_uid) {
LCHOWN (root, new_uid,
sb.st_gid == old_gid ? new_gid : sb.st_gid);
sb.st_gid == old_gid ? new_gid : sb.st_gid);
}
}
return rc;
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2001, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,31 +43,14 @@
#include "defines.h"
#include <pwd.h>
#include "getdef.h"
/*
* is_my_tty -- determine if "tty" is the same as TTY stdin is using
*/
static int is_my_tty (const char *tty)
{
struct stat by_name, by_fd;
if (stat (tty, &by_name) || fstat (0, &by_fd))
return 0;
if (by_name.st_rdev != by_fd.st_rdev)
return 0;
else
return 1;
}
/*
* chown_tty() sets the login tty to be owned by the new user ID
* with TTYPERM modes
*/
void chown_tty (const char *tty, const struct passwd *info)
void chown_tty (const struct passwd *info)
{
char buf[200], full_tty[200];
char *group; /* TTY group name or number */
struct group *grent;
gid_t gid;
@@ -76,45 +59,32 @@ void chown_tty (const char *tty, const struct passwd *info)
* ID. Otherwise, use the user's primary group ID.
*/
if (!(group = getdef_str ("TTYGROUP")))
gid = info->pw_gid;
else if (group[0] >= '0' && group[0] <= '9')
gid = atoi (group);
else if ((grent = getgrnam (group))) /* local, no need for xgetgrnam */
grent = getgr_nam_gid (getdef_str ("TTYGROUP"));
if (NULL != grent) {
gid = grent->gr_gid;
else
} else {
gid = info->pw_gid;
}
/*
* Change the permissions on the TTY to be owned by the user with
* the group as determined above.
*/
if (*tty != '/') {
snprintf (full_tty, sizeof full_tty, "/dev/%s", tty);
tty = full_tty;
}
if (!is_my_tty (tty)) {
SYSLOG ((LOG_WARN,
"unable to determine TTY name, got %s\n", tty));
closelog ();
exit (1);
}
if (chown (tty, info->pw_uid, gid) ||
chmod (tty, getdef_num ("TTYPERM", 0600))) {
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
int err = errno;
snprintf (buf, sizeof buf, _("Unable to change tty %s"), tty);
perror (buf);
fprintf (stderr,
_("Unable to change owner or mode of tty stdin: %s"),
strerror (err));
SYSLOG ((LOG_WARN,
"unable to change tty `%s' for user `%s'\n", tty,
info->pw_name));
closelog ();
if (err != EROFS)
exit (1);
"unable to change owner or mode of tty stdin for user `%s': %s\n",
info->pw_name, strerror (err)));
if (EROFS != err) {
closelog ();
exit (EXIT_FAILURE);
}
}
#ifdef __linux__
/*

128
libmisc/cleanup.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
/*
* The cleanup_functions stack.
*/
#define CLEANUP_FUNCTIONS 10
static cleanup_function cleanup_functions[CLEANUP_FUNCTIONS];
static void * cleanup_function_args[CLEANUP_FUNCTIONS];
/*
* - Cleanup functions shall not fail.
* - You should register do_cleanups with atexit.
* - You should add cleanup functions to the stack with add_cleanup when
* an operation is expected to be executed later, and remove it from the
* stack with del_cleanup when it has been executed.
*
**/
/*
* do_cleanups - perform the actions stored in the cleanup_functions stack.
*
* It is intended to be used as:
* atexit (do_cleanups);
*/
void do_cleanups (void)
{
unsigned int i;
/* Make sure there were no overflow */
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]);
i = CLEANUP_FUNCTIONS;
do {
i--;
if (cleanup_functions[i] != NULL) {
cleanup_functions[i] (cleanup_function_args[i]);
}
} while (i>0);
}
/*
* add_cleanup - Add a cleanup_function to the cleanup_functions stack.
*/
void add_cleanup (cleanup_function pcf, /*@null@*/void *arg)
{
unsigned int i;
assert (NULL != pcf);
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-2]);
/* Add the cleanup_function at the end of the stack */
for (i=0; NULL != cleanup_functions[i]; i++);
cleanup_functions[i] = pcf;
cleanup_function_args[i] = arg;
}
/*
* del_cleanup - Remove a cleanup_function from the cleanup_functions stack.
*/
void del_cleanup (cleanup_function pcf)
{
unsigned int i;
assert (NULL != pcf);
/* Find the pcf cleanup function */
for (i=0; i<CLEANUP_FUNCTIONS; i++) {
if (cleanup_functions[i] == pcf) {
break;
}
}
/* Make sure the cleanup function was found */
assert (i<CLEANUP_FUNCTIONS);
/* Move the rest of the cleanup functions */
for (; i<CLEANUP_FUNCTIONS; i++) {
/* Make sure the cleanup function was specified only once */
assert (cleanup_functions[i+1] != pcf);
if (i == (CLEANUP_FUNCTIONS -1)) {
cleanup_functions[i] = NULL;
cleanup_function_args[i] = NULL;
} else {
cleanup_functions[i] = cleanup_functions[i+1];
cleanup_function_args[i] = cleanup_function_args[i+1];
}
/* A NULL indicates the end of the stack */
if (NULL == cleanup_functions[i]) {
break;
}
}
}

237
libmisc/cleanup_group.c Normal file
View File

@@ -0,0 +1,237 @@
/*
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "defines.h"
#include "groupio.h"
#include "sgroupio.h"
#include "prototypes.h"
/*
* cleanup_report_add_group - Report failure to add a group to the system
*
* It should be registered when it is decided to add a group to the system.
*/
void cleanup_report_add_group (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR, "failed to add group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_del_group - Report failure to remove a group from the system
*
* It should be registered when it is decided to remove a group from the system.
*/
void cleanup_report_del_group (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, Prog,
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
void cleanup_report_mod_group (void *cleanup_info)
{
const struct cleanup_info_mod *info;
info = (const struct cleanup_info_mod *)cleanup_info;
SYSLOG ((LOG_ERR,
"failed to change %s (%s)",
gr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, Prog,
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#ifdef SHADOWGRP
void cleanup_report_mod_gshadow (void *cleanup_info)
{
const struct cleanup_info_mod *info;
info = (const struct cleanup_info_mod *)cleanup_info;
SYSLOG ((LOG_ERR,
"failed to change %s (%s)",
sgr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, Prog,
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#endif
/*
* cleanup_report_add_group_group - Report failure to add a group to group
*
* It should be registered when it is decided to add a group to the
* group database.
*/
void cleanup_report_add_group_group (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"adding group to /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#ifdef SHADOWGRP
/*
* cleanup_report_add_group_gshadow - Report failure to add a group to gshadow
*
* It should be registered when it is decided to add a group to the
* gshadow database.
*/
void cleanup_report_add_group_gshadow (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"adding group to /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#endif
/*
* cleanup_report_del_group_group - Report failure to remove a group from the
* regular group database
*
* It should be registered when it is decided to remove a group from the
* regular group database.
*/
void cleanup_report_del_group_group (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR,
"failed to remove group %s from %s",
name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"removing group from /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#ifdef SHADOWGRP
/*
* cleanup_report_del_group_gshadow - Report failure to remove a group from
* gshadow
*
* It should be registered when it is decided to remove a group from the
* gshadow database.
*/
void cleanup_report_del_group_gshadow (void *group_name)
{
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR,
"failed to remove group %s from %s",
name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
"removing group from /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#endif
/*
* cleanup_unlock_group - Unlock the group file
*
* It should be registered after the group file is successfully locked.
*/
void cleanup_unlock_group (unused void *arg)
{
if (gr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, gr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking group file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
#ifdef SHADOWGRP
/*
* cleanup_unlock_gshadow - Unlock the gshadow file
*
* It should be registered after the gshadow file is successfully locked.
*/
void cleanup_unlock_gshadow (unused void *arg)
{
if (sgr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking gshadow file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
#endif

152
libmisc/cleanup_user.c Normal file
View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "defines.h"
#include "pwio.h"
#include "shadowio.h"
#include "prototypes.h"
/*
* cleanup_report_add_user - Report failure to add an user to the system
*
* It should be registered when it is decided to add an user to the system.
*/
void cleanup_report_add_user (void *user_name)
{
const char *name = (const char *)user_name;
SYSLOG ((LOG_ERR, "failed to add user %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
void cleanup_report_mod_passwd (void *cleanup_info)
{
const struct cleanup_info_mod *info;
info = (const struct cleanup_info_mod *)cleanup_info;
SYSLOG ((LOG_ERR,
"failed to change %s (%s)",
pw_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, Prog,
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_add_user_passwd - Report failure to add an user to
* /etc/passwd
*
* It should be registered when it is decided to add an user to the
* /etc/passwd database.
*/
void cleanup_report_add_user_passwd (void *user_name)
{
const char *name = (const char *)user_name;
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"adding user to /etc/passwd",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_add_user_shadow - Report failure to add an user to
* /etc/shadow
*
* It should be registered when it is decided to add an user to the
* /etc/shadow database.
*/
void cleanup_report_add_user_shadow (void *user_name)
{
const char *name = (const char *)user_name;
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, Prog,
"adding user to /etc/shadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_unlock_passwd - Unlock the /etc/passwd database
*
* It should be registered after the passwd database is successfully locked.
*/
void cleanup_unlock_passwd (unused void *arg)
{
if (pw_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, pw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking passwd file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
/*
* cleanup_unlock_shadow - Unlock the /etc/shadow database
*
* It should be registered after the shadow database is successfully locked.
*/
void cleanup_unlock_shadow (unused void *arg)
{
if (spw_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, spw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking shadow file",
SHADOW_AUDIT_FAILURE);
#endif
}
}

View File

@@ -40,14 +40,14 @@
#ident "$Id$"
/* local function prototypes */
static int is_listed (const char *cfgin, const char *tty, int def);
static bool is_listed (const char *cfgin, const char *tty, bool def);
/*
* This is now rather generic function which decides if "tty" is listed
* under "cfgin" in config (directly or indirectly). Fallback to default if
* something is bad.
*/
static int is_listed (const char *cfgin, const char *tty, int def)
static bool is_listed (const char *cfgin, const char *tty, bool def)
{
FILE *fp;
char buf[200], *cons, *s;
@@ -57,8 +57,10 @@ static int is_listed (const char *cfgin, const char *tty, int def)
* fallback to default.
*/
if ((cons = getdef_str (cfgin)) == NULL)
cons = getdef_str (cfgin);
if (NULL == cons) {
return def;
}
/*
* If this isn't a filename, then it is a ":" delimited list of
@@ -66,14 +68,15 @@ static int is_listed (const char *cfgin, const char *tty, int def)
*/
if (*cons != '/') {
cons = strcpy (buf, cons);
while ((s = strtok (cons, ":")) != NULL) {
if (strcmp (s, tty) == 0)
return 1;
strcpy (buf, cons);
while ((s = strtok (buf, ":")) != NULL) {
if (strcmp (s, tty) == 0) {
return true;
}
cons = NULL;
}
return 0;
return false;
}
/*
@@ -81,18 +84,20 @@ static int is_listed (const char *cfgin, const char *tty, int def)
* console - otherwise root will never be allowed to login.
*/
if ((fp = fopen (cons, "r")) == NULL)
fp = fopen (cons, "r");
if (NULL == fp) {
return def;
}
/*
* See if this tty is listed in the console file.
*/
while (fgets (buf, sizeof (buf), fp) != NULL) {
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
buf[strlen (buf) - 1] = '\0';
if (strcmp (buf, tty) == 0) {
(void) fclose (fp);
return 1;
return true;
}
}
@@ -101,7 +106,7 @@ static int is_listed (const char *cfgin, const char *tty, int def)
*/
(void) fclose (fp);
return 0;
return false;
}
/*
@@ -114,7 +119,12 @@ static int is_listed (const char *cfgin, const char *tty, int def)
* that would allow an unauthorized root login.
*/
int console (const char *tty)
bool console (const char *tty)
{
return is_listed ("CONSOLE", tty, 1);
if (strncmp (tty, "/dev/", 5) == 0) {
tty += 5;
}
return is_listed ("CONSOLE", tty, true);
}

View File

@@ -34,6 +34,7 @@
#ident "$Id$"
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
@@ -43,37 +44,37 @@
#include "defines.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
static int selinux_enabled = -1;
#endif
static const char *src_orig;
static const char *dst_orig;
static /*@null@*/const char *src_orig;
static /*@null@*/const char *dst_orig;
struct link_name {
dev_t ln_dev;
ino_t ln_ino;
int ln_count;
nlink_t ln_count;
char *ln_name;
struct link_name *ln_next;
/*@dependent@*/struct link_name *ln_next;
};
static struct link_name *links;
static /*@exposed@*/struct link_name *links;
static int copy_entry (const char *src, const char *dst,
long int uid, long int gid);
static int copy_dir (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid);
#ifdef S_IFLNK
static char *readlink_malloc (const char *filename);
static int copy_symlink (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid);
#endif
static int copy_hardlink (const char *src, const char *dst,
struct link_name *lp);
static int copy_special (const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid);
static int copy_file (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid);
#ifdef WITH_SELINUX
@@ -84,14 +85,21 @@ static int copy_file (const char *src, const char *dst,
* selinux_file_context () should be called before any creation of file,
* symlink, directory, ...
*
* Callers may have to Reset SELinux to create files with default
* contexts:
* setfscreatecon (NULL);
*/
static int selinux_file_context (const char *dst_name)
int selinux_file_context (const char *dst_name)
{
static bool selinux_checked = false;
static bool selinux_enabled;
security_context_t scontext = NULL;
if (selinux_enabled < 0) {
if (!selinux_checked) {
selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true;
}
if (selinux_enabled) {
/* Get the default security context for this file */
if (matchpathcon (dst_name, 0, &scontext) < 0) {
@@ -114,7 +122,7 @@ static int selinux_file_context (const char *dst_name)
/*
* remove_link - delete a link from the linked list
*/
static void remove_link (struct link_name *ln)
static void remove_link (/*@only@*/struct link_name *ln)
{
struct link_name *lp;
@@ -131,6 +139,8 @@ static void remove_link (struct link_name *ln)
}
if (NULL == lp) {
free (ln->ln_name);
free (ln);
return;
}
@@ -143,15 +153,19 @@ static void remove_link (struct link_name *ln)
* check_link - see if a file is really a link
*/
static struct link_name *check_link (const char *name, const struct stat *sb)
static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, const struct stat *sb)
{
struct link_name *lp;
int src_len;
int dst_len;
int name_len;
int len;
size_t src_len;
size_t dst_len;
size_t name_len;
size_t len;
for (lp = links; lp; lp = lp->ln_next) {
/* copy_tree () must be the entry point */
assert (NULL != src_orig);
assert (NULL != dst_orig);
for (lp = links; NULL != lp; lp = lp->ln_next) {
if ((lp->ln_dev == sb->st_dev) && (lp->ln_ino == sb->st_ino)) {
return lp;
}
@@ -169,7 +183,7 @@ static struct link_name *check_link (const char *name, const struct stat *sb)
lp->ln_ino = sb->st_ino;
lp->ln_count = sb->st_nlink;
len = name_len - src_len + dst_len + 1;
lp->ln_name = xmalloc (len);
lp->ln_name = (char *) xmalloc (len);
snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len);
lp->ln_next = links;
links = lp;
@@ -186,10 +200,8 @@ static struct link_name *check_link (const char *name, const struct stat *sb)
int copy_tree (const char *src_root, const char *dst_root,
long int uid, long int gid)
{
char src_name[1024];
char dst_name[1024];
int err = 0;
int set_orig = 0;
bool set_orig = false;
struct DIRECT *ent;
DIR *dir;
@@ -216,10 +228,10 @@ int copy_tree (const char *src_root, const char *dst_root,
return -1;
}
if (src_orig == 0) {
if (src_orig == NULL) {
src_orig = src_root;
dst_orig = dst_root;
set_orig++;
set_orig = true;
}
while ((0 == err) && (ent = readdir (dir)) != NULL) {
/*
@@ -227,35 +239,54 @@ int copy_tree (const char *src_root, const char *dst_root,
*/
if ((strcmp (ent->d_name, ".") != 0) &&
(strcmp (ent->d_name, "..") != 0)) {
/*
* Make sure the resulting source and destination
* filenames will fit in their buffers.
*/
if ( (strlen (src_root) + strlen (ent->d_name) + 2 >
sizeof src_name)
|| (strlen (dst_root) + strlen (ent->d_name) + 2 >
sizeof dst_name)) {
char *src_name;
char *dst_name;
size_t src_len = strlen (ent->d_name) + 2;
size_t dst_len = strlen (ent->d_name) + 2;
src_len += strlen (src_root);
dst_len += strlen (dst_root);
src_name = (char *) malloc (src_len);
dst_name = (char *) malloc (dst_len);
if ((NULL == src_name) || (NULL == dst_name)) {
err = -1;
} else {
/*
* Build the filename for both the source and
* the destination files.
*/
snprintf (src_name, sizeof src_name, "%s/%s",
snprintf (src_name, src_len, "%s/%s",
src_root, ent->d_name);
snprintf (dst_name, sizeof dst_name, "%s/%s",
snprintf (dst_name, dst_len, "%s/%s",
dst_root, ent->d_name);
err = copy_entry (src_name, dst_name, uid, gid);
}
if (NULL != src_name) {
free (src_name);
}
if (NULL != dst_name) {
free (dst_name);
}
}
}
(void) closedir (dir);
if (set_orig) {
src_orig = 0;
dst_orig = 0;
src_orig = NULL;
dst_orig = NULL;
}
#ifdef WITH_SELINUX
/* Reset SELinux to create files with default contexts */
setfscreatecon (NULL);
#endif
/* FIXME: with the call to remove_link, we could also check that
* no links remain in links.
* assert (NULL == links); */
return err;
}
@@ -285,16 +316,28 @@ static int copy_entry (const char *src, const char *dst,
if (LSTAT (src, &sb) == -1) {
/* If we cannot stat the file, do not care. */
} else {
#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE)
#ifdef HAVE_STRUCT_STAT_ST_ATIM
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
#else
mt[0].tv_sec = sb.st_atime;
#ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
mt[0].tv_usec = sb.st_atimensec / 1000;
#else
mt[0].tv_usec = 0;
#endif
#endif
#ifdef HAVE_STRUCT_STAT_ST_MTIM
mt[1].tv_sec = sb.st_mtim.tv_sec;
mt[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
#else
mt[0].tv_sec = sb.st_atime;
mt[0].tv_usec = sb.st_atimensec / 1000;
mt[1].tv_sec = sb.st_mtime;
#ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
mt[1].tv_usec = sb.st_mtimensec / 1000;
#else
mt[1].tv_usec = 0;
#endif
#endif
if (S_ISDIR (sb.st_mode)) {
@@ -353,7 +396,7 @@ static int copy_entry (const char *src, const char *dst,
* Return 0 on success, -1 on error.
*/
static int copy_dir (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid)
{
int err = 0;
@@ -380,6 +423,41 @@ static int copy_dir (const char *src, const char *dst,
}
#ifdef S_IFLNK
/*
* readlink_malloc - wrapper for readlink
*
* return NULL on error.
* The return string shall be freed by the caller.
*/
static char *readlink_malloc (const char *filename)
{
size_t size = 1024;
while (1) {
ssize_t nchars;
char *buffer = (char *) malloc (size);
if (NULL == buffer) {
return NULL;
}
nchars = readlink (filename, buffer, size);
if (nchars < 0) {
return NULL;
}
if ( (size_t) nchars < size) { /* The buffer was large enough */
/* readlink does not nul-terminate */
buffer[nchars] = '\0';
return buffer;
}
/* Try again with a bigger buffer */
free (buffer);
size *= 2;
}
}
/*
* copy_symlink - copy a symlink
*
@@ -391,13 +469,14 @@ static int copy_dir (const char *src, const char *dst,
* Return 0 on success, -1 on error.
*/
static int copy_symlink (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid)
{
char oldlink[1024];
char dummy[1024];
int len;
int err = 0;
char *oldlink;
/* copy_tree () must be the entry point */
assert (NULL != src_orig);
assert (NULL != dst_orig);
/*
* Get the name of the file which the link points
@@ -407,17 +486,26 @@ static int copy_symlink (const char *src, const char *dst,
* destination directory name.
*/
len = readlink (src, oldlink, sizeof (oldlink) - 1);
if (len < 0) {
oldlink = readlink_malloc (src);
if (NULL == oldlink) {
return -1;
}
oldlink[len] = '\0'; /* readlink() does not NUL-terminate */
/* If src was a link to an entry of the src_orig directory itself,
* create a link to the corresponding entry in the dst_orig
* directory.
* FIXME: This may change a relative link to an absolute link
*/
if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
snprintf (dummy, sizeof dummy, "%s%s",
size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
char *dummy = (char *) malloc (len);
snprintf (dummy, len, "%s%s",
dst_orig,
oldlink + strlen (src_orig));
strcpy (oldlink, dummy);
free (oldlink);
oldlink = dummy;
}
#ifdef WITH_SELINUX
selinux_file_context (dst);
#endif
@@ -425,17 +513,21 @@ static int copy_symlink (const char *src, const char *dst,
|| (lchown (dst,
(uid == -1) ? statp->st_uid : (uid_t) uid,
(gid == -1) ? statp->st_gid : (gid_t) gid) != 0)) {
free (oldlink);
return -1;
}
free (oldlink);
#ifdef HAVE_LUTIMES
/* 2007-10-18: We don't care about
* exit status of lutimes because
* it returns ENOSYS on many system
* - not implemented
*/
lutimes (dst, mt);
#endif
return err;
return 0;
}
#endif
@@ -454,10 +546,13 @@ static int copy_hardlink (const char *src, const char *dst,
if (link (lp->ln_name, dst) != 0) {
return -1;
}
/* FIXME: why is it unlinked? This is a copy, not a move */
if (unlink (src) != 0) {
return -1;
}
/* FIXME: idem, although it may never be used again */
/* If the file could be unlinked, decrement the links counter,
* and delete the file if it was the last reference */
lp->ln_count--;
@@ -479,7 +574,7 @@ static int copy_hardlink (const char *src, const char *dst,
* Return 0 on success, -1 on error.
*/
static int copy_special (const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid)
{
int err = 0;
@@ -511,14 +606,14 @@ static int copy_special (const char *dst,
* Return 0 on success, -1 on error.
*/
static int copy_file (const char *src, const char *dst,
const struct stat *statp, const struct timeval mt[2],
const struct stat *statp, const struct timeval mt[],
long int uid, long int gid)
{
int err = 0;
int ifd;
int ofd;
char buf[1024];
int cnt;
ssize_t cnt;
ifd = open (src, O_RDONLY);
if (ifd < 0) {
@@ -527,32 +622,40 @@ static int copy_file (const char *src, const char *dst,
#ifdef WITH_SELINUX
selinux_file_context (dst);
#endif
ofd = open (dst, O_WRONLY | O_CREAT | O_TRUNC, 0);
ofd = open (dst, O_WRONLY | O_CREAT | O_TRUNC, statp->st_mode & 07777);
if ( (ofd < 0)
|| (chown (dst,
(uid == -1) ? statp->st_uid : (uid_t) uid,
(gid == -1) ? statp->st_gid : (gid_t) gid) != 0)
|| (chmod (dst, statp->st_mode & 07777) != 0)) {
|| (fchown (ofd,
(uid == -1) ? statp->st_uid : (uid_t) uid,
(gid == -1) ? statp->st_gid : (gid_t) gid) != 0)
|| (fchmod (ofd, statp->st_mode & 07777) != 0)) {
(void) close (ifd);
return -1;
}
while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
if (write (ofd, buf, cnt) != cnt) {
if (write (ofd, buf, (size_t)cnt) != cnt) {
return -1;
}
}
(void) close (ifd);
#ifdef HAVE_FUTIMES
if (futimes (ofd, mt) != 0) {
return -1;
}
#endif
if (close (ofd) != 0) {
return -1;
}
#ifndef HAVE_FUTIMES
if (utimes(dst, mt) != 0) {
return -1;
}
#endif
return err;
}
@@ -566,20 +669,12 @@ static int copy_file (const char *src, const char *dst,
int remove_tree (const char *root)
{
char new_name[1024];
char *new_name = NULL;
int err = 0;
struct DIRECT *ent;
struct stat sb;
DIR *dir;
/*
* Make certain the directory exists.
*/
if (access (root, F_OK) != 0) {
return -1;
}
/*
* Open the source directory and read each entry. Every file
* entry in the directory is copied with the UID and GID set
@@ -593,6 +688,7 @@ int remove_tree (const char *root)
}
while ((ent = readdir (dir))) {
size_t new_len = strlen (root) + strlen (ent->d_name) + 2;
/*
* Skip the "." and ".." entries
@@ -607,12 +703,15 @@ int remove_tree (const char *root)
* Make the filename for the current entry.
*/
if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) {
if (NULL != new_name) {
free (new_name);
}
new_name = (char *) malloc (new_len);
if (NULL == new_name) {
err = -1;
break;
}
snprintf (new_name, sizeof new_name, "%s/%s", root,
ent->d_name);
snprintf (new_name, new_len, "%s/%s", root, ent->d_name);
if (LSTAT (new_name, &sb) == -1) {
continue;
}
@@ -635,6 +734,9 @@ int remove_tree (const char *root)
}
}
}
if (NULL != new_name) {
free (new_name);
}
(void) closedir (dir);
if (0 == err) {

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1992, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#ident "$Id$"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -46,7 +47,7 @@
*/
#define NEWENVP_STEP 16
size_t newenvc = 0;
char **newenvp = NULL;
/*@null@*/char **newenvp = NULL;
extern char **environ;
static const char *forbid[] = {
@@ -85,15 +86,18 @@ void initenv (void)
}
void addenv (const char *string, const char *value)
void addenv (const char *string, /*@null@*/const char *value)
{
char *cp, *newstring;
size_t i;
size_t n;
if (value) {
newstring = xmalloc (strlen (string) + strlen (value) + 2);
sprintf (newstring, "%s=%s", string, value);
if (NULL != value) {
size_t len = strlen (string) + strlen (value) + 2;
int wlen;
newstring = xmalloc (len);
wlen = snprintf (newstring, len, "%s=%s", string, value);
assert (wlen == (int) len -1);
} else {
newstring = xstrdup (string);
}
@@ -104,7 +108,7 @@ void addenv (const char *string, const char *value)
*/
cp = strchr (newstring, '=');
if (!cp) {
if (NULL == cp) {
free (newstring);
return;
}
@@ -112,9 +116,10 @@ void addenv (const char *string, const char *value)
n = (size_t) (cp - newstring);
for (i = 0; i < newenvc; i++) {
if (strncmp (newstring, newenvp[i], n) == 0 &&
(newenvp[i][n] == '=' || newenvp[i][n] == '\0'))
if ( (strncmp (newstring, newenvp[i], n) == 0)
&& (('=' == newenvp[i][n]) || ('\0' == newenvp[i][n]))) {
break;
}
}
if (i < newenvc) {
@@ -151,12 +156,14 @@ void addenv (const char *string, const char *value)
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
if (environ == newenvp)
if (environ == newenvp) {
environ = __newenvp;
}
newenvp = __newenvp;
} else {
fputs (_("Environment overflow\n"), stderr);
free (newenvp[--newenvc]);
(void) fputs (_("Environment overflow\n"), stderr);
newenvc--;
free (newenvp[newenvc]);
}
}
@@ -178,21 +185,28 @@ void set_env (int argc, char *const *argv)
char *cp;
for (; argc > 0; argc--, argv++) {
if (strlen (*argv) >= sizeof variable)
if (strlen (*argv) >= sizeof variable) {
continue; /* ignore long entries */
}
if (!(cp = strchr (*argv, '='))) {
snprintf (variable, sizeof variable, "L%d", noname++);
cp = strchr (*argv, '=');
if (NULL == cp) {
int wlen;
wlen = snprintf (variable, sizeof variable, "L%d", noname);
assert (wlen < (int) sizeof(variable));
noname++;
addenv (variable, *argv);
} else {
const char **p;
for (p = forbid; *p; p++)
if (strncmp (*argv, *p, strlen (*p)) == 0)
for (p = forbid; NULL != *p; p++) {
if (strncmp (*argv, *p, strlen (*p)) == 0) {
break;
}
}
if (*p) {
strncpy (variable, *argv, cp - *argv);
if (NULL != *p) {
strncpy (variable, *argv, (size_t)(cp - *argv));
variable[cp - *argv] = '\0';
printf (_("You may not change $%s\n"),
variable);
@@ -220,27 +234,32 @@ void sanitize_env (void)
char **cur;
char **move;
for (cur = envp; *cur; cur++) {
for (bad = forbid; *bad; bad++) {
for (cur = envp; NULL != *cur; cur++) {
for (bad = forbid; NULL != *bad; bad++) {
if (strncmp (*cur, *bad, strlen (*bad)) == 0) {
for (move = cur; *move; move++)
for (move = cur; NULL != *move; move++) {
*move = *(move + 1);
}
cur--;
break;
}
}
}
for (cur = envp; *cur; cur++) {
for (bad = noslash; *bad; bad++) {
if (strncmp (*cur, *bad, strlen (*bad)) != 0)
for (cur = envp; NULL != *cur; cur++) {
for (bad = noslash; NULL != *bad; bad++) {
if (strncmp (*cur, *bad, strlen (*bad)) != 0) {
continue;
if (!strchr (*cur, '/'))
}
if (strchr (*cur, '/') != NULL) {
continue; /* OK */
for (move = cur; *move; move++)
}
for (move = cur; NULL != *move; move++) {
*move = *(move + 1);
}
cur--;
break;
}
}
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2002 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "defines.h"
#include "faillog.h"
#include "getdef.h"
@@ -49,13 +51,23 @@
void failure (uid_t uid, const char *tty, struct faillog *fl)
{
int fd;
off_t offset_uid = (off_t) (sizeof *fl) * uid;
/*
* Don't do anything if failure logging isn't set up.
*/
if ((fd = open (FAILLOG_FILE, O_RDWR)) < 0)
if (access (FAILLOG_FILE, F_OK) != 0) {
return;
}
fd = open (FAILLOG_FILE, O_RDWR);
if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
return;
}
/*
* The file is indexed by UID value meaning that shared UID's
@@ -63,9 +75,17 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
* share just about everything else ...
*/
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
if (read (fd, (char *) fl, sizeof *fl) != sizeof *fl)
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
/* This is not necessarily a failure. The file is
* initially zero length.
*
* If lseek() or read() failed for any other reason, this
* might reset the counter. But the new failure will be
* logged.
*/
memzero (fl, sizeof *fl);
}
/*
* Update the record. We increment the failure count to log the
@@ -74,11 +94,12 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
* updated as well.
*/
if (fl->fail_cnt + 1 > 0)
if (fl->fail_cnt + 1 > 0) {
fl->fail_cnt++;
}
strncpy (fl->fail_line, tty, sizeof fl->fail_line);
time (&fl->fail_time);
(void) time (&fl->fail_time);
/*
* Seek back to the correct position in the file and write the
@@ -87,26 +108,34 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
* seem that great.
*/
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
write (fd, (char *) fl, sizeof *fl);
close (fd);
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
(void) close (fd);
}
}
static int too_many_failures (const struct faillog *fl)
static bool too_many_failures (const struct faillog *fl)
{
time_t now;
if (fl->fail_max == 0 || fl->fail_cnt < fl->fail_max)
return 0;
if ((0 == fl->fail_max) || (fl->fail_cnt < fl->fail_max)) {
return false;
}
if (fl->fail_locktime == 0)
return 1; /* locked until reset manually */
if (0 == fl->fail_locktime) {
return true; /* locked until reset manually */
}
time (&now);
if (fl->fail_time + fl->fail_locktime < now)
return 0; /* enough time since last failure */
(void) time (&now);
if ((fl->fail_time + fl->fail_locktime) < now) {
return false; /* enough time since last failure */
}
return 1;
return true;
}
/*
@@ -114,21 +143,35 @@ static int too_many_failures (const struct faillog *fl)
*
* failcheck() is called AFTER the password has been validated. If the
* account has been "attacked" with too many login failures, failcheck()
* returns FALSE to indicate that the login should be denied even though
* returns 0 to indicate that the login should be denied even though
* the password is valid.
*
* failed indicates if the login failed AFTER the password has been
* validated.
*/
int failcheck (uid_t uid, struct faillog *fl, int failed)
int failcheck (uid_t uid, struct faillog *fl, bool failed)
{
int fd;
struct faillog fail;
off_t offset_uid = (off_t) (sizeof *fl) * uid;
/*
* Suppress the check if the log file isn't there.
*/
if ((fd = open (FAILLOG_FILE, O_RDWR)) < 0)
if (access (FAILLOG_FILE, F_OK) != 0) {
return 1;
}
fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR);
if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't open the faillog file (%s) to check UID %lu. "
"User access authorized.",
FAILLOG_FILE, (unsigned long) uid));
return 1;
}
/*
* Get the record from the file and determine if the user has
@@ -142,14 +185,14 @@ int failcheck (uid_t uid, struct faillog *fl, int failed)
* no need to reset the count.
*/
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
if (read (fd, (char *) fl, sizeof *fl) != sizeof *fl) {
close (fd);
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
(void) close (fd);
return 1;
}
if (too_many_failures (fl)) {
close (fd);
(void) close (fd);
return 0;
}
@@ -164,10 +207,18 @@ int failcheck (uid_t uid, struct faillog *fl, int failed)
fail = *fl;
fail.fail_cnt = 0;
lseek (fd, (off_t) sizeof fail * uid, SEEK_SET);
write (fd, (char *) &fail, sizeof fail);
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
(void) close (fd);
}
} else {
(void) close (fd);
}
close (fd);
return 1;
}
@@ -190,17 +241,18 @@ void failprint (const struct faillog *fail)
#endif
time_t NOW;
if (fail->fail_cnt == 0)
if (0 == fail->fail_cnt) {
return;
}
tp = localtime (&(fail->fail_time));
time (&NOW);
(void) time (&NOW);
#if HAVE_STRFTIME
/*
* Print all information we have.
*/
strftime (lasttimeb, sizeof lasttimeb, "%c", tp);
(void) strftime (lasttimeb, sizeof lasttimeb, "%c", tp);
#else
/*
@@ -210,35 +262,38 @@ void failprint (const struct faillog *fail)
lasttime = asctime (tp);
lasttime[24] = '\0';
if (NOW - fail->fail_time < YEAR)
if ((NOW - fail->fail_time) < YEAR) {
lasttime[19] = '\0';
if (NOW - fail->fail_time < DAY)
}
if ((NOW - fail->fail_time) < DAY) {
lasttime = lasttime + 11;
}
if (*lasttime == ' ')
if (' ' == *lasttime) {
lasttime++;
}
#endif
printf (ngettext ("%d failure since last login.\n"
"Last was %s on %s.\n",
"%d failures since last login.\n"
"Last was %s on %s.\n",
fail->fail_cnt),
fail->fail_cnt, lasttime, fail->fail_line);
(void) printf (ngettext ("%d failure since last login.\n"
"Last was %s on %s.\n",
"%d failures since last login.\n"
"Last was %s on %s.\n",
(unsigned long) fail->fail_cnt),
fail->fail_cnt, lasttime, fail->fail_line);
}
/*
* failtmp - update the cummulative failure log
* failtmp - update the cumulative failure log
*
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
void failtmp (
#ifdef HAVE_UTMPX_H
void failtmp (const char *username,
#ifdef USE_UTMPX
const struct utmpx *failent
#else
#else /* !USE_UTMPX */
const struct utmp *failent
#endif
#endif /* !USE_UTMPX */
)
{
char *ftmp;
@@ -249,21 +304,38 @@ void failtmp (
* in login.defs, don't do this.
*/
if (!(ftmp = getdef_str ("FTMP_FILE")))
ftmp = getdef_str ("FTMP_FILE");
if (NULL == ftmp) {
return;
}
/*
* Open the file for append. It must already exist for this
* feature to be used.
*/
if ((fd = open (ftmp, O_WRONLY | O_APPEND)) == -1)
if (access (ftmp, F_OK) != 0) {
return;
}
fd = open (ftmp, O_WRONLY | O_APPEND);
if (-1 == fd) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",
username, ftmp));
return;
}
/*
* Output the new failure record and close the log file.
* Append the new failure record and close the log file.
*/
write (fd, (const char *) failent, sizeof *failent);
close (fd);
if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",
username, ftmp));
(void) close (fd);
}
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1997 - 2000, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,11 +36,11 @@
#include "defines.h"
#include "faillog.h"
#ifdef HAVE_UTMPX_H
#ifdef USE_UTMPX
#include <utmpx.h>
#else
#else /* !USE_UTMPX */
#include <utmp.h>
#endif
#endif /* !USE_UTMPX */
/*
* failure - make failure entry
@@ -57,7 +58,7 @@ extern void failure (uid_t, const char *, struct faillog *);
* returns FALSE to indicate that the login should be denied even though
* the password is valid.
*/
extern int failcheck (uid_t, struct faillog *, int);
extern int failcheck (uid_t uid, struct faillog *fl, bool failed);
/*
* failprint - print line of failure information
@@ -73,11 +74,11 @@ extern void failprint (const struct faillog *);
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
#ifdef HAVE_UTMPX_H
extern void failtmp (const struct utmpx *);
#else
extern void failtmp (const struct utmp *);
#endif
#ifdef USE_UTMPX
extern void failtmp (const char *username, const struct utmpx *);
#else /* !USE_UTMPX */
extern void failtmp (const char *username, const struct utmp *);
#endif /* !USE_UTMPX */
#endif

184
libmisc/find_new_gid.c Normal file
View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
#include "groupio.h"
#include "getdef.h"
/*
* find_new_gid - Find a new unused GID.
*
* If successful, find_new_gid provides an unused group ID in the
* [GID_MIN:GID_MAX] range.
* This ID should be higher than all the used GID, but if not possible,
* the lowest unused ID in the range will be returned.
*
* Return 0 on success, -1 if no unused GIDs are available.
*/
int find_new_gid (bool sys_group,
gid_t *gid,
/*@null@*/gid_t const *preferred_gid)
{
const struct group *grp;
gid_t gid_min, gid_max, group_id, id;
bool *used_gids;
assert (gid != NULL);
if (!sys_group) {
gid_min = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
gid_max = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
} else {
gid_min = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL);
gid_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
gid_max = (gid_t) getdef_ulong ("SYS_GID_MAX", (unsigned long) gid_max);
}
used_gids = alloca (sizeof (bool) * (gid_max +1));
memset (used_gids, false, sizeof (bool) * (gid_max + 1));
if ( (NULL != preferred_gid)
&& (*preferred_gid >= gid_min)
&& (*preferred_gid <= gid_max)
/* Check if the user exists according to NSS */
&& (getgrgid (*preferred_gid) == NULL)
/* Check also the local database in case of uncommitted
* changes */
&& (gr_locate_gid (*preferred_gid) == NULL)) {
*gid = *preferred_gid;
return 0;
}
/*
* Search the entire group file,
* looking for the largest unused value.
*
* We check the list of groups according to NSS (setgrent/getgrent),
* but we also check the local database (gr_rewind/gr_next) in case
* some groups were created but the changes were not committed yet.
*/
if (sys_group) {
/* setgrent / getgrent / endgrent can be very slow with
* LDAP configurations (and many accounts).
* Since there is a limited amount of IDs to be tested
* for system accounts, we just check the existence
* of IDs with getgrgid.
*/
group_id = gid_max;
for (id = gid_max; id >= gid_min; id--) {
if (getgrgid (id) != NULL) {
group_id = id - 1;
used_gids[id] = true;
}
}
gr_rewind ();
while ((grp = gr_next ()) != NULL) {
if ((grp->gr_gid <= group_id) && (grp->gr_gid >= gid_min)) {
group_id = grp->gr_gid - 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
} else {
group_id = gid_min;
setgrent ();
while ((grp = getgrent ()) != NULL) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
group_id = grp->gr_gid + 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
endgrent ();
gr_rewind ();
while ((grp = gr_next ()) != NULL) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
group_id = grp->gr_gid + 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
}
/*
* If a group with GID equal to GID_MAX exists, the above algorithm
* will give us GID_MAX+1 even if not unique. Search for the first
* free GID starting with GID_MIN.
*/
if (sys_group) {
if (group_id == gid_min - 1) {
for (group_id = gid_max; group_id >= gid_min; group_id--) {
if (false == used_gids[group_id]) {
break;
}
}
if ( group_id < gid_min ) {
fprintf (stderr,
_("%s: Can't get unique system GID (no more available GIDs)\n"),
Prog);
SYSLOG ((LOG_WARN,
"no more available GID on the system"));
return -1;
}
}
} else {
if (group_id == gid_max + 1) {
for (group_id = gid_min; group_id < gid_max; group_id++) {
if (false == used_gids[group_id]) {
break;
}
}
if (group_id == gid_max) {
fprintf (stderr,
_("%s: Can't get unique GID (no more available GIDs)\n"),
Prog);
SYSLOG ((LOG_WARN, "no more available GID on the system"));
return -1;
}
}
}
*gid = group_id;
return 0;
}

View File

@@ -1,205 +0,0 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
#include "pwio.h"
#include "groupio.h"
#include "getdef.h"
/*
* find_new_uid - Find a new unused UID.
*
* If successful, find_new_uid provides an unused user ID in the
* [UID_MIN:UID_MAX] range.
* This ID should be higher than all the used UID, but if not possible,
* the lowest unused ID in the range will be returned.
*
* Return 0 on success, -1 if no unused UIDs are available.
*/
int find_new_uid (int sys_user, uid_t *uid, uid_t const *preferred_uid)
{
const struct passwd *pwd;
uid_t uid_min, uid_max, user_id;
assert (uid != NULL);
if (sys_user == 0) {
uid_min = getdef_unum ("UID_MIN", 1000);
uid_max = getdef_unum ("UID_MAX", 60000);
} else {
uid_min = getdef_unum ("SYS_UID_MIN", 1);
uid_max = getdef_unum ("UID_MIN", 1000) - 1;
uid_max = getdef_unum ("SYS_UID_MAX", uid_max);
}
if ( (NULL != preferred_uid)
&& (*preferred_uid >= uid_min)
&& (*preferred_uid <= uid_max)
/* Check if the user exists according to NSS */
&& (getpwuid (*preferred_uid) == NULL)
/* Check also the local database in case of uncommitted
* changes */
&& (pw_locate_uid (*preferred_uid) == NULL)) {
*uid = *preferred_uid;
return 0;
}
user_id = uid_min;
/*
* Search the entire password file,
* looking for the largest unused value.
*
* We check the list of users according to NSS (setpwent/getpwent),
* but we also check the local database (pw_rewind/pw_next) in case
* some users were created but the changes were not committed yet.
*/
setpwent ();
pw_rewind ();
while ( ((pwd = getpwent ()) != NULL)
|| ((pwd = pw_next ()) != NULL)) {
if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) {
user_id = pwd->pw_uid + 1;
}
}
endpwent ();
/*
* If a user with UID equal to UID_MAX exists, the above algorithm
* will give us UID_MAX+1 even if not unique. Search for the first
* free UID starting with UID_MIN (it's O(n*n) but can be avoided
* by not having users with UID equal to UID_MAX). --marekm
*/
if (user_id == uid_max + 1) {
for (user_id = uid_min; user_id < uid_max; user_id++) {
/* local, no need for xgetpwuid */
if ( (getpwuid (user_id) == NULL)
&& (pw_locate_uid (user_id) == NULL)) {
break;
}
}
if (user_id == uid_max) {
fputs (_("Can't get unique UID (no more available UIDs)\n"), stderr);
return -1;
}
}
*uid = user_id;
return 0;
}
/*
* find_new_gid - Find a new unused GID.
*
* If successful, find_new_gid provides an unused group ID in the
* [GID_MIN:GID_MAX] range.
* This ID should be higher than all the used GID, but if not possible,
* the lowest unused ID in the range will be returned.
*
* Return 0 on success, -1 if no unused GIDs are available.
*/
int find_new_gid (int sys_group, gid_t *gid, gid_t const *preferred_gid)
{
const struct group *grp;
gid_t gid_min, gid_max, group_id;
assert (gid != NULL);
if (sys_group == 0) {
gid_min = getdef_unum ("GID_MIN", 1000);
gid_max = getdef_unum ("GID_MAX", 60000);
} else {
gid_min = getdef_unum ("SYS_GID_MIN", 1);
gid_max = getdef_unum ("GID_MIN", 1000) - 1;
gid_max = getdef_unum ("SYS_GID_MAX", gid_max);
}
if ( (NULL != preferred_gid)
&& (*preferred_gid >= gid_min)
&& (*preferred_gid <= gid_max)
/* Check if the user exists according to NSS */
&& (getgrgid (*preferred_gid) == NULL)
/* Check also the local database in case of uncommitted
* changes */
&& (gr_locate_gid (*preferred_gid) == NULL)) {
*gid = *preferred_gid;
return 0;
}
group_id = gid_min;
/*
* Search the entire group file,
* looking for the largest unused value.
*
* We check the list of users according to NSS (setpwent/getpwent),
* but we also check the local database (pw_rewind/pw_next) in case
* some groups were created but the changes were not committed yet.
*/
setgrent ();
gr_rewind ();
while ( ((grp = getgrent ()) != NULL)
|| ((grp = gr_next ()) != NULL)) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
group_id = grp->gr_gid + 1;
}
}
endgrent ();
/*
* If a group with GID equal to GID_MAX exists, the above algorithm
* will give us GID_MAX+1 even if not unique. Search for the first
* free GID starting with GID_MIN (it's O(n*n) but can be avoided
* by not having users with GID equal to GID_MAX). --marekm
*/
if (group_id == gid_max + 1) {
for (group_id = gid_min; group_id < gid_max; group_id++) {
/* local, no need for xgetgrgid */
if ( (getgrgid (group_id) == NULL)
&& (gr_locate_gid (group_id) == NULL)) {
break;
}
}
if (group_id == gid_max) {
fputs (_("Can't get unique GID (no more available GIDs)\n"), stderr);
return -1;
}
}
*gid = group_id;
return 0;
}

184
libmisc/find_new_uid.c Normal file
View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
#include "pwio.h"
#include "getdef.h"
/*
* find_new_uid - Find a new unused UID.
*
* If successful, find_new_uid provides an unused user ID in the
* [UID_MIN:UID_MAX] range.
* This ID should be higher than all the used UID, but if not possible,
* the lowest unused ID in the range will be returned.
*
* Return 0 on success, -1 if no unused UIDs are available.
*/
int find_new_uid (bool sys_user,
uid_t *uid,
/*@null@*/uid_t const *preferred_uid)
{
const struct passwd *pwd;
uid_t uid_min, uid_max, user_id, id;
bool *used_uids;
assert (uid != NULL);
if (!sys_user) {
uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
} else {
uid_min = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL);
uid_max = (uid_t) getdef_ulong ("UID_MIN", 1000UL) - 1;
uid_max = (uid_t) getdef_ulong ("SYS_UID_MAX", (unsigned long) uid_max);
}
used_uids = alloca (sizeof (bool) * (uid_max +1));
memset (used_uids, false, sizeof (bool) * (uid_max + 1));
if ( (NULL != preferred_uid)
&& (*preferred_uid >= uid_min)
&& (*preferred_uid <= uid_max)
/* Check if the user exists according to NSS */
&& (getpwuid (*preferred_uid) == NULL)
/* Check also the local database in case of uncommitted
* changes */
&& (pw_locate_uid (*preferred_uid) == NULL)) {
*uid = *preferred_uid;
return 0;
}
/*
* Search the entire password file,
* looking for the largest unused value.
*
* We check the list of users according to NSS (setpwent/getpwent),
* but we also check the local database (pw_rewind/pw_next) in case
* some users were created but the changes were not committed yet.
*/
if (sys_user) {
/* setpwent / getpwent / endpwent can be very slow with
* LDAP configurations (and many accounts).
* Since there is a limited amount of IDs to be tested
* for system accounts, we just check the existence
* of IDs with getpwuid.
*/
user_id = uid_max;
for (id = uid_max; id >= uid_min; id--) {
if (getpwuid (id) != NULL) {
user_id = id - 1;
used_uids[id] = true;
}
}
pw_rewind ();
while ((pwd = pw_next ()) != NULL) {
if ((pwd->pw_uid <= user_id) && (pwd->pw_uid >= uid_min)) {
user_id = pwd->pw_uid - 1;
}
/* create index of used UIDs */
if (pwd->pw_uid <= uid_max) {
used_uids[pwd->pw_uid] = true;
}
}
} else {
user_id = uid_min;
setpwent ();
while ((pwd = getpwent ()) != NULL) {
if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) {
user_id = pwd->pw_uid + 1;
}
/* create index of used UIDs */
if (pwd->pw_uid <= uid_max) {
used_uids[pwd->pw_uid] = true;
}
}
endpwent ();
pw_rewind ();
while ((pwd = pw_next ()) != NULL) {
if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) {
user_id = pwd->pw_uid + 1;
}
/* create index of used UIDs */
if (pwd->pw_uid <= uid_max) {
used_uids[pwd->pw_uid] = true;
}
}
}
/*
* If a user with UID equal to UID_MAX exists, the above algorithm
* will give us UID_MAX+1 even if not unique. Search for the first
* free UID starting with UID_MIN.
*/
if (sys_user) {
if (user_id == uid_min - 1) {
for (user_id = uid_max; user_id >= uid_min; user_id--) {
if (false == used_uids[user_id]) {
break;
}
}
if (user_id < uid_min ) {
fprintf (stderr,
_("%s: Can't get unique system UID (no more available UIDs)\n"),
Prog);
SYSLOG ((LOG_WARN,
"no more available UID on the system"));
return -1;
}
}
} else {
if (user_id == uid_max + 1) {
for (user_id = uid_min; user_id < uid_max; user_id++) {
if (false == used_uids[user_id]) {
break;
}
}
if (user_id == uid_max) {
fprintf (stderr,
_("%s: Can't get unique UID (no more available UIDs)\n"),
Prog);
SYSLOG ((LOG_WARN, "no more available UID on the system"));
return -1;
}
}
}
*uid = user_id;
return 0;
}

View File

@@ -395,7 +395,7 @@ relunit : tUNUMBER tYEAR_UNIT {
number : tUNUMBER
{
if (yyHaveTime && yyHaveDate && !yyHaveRel)
if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0))
yyYear = $1;
else
{
@@ -647,10 +647,10 @@ static int LookupWord (char *buff)
register char *q;
register const TABLE *tp;
int i;
int abbrev;
bool abbrev;
/* Make it lowercase. */
for (p = buff; *p; p++)
for (p = buff; '\0' != *p; p++)
if (ISUPPER (*p))
*p = tolower (*p);
@@ -667,14 +667,14 @@ static int LookupWord (char *buff)
/* See if we have an abbreviation for a month. */
if (strlen (buff) == 3)
abbrev = 1;
abbrev = true;
else if (strlen (buff) == 4 && buff[3] == '.')
{
abbrev = 1;
abbrev = true;
buff[3] = '\0';
}
else
abbrev = 0;
abbrev = false;
for (tp = MonthDayTable; tp->name; tp++)
{
@@ -743,14 +743,14 @@ static int LookupWord (char *buff)
}
/* Drop out any periods and try the timezone table again. */
for (i = 0, p = q = buff; *q; q++)
for (i = 0, p = q = buff; '\0' != *q; q++)
if (*q != '.')
*p++ = *q;
else
i++;
*p = '\0';
if (i)
for (tp = TimezoneTable; tp->name; tp++)
if (0 != i)
for (tp = TimezoneTable; NULL != tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
{
yylval.Number = tp->value;
@@ -790,7 +790,7 @@ yylex (void)
yyInput--;
if (sign < 0)
yylval.Number = -yylval.Number;
return sign ? tSNUMBER : tUNUMBER;
return (0 != sign) ? tSNUMBER : tUNUMBER;
}
if (ISALPHA (c))
{
@@ -874,7 +874,8 @@ time_t get_date (const char *p, const time_t *now)
tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
tm.tm_mon = yyMonth - 1 + yyRelMonth;
tm.tm_mday = yyDay + yyRelDay;
if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay))
if ((yyHaveTime != 0) ||
( (yyHaveRel != 0) && (yyHaveDate == 0) && (yyHaveDay == 0) ))
{
tm.tm_hour = ToHour (yyHour, yyMeridian);
if (tm.tm_hour < 0)

66
libmisc/getgr_nam_gid.c Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2000 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdlib.h>
#include <errno.h>
#include <grp.h>
#include "prototypes.h"
/*
* getgr_nam_gid - Return a pointer to the group specified by a string.
* The string may be a valid GID or a valid groupname.
* If the group does not exist on the system, NULL is returned.
*/
extern /*@null@*/struct group *getgr_nam_gid (const char *grname)
{
long long int gid;
char *endptr;
if (NULL == grname) {
return NULL;
}
errno = 0;
gid = strtoll (grname, &endptr, 10);
if ( ('\0' != *grname)
&& ('\0' == *endptr)
&& (ERANGE != errno)
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
return xgetgrgid ((gid_t) gid);
}
return xgetgrnam (grname);
}

124
libmisc/getrange.c Normal file
View File

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: $"
#include <ctype.h>
#include <stdlib.h>
#include "defines.h"
#include "prototypes.h"
/*
* Parse a range and indicate if the range is valid.
* Valid ranges are in the form:
* <long> -> min=max=long has_min has_max
* -<long> -> max=long !has_min has_max
* <long>- -> min=long has_min !has_max
* <long1>-<long2> -> min=long1 max=long2 has_min has_max
*
* If the range is valid, getrange returns 1.
* If the range is not valid, getrange returns 0.
*/
int getrange (char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max)
{
char *endptr;
unsigned long n;
if (NULL == range) {
return 0;
}
if ('-' == range[0]) {
if (!isdigit(range[1])) {
/* invalid */
return 0;
}
errno = 0;
n = strtoul (&range[1], &endptr, 10);
if (('\0' != *endptr) || (ERANGE == errno)) {
/* invalid */
return 0;
}
/* -<long> */
*has_min = false;
*has_max = true;
*max = n;
} else {
errno = 0;
n = strtoul (range, &endptr, 10);
if (ERANGE == errno) {
/* invalid */
return 0;
}
switch (*endptr) {
case '\0':
/* <long> */
*has_min = true;
*has_max = true;
*min = n;
*max = n;
break;
case '-':
endptr++;
if ('\0' == *endptr) {
/* <long>- */
*has_min = true;
*has_max = false;
*min = n;
} else if (!isdigit (*endptr)) {
/* invalid */
return 0;
} else {
*has_min = true;
*min = n;
errno = 0;
n = strtoul (endptr, &endptr, 10);
if ( ('\0' != *endptr)
|| (ERANGE == errno)) {
/* invalid */
return 0;
}
/* <long>-<long> */
*has_max = true;
*max = n;
}
break;
default:
return 0;
}
}
return 1;
}

View File

@@ -3,6 +3,7 @@
* Copyright (c) 1991 - 1993, Chip Rosenthal
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,21 +37,22 @@
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
#include <pwd.h>
/*
* hushed - determine if a user receives login messages
*
* Look in the hushed-logins file (or user's home directory) to see
* if the user is to receive the login-time messages.
*/
int hushed (const struct passwd *pw)
bool hushed (const char *username)
{
struct passwd *pw;
char *hushfile;
char buf[BUFSIZ];
int found;
bool found;
FILE *fp;
/*
@@ -58,8 +60,15 @@ int hushed (const struct passwd *pw)
* defined, default to a noisy login.
*/
if ((hushfile = getdef_str ("HUSHLOGIN_FILE")) == NULL)
return 0;
hushfile = getdef_str ("HUSHLOGIN_FILE");
if (NULL == hushfile) {
return false;
}
pw = getpwnam (username);
if (NULL == pw) {
return false;
}
/*
* If this is not a fully rooted path then see if the
@@ -73,17 +82,19 @@ int hushed (const struct passwd *pw)
/*
* If this is a fully rooted path then go through the file
* and see if this user is in there.
* and see if this user, or its shell is in there.
*/
if ((fp = fopen (hushfile, "r")) == NULL)
return 0;
for (found = 0; !found && fgets (buf, sizeof buf, fp);) {
fp = fopen (hushfile, "r");
if (NULL == fp) {
return false;
}
for (found = false; !found && (fgets (buf, (int) sizeof buf, fp) == buf);) {
buf[strlen (buf) - 1] = '\0';
found = !strcmp (buf,
buf[0] == '/' ? pw->pw_shell : pw->pw_name);
found = (strcmp (buf, pw->pw_shell) == 0) ||
(strcmp (buf, pw->pw_name) == 0);
}
(void) fclose (fp);
return found;
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,15 +51,23 @@
*
* isexpired calculates the expiration date based on the
* password expiration criteria.
*
* Return value:
* 0: The password is still valid
* 1: The password has expired, it must be changed
* 2: The password has expired since a long time and the account is
* now disabled. (password cannot be changed)
* 3: The account has expired
*/
/*ARGSUSED*/ int isexpired (const struct passwd *pw, const struct spwd *sp)
int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp)
{
long now;
now = time ((time_t *) 0) / SCALE;
now = (long) time ((time_t *) 0) / SCALE;
if (!sp)
sp = pwd_to_spwd (pw);
if (NULL == sp) {
return 0;
}
/*
* Quick and easy - there is an expired account field
@@ -66,8 +75,9 @@
* one first since it is worse.
*/
if (sp->sp_expire > 0 && now >= sp->sp_expire)
if ((sp->sp_expire > 0) && (now >= sp->sp_expire)) {
return 3;
}
/*
* Last changed date 1970-01-01 (not very likely) means that
@@ -77,12 +87,17 @@
* if /etc/shadow doesn't exist, getspnam() still succeeds and
* returns sp_lstchg==0 (must change password) instead of -1!
*/
if (sp->sp_lstchg == 0 && !strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING))
if ( (0 == sp->sp_lstchg)
&& (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)) {
return 1;
}
if (sp->sp_lstchg > 0 && sp->sp_max >= 0 && sp->sp_inact >= 0 &&
now >= sp->sp_lstchg + sp->sp_max + sp->sp_inact)
if ( (sp->sp_lstchg > 0)
&& (sp->sp_max >= 0)
&& (sp->sp_inact >= 0)
&& (now >= (sp->sp_lstchg + sp->sp_max + sp->sp_inact))) {
return 2;
}
/*
* The last and max fields must be present for an account
@@ -90,9 +105,11 @@
* is considered to be infinite.
*/
if (sp->sp_lstchg == -1 ||
sp->sp_max == -1 || sp->sp_max >= (10000L * DAY / SCALE))
if ( (-1 == sp->sp_lstchg)
|| (-1 == sp->sp_max)
|| (sp->sp_max >= (10000L * DAY / SCALE))) {
return 0;
}
/*
* Calculate today's day and the day on which the password
@@ -100,7 +117,9 @@
* the password has expired.
*/
if (now >= sp->sp_lstchg + sp->sp_max)
if (now >= (sp->sp_lstchg + sp->sp_max)) {
return 1;
}
return 0;
}

View File

@@ -65,49 +65,53 @@
* multiplier - value*multiplier is the actual limit
*/
static int
setrlimit_value (unsigned int rlimit, const char *value,
setrlimit_value (unsigned int resource, const char *value,
unsigned int multiplier)
{
struct rlimit rlim;
long limit;
char **endptr = (char **) &value;
const char *value_orig = value;
limit = strtol (value, endptr, 10);
if (limit == 0 && value_orig == *endptr) /* no chars read */
if (getlong (value, &limit) == 0) {
return 0;
}
limit *= multiplier;
rlim.rlim_cur = limit;
rlim.rlim_max = limit;
if (setrlimit (rlimit, &rlim))
if (limit != (rlim_t) limit) {
return 0;
}
rlim.rlim_cur = (rlim_t) limit;
rlim.rlim_max = (rlim_t) limit;
if (setrlimit (resource, &rlim) != 0) {
return LOGIN_ERROR_RLIMIT;
}
return 0;
}
static int set_prio (const char *value)
{
int prio;
char **endptr = (char **) &value;
long prio;
prio = strtol (value, endptr, 10);
if ((prio == 0) && (value == *endptr))
if ( (getlong (value, &prio) == 0)
|| (prio != (int) prio)) {
return 0;
if (setpriority (PRIO_PROCESS, 0, prio))
}
if (setpriority (PRIO_PROCESS, 0, (int) prio) != 0) {
return LOGIN_ERROR_RLIMIT;
}
return 0;
}
static int set_umask (const char *value)
{
mode_t mask;
char **endptr = (char **) &value;
unsigned long int mask;
mask = strtol (value, endptr, 8) & 0777;
if ((mask == 0) && (value == *endptr))
if ( (getulong (value, &mask) == 0)
|| (mask != (mode_t) mask)) {
return 0;
umask (mask);
}
(void) umask ((mode_t) mask);
return 0;
}
@@ -115,46 +119,49 @@ static int set_umask (const char *value)
/* Counts the number of user logins and check against the limit */
static int check_logins (const char *name, const char *maxlogins)
{
#if HAVE_UTMPX_H
#ifdef USE_UTMPX
struct utmpx *ut;
#else
#else /* !USE_UTMPX */
struct utmp *ut;
#endif
unsigned int limit, count;
char **endptr = (char **) &maxlogins;
const char *ml_orig = maxlogins;
#endif /* !USE_UTMPX */
unsigned long limit, count;
limit = strtol (maxlogins, endptr, 10);
if (limit == 0 && ml_orig == *endptr) /* no chars read */
if (getulong (maxlogins, &limit) == 0) {
return 0;
}
if (limit == 0) { /* maximum 0 logins ? */
if (0 == limit) { /* maximum 0 logins ? */
SYSLOG ((LOG_WARN, "No logins allowed for `%s'\n", name));
return LOGIN_ERROR_LOGIN;
}
count = 0;
#if HAVE_UTMPX_H
#ifdef USE_UTMPX
setutxent ();
while ((ut = getutxent ())) {
#else
#else /* !USE_UTMPX */
setutent ();
while ((ut = getutent ())) {
#endif
if (ut->ut_type != USER_PROCESS)
#endif /* !USE_UTMPX */
if (USER_PROCESS != ut->ut_type) {
continue;
if (ut->ut_user[0] == '\0')
}
if ('\0' == ut->ut_user[0]) {
continue;
if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0)
}
if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0) {
continue;
if (++count > limit)
}
count++;
if (count > limit) {
break;
}
}
#if HAVE_UTMPX_H
#ifdef USE_UTMPX
endutxent ();
#else
#else /* !USE_UTMPX */
endutent ();
#endif
#endif /* !USE_UTMPX */
/*
* This is called after setutmp(), so the number of logins counted
* includes the user who is currently trying to log in.
@@ -203,10 +210,11 @@ static int do_user_limits (const char *buf, const char *name)
{
const char *pp;
int retval = 0;
bool reported = false;
pp = buf;
while (*pp != '\0')
while ('\0' != *pp) {
switch (*pp++) {
#ifdef RLIMIT_AS
case 'a':
@@ -298,14 +306,24 @@ static int do_user_limits (const char *buf, const char *name)
break;
case 'l':
case 'L':
/* LIMIT the number of concurent logins */
/* LIMIT the number of concurrent logins */
retval |= check_logins (name, pp);
break;
case 'p':
case 'P':
retval |= set_prio (pp);
break;
default:
/* Only report invalid strings once */
if (!reported) {
SYSLOG ((LOG_WARN,
"Invalid limit string: '%s'",
pp-1));
reported = true;
retval |= LOGIN_ERROR_RLIMIT;
}
}
}
return retval;
}
@@ -336,8 +354,9 @@ static int setup_user_limits (const char *uname)
* - username must start on first column
* A better (smarter) checking should be done --cristiang */
while (fgets (buf, 1024, fil) != NULL) {
if (buf[0] == '#' || buf[0] == '\n')
if (('#' == buf[0]) || ('\n' == buf[0])) {
continue;
}
memzero (tempbuf, sizeof (tempbuf));
/* a valid line should have a username, then spaces,
* then limits
@@ -357,11 +376,12 @@ static int setup_user_limits (const char *uname)
}
}
}
fclose (fil);
(void) fclose (fil);
if (limits[0] == '\0') {
/* no user specific limits */
if (deflimits[0] == '\0') /* no default limits */
if (deflimits[0] == '\0') { /* no default limits */
return 0;
}
strcpy (limits, deflimits); /* use the default limits */
}
return do_user_limits (limits, uname);
@@ -372,19 +392,21 @@ static int setup_user_limits (const char *uname)
static void setup_usergroups (const struct passwd *info)
{
const struct group *grp;
mode_t oldmask;
mode_t tmpmask;
/*
* if not root, and UID == GID, and username is the same as primary
* group name, set umask group bits to be the same as owner bits
* (examples: 022 -> 002, 077 -> 007).
*/
if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) {
if ((0 != info->pw_uid) && (info->pw_uid == info->pw_gid)) {
/* local, no need for xgetgrgid */
grp = getgrgid (info->pw_gid);
if (grp && (strcmp (info->pw_name, grp->gr_name) == 0)) {
oldmask = umask (0777);
umask ((oldmask & ~070) | ((oldmask >> 3) & 070));
if ( (NULL != grp)
&& (strcmp (info->pw_name, grp->gr_name) == 0)) {
tmpmask = umask (0777);
tmpmask = (tmpmask & ~070) | ((tmpmask >> 3) & 070);
(void) umask (tmpmask);
}
}
}
@@ -396,11 +418,10 @@ static void setup_usergroups (const struct passwd *info)
void setup_limits (const struct passwd *info)
{
char *cp;
int i;
long l;
if (getdef_bool ("USERGROUPS_ENAB"))
if (getdef_bool ("USERGROUPS_ENAB")) {
setup_usergroups (info);
}
/*
* See if the GECOS field contains values for NICE, UMASK or ULIMIT.
@@ -410,33 +431,59 @@ void setup_limits (const struct passwd *info)
if (getdef_bool ("QUOTAS_ENAB")) {
#ifdef LIMITS
if (info->pw_uid != 0)
if (info->pw_uid != 0) {
if (setup_user_limits (info->pw_name) &
LOGIN_ERROR_LOGIN) {
fputs (_("Too many logins.\n"), stderr);
sleep (2);
exit (1);
(void) fputs (_("Too many logins.\n"), stderr);
(void) sleep (2); /* XXX: Should be FAIL_DELAY */
exit (EXIT_FAILURE);
}
}
#endif
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
if (*cp == ',')
if (',' == *cp) {
cp++;
}
if (strncmp (cp, "pri=", 4) == 0) {
i = atoi (cp + 4);
if (i >= -20 && i <= 20)
(void) nice (i);
long int inc;
if ( (getlong (cp + 4, &inc) == 1)
&& (inc >= -20) && (inc <= 20)) {
errno = 0;
if ( (nice ((int) inc) != -1)
|| (0 != errno)) {
continue;
}
}
/* Failed to parse or failed to nice() */
SYSLOG ((LOG_WARN,
"Can't set the nice value for user %s",
info->pw_name));
continue;
}
if (strncmp (cp, "ulimit=", 7) == 0) {
l = strtol (cp + 7, (char **) 0, 10);
set_filesize_limit (l);
long int blocks;
if ( (getlong (cp + 7, &blocks) == 0)
|| (blocks != (int) blocks)
|| (set_filesize_limit ((int) blocks) != 0)) {
SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s",
info->pw_name));
}
continue;
}
if (strncmp (cp, "umask=", 6) == 0) {
i = strtol (cp + 6, (char **) 0, 8) & 0777;
(void) umask (i);
unsigned long int mask;
if ( (getulong (cp + 6, &mask) == 0)
|| (mask != (mode_t) mask)) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",
info->pw_name));
} else {
(void) umask ((mode_t) mask);
}
continue;
}

View File

@@ -29,13 +29,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Removed duplicated code from gpmain.c, useradd.c, userdel.c and
usermod.c. --marekm */
#include <config.h>
#ident "$Id$"
#include <assert.h>
#include "prototypes.h"
#include "defines.h"
/*
@@ -45,11 +43,14 @@
* name, and if not present it is added to a freshly allocated
* list of users.
*/
char **add_list (char **list, const char *member)
/*@only@*/ /*@out@*/char **add_list (/*@returned@*/ /*@only@*/char **list, const char *member)
{
int i;
char **tmp;
assert (NULL != member);
assert (NULL != list);
/*
* Scan the list for the new name. Return the original list
* pointer if it is present.
@@ -92,11 +93,14 @@ char **add_list (char **list, const char *member)
* list of users.
*/
char **del_list (char **list, const char *member)
/*@only@*/ /*@out@*/char **del_list (/*@returned@*/ /*@only@*/char **list, const char *member)
{
int i, j;
char **tmp;
assert (NULL != member);
assert (NULL != list);
/*
* Scan the list for the old name. Return the original list
* pointer if it is not present.
@@ -137,17 +141,19 @@ char **del_list (char **list, const char *member)
return tmp;
}
char **dup_list (char *const *list)
/*@only@*/ /*@out@*/char **dup_list (char *const *list)
{
int i;
char **tmp;
for (i = 0; list[i]; i++);
assert (NULL != list);
for (i = 0; NULL != list[i]; i++);
tmp = (char **) xmalloc ((i + 1) * sizeof (char *));
i = 0;
while (*list) {
while (NULL != *list) {
tmp[i] = xstrdup (*list);
i++;
list++;
@@ -157,27 +163,34 @@ char **dup_list (char *const *list)
return tmp;
}
int is_on_list (char *const *list, const char *member)
bool is_on_list (char *const *list, const char *member)
{
while (*list) {
assert (NULL != member);
assert (NULL != list);
while (NULL != *list) {
if (strcmp (*list, member) == 0) {
return 1;
return true;
}
list++;
}
return 0;
return false;
}
/*
* comma_to_list - convert comma-separated list to (char *) array
*/
char **comma_to_list (const char *comma)
/*@only@*/char **comma_to_list (const char *comma)
{
char *members;
char **array;
int i;
char *cp, *cp2;
const char *cp;
char *cp2;
assert (NULL != comma);
/*
* Make a copy since we are going to be modifying the list

View File

@@ -49,9 +49,11 @@
* UID is extracted from the global (struct passwd) entry and the
* TTY information is gotten from the (struct utmp).
*/
void
dolastlog (struct lastlog *ll, const struct passwd *pw, const char *line,
const char *host)
void dolastlog (
struct lastlog *ll,
const struct passwd *pw,
/*@unique@*/const char *line,
/*@unique@*/const char *host)
{
int fd;
off_t offset;
@@ -62,18 +64,23 @@ dolastlog (struct lastlog *ll, const struct passwd *pw, const char *line,
* If the file does not exist, don't create it.
*/
if ((fd = open (LASTLOG_FILE, O_RDWR)) == -1)
fd = open (LASTLOG_FILE, O_RDWR);
if (-1 == fd) {
return;
}
/*
* The file is indexed by UID number. Seek to the record
* for this UID. Negative UID's will create problems, but ...
*/
offset = (unsigned long) pw->pw_uid * sizeof newlog;
offset = (off_t) pw->pw_uid * sizeof newlog;
if (lseek (fd, offset, SEEK_SET) != offset) {
close (fd);
SYSLOG ((LOG_WARN,
"Can't read last lastlog entry for UID %lu in %s. Entry not updated.",
(unsigned long) pw->pw_uid, LASTLOG_FILE));
(void) close (fd);
return;
}
@@ -83,19 +90,27 @@ dolastlog (struct lastlog *ll, const struct passwd *pw, const char *line,
* the way we read the old one in.
*/
if (read (fd, (char *) &newlog, sizeof newlog) != sizeof newlog)
if (read (fd, (void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) {
memzero (&newlog, sizeof newlog);
if (ll)
}
if (NULL != ll) {
*ll = newlog;
}
ll_time = newlog.ll_time;
time (&ll_time);
(void) time (&ll_time);
newlog.ll_time = ll_time;
strncpy (newlog.ll_line, line, sizeof newlog.ll_line);
#if HAVE_LL_HOST
strncpy (newlog.ll_host, host, sizeof newlog.ll_host);
#endif
if (lseek (fd, offset, SEEK_SET) == offset)
write (fd, (char *) &newlog, sizeof newlog);
close (fd);
if ( (lseek (fd, offset, SEEK_SET) != offset)
|| (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write lastlog entry for UID %lu in %s.",
(unsigned long) pw->pw_uid, LASTLOG_FILE));
(void) close (fd);
}
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#ident "$Id$"
#include <assert.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
@@ -43,7 +44,7 @@
static void login_exit (unused int sig)
{
exit (1);
exit (EXIT_FAILURE);
}
/*
@@ -86,17 +87,21 @@ void login_prompt (const char *prompt, char *name, int namesize)
* be displayed and display it before the prompt.
*/
if (prompt) {
if (NULL != prompt) {
cp = getdef_str ("ISSUE_FILE");
if (cp && (fp = fopen (cp, "r"))) {
while ((i = getc (fp)) != EOF)
putc (i, stdout);
if (NULL != cp) {
fp = fopen (cp, "r");
if (NULL != fp) {
while ((i = getc (fp)) != EOF) {
(void) putc (i, stdout);
}
fclose (fp);
(void) fclose (fp);
}
}
gethostname (buf, sizeof buf);
printf (prompt, buf);
fflush (stdout);
(void) fflush (stdout);
}
/*
@@ -105,12 +110,14 @@ void login_prompt (const char *prompt, char *name, int namesize)
*/
memzero (buf, sizeof buf);
if (fgets (buf, sizeof buf, stdin) != buf)
exit (1);
if (fgets (buf, (int) sizeof buf, stdin) != buf) {
exit (EXIT_FAILURE);
}
cp = strchr (buf, '\n');
if (!cp)
exit (1);
if (NULL == cp) {
exit (EXIT_FAILURE);
}
*cp = '\0'; /* remove \n [ must be there ] */
/*
@@ -122,11 +129,13 @@ void login_prompt (const char *prompt, char *name, int namesize)
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++);
for (i = 0; i < namesize - 1 && isgraph (*cp); name[i++] = *cp++);
while (isgraph (*cp))
while (isgraph (*cp)) {
cp++;
}
if (*cp)
if ('\0' != *cp) {
cp++;
}
name[i] = '\0';
@@ -136,19 +145,23 @@ void login_prompt (const char *prompt, char *name, int namesize)
* to do this, and I just take the easy way out.
*/
if (*cp != '\0') { /* process new variables */
if ('\0' != *cp) { /* process new variables */
char *nvar;
int count = 1;
for (envc = 0; envc < MAX_ENV; envc++) {
nvar = strtok (envc ? (char *) 0 : cp, " \t,");
if (!nvar)
nvar = strtok ((0 != envc) ? (char *) 0 : cp, " \t,");
if (NULL == nvar) {
break;
if (strchr (nvar, '=')) {
}
if (strchr (nvar, '=') != NULL) {
envp[envc] = nvar;
} else {
envp[envc] = xmalloc (strlen (nvar) + 32);
sprintf (envp[envc], "L%d=%s", count++, nvar);
size_t len = strlen (nvar) + 32;
int wlen;
envp[envc] = xmalloc (len);
wlen = snprintf (envp[envc], len, "L%d=%s", count++, nvar);
assert (wlen == (int) len -1);
}
}
set_env (envc, envp);
@@ -158,8 +171,9 @@ void login_prompt (const char *prompt, char *name, int namesize)
* Set the SIGQUIT handler back to its original value
*/
signal (SIGQUIT, sigquit);
(void) signal (SIGQUIT, sigquit);
#ifdef SIGTSTP
signal (SIGTSTP, sigtstp);
(void) signal (SIGTSTP, sigtstp);
#endif
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1991, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,6 +33,7 @@
#include <config.h>
#include "prototypes.h"
#include "defines.h"
#include <assert.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
@@ -46,34 +48,45 @@ void mailcheck (void)
struct stat statbuf;
char *mailbox;
if (!getdef_bool ("MAIL_CHECK_ENAB"))
if (!getdef_bool ("MAIL_CHECK_ENAB")) {
return;
}
/*
* Check incoming mail in Maildir format - J.
*/
if ((mailbox = getenv ("MAILDIR"))) {
mailbox = getenv ("MAILDIR");
if (NULL != mailbox) {
char *newmail;
size_t len = strlen (mailbox) + 5;
int wlen;
newmail = xmalloc (len);
wlen = snprintf (newmail, len, "%s/new", mailbox);
assert (wlen == (int) len - 1);
newmail = xmalloc (strlen (mailbox) + 5);
sprintf (newmail, "%s/new", mailbox);
if (stat (newmail, &statbuf) != -1 && statbuf.st_size != 0) {
if (statbuf.st_mtime > statbuf.st_atime) {
free (newmail);
puts (_("You have new mail."));
(void) puts (_("You have new mail."));
return;
}
}
free (newmail);
}
if (!(mailbox = getenv ("MAIL")))
mailbox = getenv ("MAIL");
if (NULL == mailbox) {
return;
}
if (stat (mailbox, &statbuf) == -1 || statbuf.st_size == 0)
puts (_("No mail."));
else if (statbuf.st_atime > statbuf.st_mtime)
puts (_("You have mail."));
else
puts (_("You have new mail."));
if ( (stat (mailbox, &statbuf) == -1)
|| (statbuf.st_size == 0)) {
(void) puts (_("No mail."));
} else if (statbuf.st_atime > statbuf.st_mtime) {
(void) puts (_("You have mail."));
} else {
(void) puts (_("You have new mail."));
}
}

View File

@@ -1,7 +1,7 @@
/*
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@
#include "defines.h"
#include <pwd.h>
#include "prototypes.h"
struct passwd *get_my_pwent (void)
/*@null@*/ /*@only@*/struct passwd *get_my_pwent (void)
{
struct passwd *pw;
const char *cp = getlogin ();
@@ -57,8 +57,12 @@ struct passwd *get_my_pwent (void)
* XXX - when running from su, will return the current user (not
* the original user, like getlogin() does). Does this matter?
*/
if (cp && *cp && (pw = xgetpwnam (cp)) && pw->pw_uid == ruid)
return pw;
if ((NULL != cp) && ('\0' != *cp)) {
pw = xgetpwnam (cp);
if ((NULL != pw) && (pw->pw_uid == ruid)) {
return pw;
}
}
return xgetpwuid (ruid);
}

View File

@@ -50,24 +50,26 @@
/*
* can't be a palindrome - like `R A D A R' or `M A D A M'
*/
static int palindrome (unused const char *old, const char *new)
static bool palindrome (unused const char *old, const char *new)
{
int i, j;
size_t i, j;
i = strlen (new);
for (j = 0; j < i; j++)
if (new[i - j - 1] != new[j])
return 0;
for (j = 0; j < i; j++) {
if (new[i - j - 1] != new[j]) {
return false;
}
}
return 1;
return true;
}
/*
* more than half of the characters are different ones.
*/
static int similar (const char *old, const char *new)
static bool similar (const char *old, const char *new)
{
int i, j;
@@ -77,17 +79,21 @@ static int similar (const char *old, const char *new)
* the new password is long enough. Please feel free to suggest
* something better... --marekm
*/
if (strlen (new) >= 8)
return 0;
if (strlen (new) >= 8) {
return false;
}
for (i = j = 0; new[i] && old[i]; i++)
if (strchr (new, old[i]))
for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) {
if (strchr (new, old[i]) != NULL) {
j++;
}
}
if (i >= j * 2)
return 0;
if (i >= j * 2) {
return false;
}
return 1;
return true;
}
/*
@@ -96,22 +102,23 @@ static int similar (const char *old, const char *new)
static int simple (unused const char *old, const char *new)
{
int digits = 0;
int uppers = 0;
int lowers = 0;
int others = 0;
bool digits = false;
bool uppers = false;
bool lowers = false;
bool others = false;
int size;
int i;
for (i = 0; new[i]; i++) {
if (isdigit (new[i]))
digits++;
else if (isupper (new[i]))
uppers++;
else if (islower (new[i]))
lowers++;
else
others++;
for (i = 0; '\0' != new[i]; i++) {
if (isdigit (new[i])) {
digits = true;
} else if (isupper (new[i])) {
uppers = true;
} else if (islower (new[i])) {
lowers = true;
} else {
others = true;
}
}
/*
@@ -120,27 +127,33 @@ static int simple (unused const char *old, const char *new)
*/
size = 9;
if (digits)
if (digits) {
size--;
if (uppers)
}
if (uppers) {
size--;
if (lowers)
}
if (lowers) {
size--;
if (others)
}
if (others) {
size--;
}
if (size <= i)
return 0;
if (size <= i) {
return false;
}
return 1;
return true;
}
static char *str_lower (char *string)
{
char *cp;
for (cp = string; *cp; cp++)
for (cp = string; '\0' != *cp; cp++) {
*cp = tolower (*cp);
}
return string;
}
@@ -160,8 +173,9 @@ static const char *password_check (const char *old, const char *new,
#endif
#endif
if (strcmp (new, old) == 0)
if (strcmp (new, old) == 0) {
return _("no change");
}
newmono = str_lower (xstrdup (new));
oldmono = str_lower (xstrdup (old));
@@ -169,33 +183,32 @@ static const char *password_check (const char *old, const char *new,
strcpy (wrapped, oldmono);
strcat (wrapped, oldmono);
if (palindrome (oldmono, newmono))
if (palindrome (oldmono, newmono)) {
msg = _("a palindrome");
if (!msg && strcmp (oldmono, newmono) == 0)
} else if (strcmp (oldmono, newmono) == 0) {
msg = _("case changes only");
if (!msg && similar (oldmono, newmono))
} else if (similar (oldmono, newmono)) {
msg = _("too similar");
if (!msg && simple (old, new))
} else if (simple (old, new)) {
msg = _("too simple");
if (!msg && strstr (wrapped, newmono))
} else if (strstr (wrapped, newmono) != NULL) {
msg = _("rotated");
} else {
#ifdef HAVE_LIBCRACK
/*
* Invoke Alec Muffett's cracklib routines.
*/
/*
* Invoke Alec Muffett's cracklib routines.
*/
if (!msg && (dictpath = getdef_str ("CRACKLIB_DICTPATH")))
dictpath = getdef_str ("CRACKLIB_DICTPATH");
if (NULL != dictpath) {
#ifdef HAVE_LIBCRACK_PW
msg = FascistCheckPw (new, dictpath, pwdp);
msg = FascistCheckPw (new, dictpath, pwdp);
#else
msg = FascistCheck (new, dictpath);
msg = FascistCheck (new, dictpath);
#endif
}
#endif
}
strzero (newmono);
strzero (oldmono);
strzero (wrapped);
@@ -206,11 +219,11 @@ static const char *password_check (const char *old, const char *new,
return msg;
}
/*ARGSUSED*/
static const char *obscure_msg (const char *old, const char *new,
/*ARGSUSED*/
static const char *obscure_msg (const char *old, const char *new,
const struct passwd *pwdp)
{
int maxlen, oldlen, newlen;
size_t maxlen, oldlen, newlen;
char *new1, *old1;
const char *msg;
char *result;
@@ -218,50 +231,60 @@ static const char *password_check (const char *old, const char *new,
oldlen = strlen (old);
newlen = strlen (new);
if (newlen < getdef_num ("PASS_MIN_LEN", 0))
if (newlen < (size_t) getdef_num ("PASS_MIN_LEN", 0)) {
return _("too short");
}
/*
* Remaining checks are optional.
*/
if (!getdef_bool ("OBSCURE_CHECKS_ENAB"))
if (!getdef_bool ("OBSCURE_CHECKS_ENAB")) {
return NULL;
}
msg = password_check (old, new, pwdp);
if (msg)
if (NULL != msg) {
return msg;
}
if ((result = getdef_str ("ENCRYPT_METHOD")) == NULL) {
result = getdef_str ("ENCRYPT_METHOD");
if (NULL == result) {
/* The traditional crypt() truncates passwords to 8 chars. It is
possible to circumvent the above checks by choosing an easy
8-char password and adding some random characters to it...
Example: "password$%^&*123". So check it again, this time
truncated to the maximum length. Idea from npasswd. --marekm */
if (getdef_bool ("MD5_CRYPT_ENAB"))
if (getdef_bool ("MD5_CRYPT_ENAB")) {
return NULL;
}
} else {
if ( !strcmp (result, "MD5")
if ( (strcmp (result, "MD5") == 0)
#ifdef USE_SHA_CRYPT
|| !strcmp (result, "SHA256")
|| !strcmp (result, "SHA512")
|| (strcmp (result, "SHA256") == 0)
|| (strcmp (result, "SHA512") == 0)
#endif
)
) {
return NULL;
}
}
maxlen = getdef_num ("PASS_MAX_LEN", 8);
if (oldlen <= maxlen && newlen <= maxlen)
maxlen = (size_t) getdef_num ("PASS_MAX_LEN", 8);
if ( (oldlen <= maxlen)
&& (newlen <= maxlen)) {
return NULL;
}
new1 = xstrdup (new);
old1 = xstrdup (old);
if (newlen > maxlen)
if (newlen > maxlen) {
new1[maxlen] = '\0';
if (oldlen > maxlen)
}
if (oldlen > maxlen) {
old1[maxlen] = '\0';
}
msg = password_check (old1, new1, pwdp);
@@ -285,7 +308,7 @@ int obscure (const char *old, const char *new, const struct passwd *pwdp)
{
const char *msg = obscure_msg (old, new, pwdp);
if (msg) {
if (NULL != msg) {
printf (_("Bad password: %s. "), msg);
return 0;
}

View File

@@ -37,10 +37,7 @@
/*
* Change the user's password using PAM. Requires libpam and libpam_misc
* (for misc_conv). Note: libpam_misc is probably Linux-PAM specific,
* so you may have to port it if you want to use this code on non-Linux
* systems with PAM (such as Solaris 2.6). --marekm
* Change the user's password using PAM.
*/
#include <stdio.h>
#include <stdlib.h>
@@ -50,7 +47,7 @@
#include "pam_defs.h"
#include "prototypes.h"
void do_pam_passwd (const char *user, int silent, int change_expired)
void do_pam_passwd (const char *user, bool silent, bool change_expired)
{
pam_handle_t *pamh = NULL;
int flags = 0, ret;
@@ -76,7 +73,7 @@ void do_pam_passwd (const char *user, int silent, int change_expired)
}
fputs (_("passwd: password updated successfully\n"), stderr);
pam_end (pamh, PAM_SUCCESS);
(void) pam_end (pamh, PAM_SUCCESS);
}
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */

View File

@@ -0,0 +1,167 @@
/*
* Copyright (c) 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id:$"
#ifdef USE_PAM
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <security/pam_appl.h>
#include "prototypes.h"
/*@null@*/ /*@only@*/static char *non_interactive_password = NULL;
static int ni_conv (int num_msg,
const struct pam_message **msg,
struct pam_response **resp,
unused void *appdata_ptr);
static struct pam_conv non_interactive_pam_conv = {
ni_conv,
NULL
};
static int ni_conv (int num_msg,
const struct pam_message **msg,
struct pam_response **resp,
unused void *appdata_ptr)
{
struct pam_response *responses;
int count;
assert (NULL != non_interactive_password);
if (num_msg <= 0) {
return PAM_CONV_ERR;
}
responses = (struct pam_response *) calloc ((size_t) num_msg,
sizeof (*responses));
if (NULL == responses) {
return PAM_CONV_ERR;
}
for (count=0; count < num_msg; count++) {
responses[count].resp_retcode = 0;
switch (msg[count]->msg_style) {
case PAM_PROMPT_ECHO_ON:
fprintf (stderr,
_("%s: PAM modules requesting echoing are not supported.\n"),
Prog);
goto failed_conversation;
case PAM_PROMPT_ECHO_OFF:
responses[count].resp = strdup (non_interactive_password);
if (NULL == responses[count].resp) {
goto failed_conversation;
}
break;
case PAM_ERROR_MSG:
if ( (NULL == msg[count]->msg)
|| (fprintf (stderr, "%s\n", msg[count]->msg) <0)) {
goto failed_conversation;
}
responses[count].resp = NULL;
break;
case PAM_TEXT_INFO:
if ( (NULL == msg[count]->msg)
|| (fprintf (stdout, "%s\n", msg[count]->msg) <0)) {
goto failed_conversation;
}
responses[count].resp = NULL;
break;
default:
(void) fprintf (stderr,
_("%s: conversation type %d not supported.\n"),
Prog, msg[count]->msg_style);
goto failed_conversation;
}
}
*resp = responses;
return PAM_SUCCESS;
failed_conversation:
for (count=0; count < num_msg; count++) {
if (NULL != responses[count].resp) {
memset (responses[count].resp, 0,
strlen (responses[count].resp));
free (responses[count].resp);
responses[count].resp = NULL;
}
}
free (responses);
*resp = NULL;
return PAM_CONV_ERR;
}
/*
* Change non interactively the user's password using PAM.
*
* Return 0 on success, 1 on failure.
*/
int do_pam_passwd_non_interractive (const char *pam_service,
const char *username,
const char* password)
{
pam_handle_t *pamh = NULL;
int ret;
ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh);
if (ret != PAM_SUCCESS) {
fprintf (stderr,
_("%s: (user %s) pam_start failure %d\n"),
Prog, username, ret);
return 1;
}
non_interactive_password = password;
ret = pam_chauthtok (pamh, 0);
if (ret != PAM_SUCCESS) {
fprintf (stderr,
_("%s: (user %s) pam_chauthtok() failed, error:\n"
"%s\n"),
Prog, username, pam_strerror (pamh, ret));
}
(void) pam_end (pamh, PAM_SUCCESS);
return ((PAM_SUCCESS == ret) ? 0 : 1);
}
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,8 @@
#ident "$Id$"
#ifndef USE_PAM
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
@@ -64,7 +66,12 @@ struct spwd *pwd_to_spwd (const struct passwd *pw)
*/
sp.sp_min = 0;
sp.sp_max = (10000L * DAY) / SCALE;
sp.sp_lstchg = time ((time_t *) 0) / SCALE;
sp.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
if (0 == sp.sp_lstchg) {
/* Better disable aging than requiring a password
* change */
sp.sp_lstchg = -1;
}
}
/*
@@ -74,7 +81,11 @@ struct spwd *pwd_to_spwd (const struct passwd *pw)
sp.sp_warn = -1;
sp.sp_expire = -1;
sp.sp_inact = -1;
sp.sp_flag = -1;
sp.sp_flag = SHADOW_SP_FLAG_UNSET;
return &sp;
}
#else /* USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */

View File

@@ -40,7 +40,7 @@
#include "defines.h"
#include "pwauth.h"
void passwd_check (const char *user, const char *passwd, const char *progname)
void passwd_check (const char *user, const char *passwd, unused const char *progname)
{
struct spwd *sp;
@@ -50,9 +50,9 @@ void passwd_check (const char *user, const char *passwd, const char *progname)
}
if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) {
SYSLOG ((LOG_WARN, "incorrect password for `%s'", user));
sleep (1);
(void) sleep (1);
fprintf (stderr, _("Incorrect password for %s.\n"), user);
exit (1);
exit (EXIT_FAILURE);
}
}
#else /* USE_PAM */

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2008, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,26 +110,30 @@ static struct {
-1, -1}
};
static void get_remote_string (char *buf, int size)
static void get_remote_string (char *buf, size_t size)
{
for (;;) {
if (read (0, buf, 1) != 1)
exit (1);
if (*buf == '\0')
if (read (0, buf, 1) != 1) {
exit (EXIT_FAILURE);
}
if ('\0' == *buf) {
return;
if (--size > 0)
}
--size;
if (size > 0) {
++buf;
}
}
/*NOTREACHED*/}
int
do_rlogin (const char *remote_host, char *name, int namelen, char *term,
int termlen)
do_rlogin (const char *remote_host, char *name, size_t namelen, char *term,
size_t termlen)
{
struct passwd *pwd;
char remote_name[32];
char *cp;
int remote_speed = 9600;
unsigned long remote_speed = 9600;
int speed_name = B9600;
int i;
TERMIO termio;
@@ -138,17 +142,23 @@ do_rlogin (const char *remote_host, char *name, int namelen, char *term,
get_remote_string (name, namelen);
get_remote_string (term, termlen);
if ((cp = strchr (term, '/'))) {
*cp++ = '\0';
cp = strchr (term, '/');
if (NULL != cp) {
*cp = '\0';
cp++;
if (!(remote_speed = atoi (cp)))
if (getulong (cp, &remote_speed) == 0) {
remote_speed = 9600;
}
}
for (i = 0; speed_table[i].spd_baud != remote_speed &&
speed_table[i].spd_name != -1; i++);
for (i = 0;
( (speed_table[i].spd_baud != remote_speed)
&& (speed_table[i].spd_name != -1));
i++);
if (speed_table[i].spd_name != -1)
if (-1 != speed_table[i].spd_name) {
speed_name = speed_table[i].spd_name;
}
/*
* Put the terminal in cooked mode with echo turned on.
@@ -165,8 +175,10 @@ do_rlogin (const char *remote_host, char *name, int namelen, char *term,
#endif
STTY (0, &termio);
if (!(pwd = getpwnam (name))) /* local, no need for xgetpwnam */
pwd = getpwnam (name); /* local, no need for xgetpwnam */
if (NULL == pwd) {
return 0;
}
/*
* ruserok() returns 0 for success on modern systems, and 1 on

View File

@@ -20,18 +20,15 @@
#include "getdef.h"
/* local function prototypes */
#ifndef HAVE_L64A
char *l64a(long value);
#endif /* !HAVE_L64A */
static void seedRNG (void);
static char *gensalt (unsigned int salt_size);
static /*@observer@*/const char *gensalt (size_t salt_size);
#ifdef USE_SHA_CRYPT
static unsigned int SHA_salt_size (void);
static const char *SHA_salt_rounds (int *prefered_rounds);
static size_t SHA_salt_size (void);
static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds);
#endif /* USE_SHA_CRYPT */
#ifndef HAVE_L64A
static char *l64a(long value)
static /*@observer@*/char *l64a(long value)
{
static char buf[8];
char *s = buf;
@@ -46,14 +43,15 @@ static char *l64a(long value)
for (i = 0; value != 0 && i < 6; i++) {
digit = value & 0x3f;
if (digit < 2)
if (digit < 2) {
*s = digit + '.';
else if (digit < 12)
} else if (digit < 12) {
*s = digit + '0' - 2;
else if (digit < 38)
} else if (digit < 38) {
*s = digit + 'A' - 12;
else
} else {
*s = digit + 'a' - 38;
}
value >>= 6;
s++;
@@ -71,8 +69,8 @@ static void seedRNG (void)
static int seeded = 0;
if (0 == seeded) {
gettimeofday(&tv, NULL);
srandom (tv.tv_sec + tv.tv_usec);
(void) gettimeofday (&tv, NULL);
srandom (tv.tv_sec ^ tv.tv_usec ^ getpid ());
seeded = 1;
}
}
@@ -88,18 +86,14 @@ static void seedRNG (void)
* The size of the salt string is between 8 and 16 bytes for the SHA crypt
* methods.
*/
static unsigned int SHA_salt_size (void)
static size_t SHA_salt_size (void)
{
double rand_size;
seedRNG ();
rand_size = (double) 9.0 * random () / RAND_MAX;
return 8 + rand_size;
return (size_t) (8 + rand_size);
}
/* ! Arguments evaluated twice ! */
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define MIN(x,y) ((x) < (y) ? (x) : (y))
/* Default number of rounds if not explicitly specified. */
#define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
@@ -110,7 +104,7 @@ static unsigned int SHA_salt_size (void)
/*
* Return a salt prefix specifying the rounds number for the SHA crypt methods.
*/
static const char *SHA_salt_rounds (int *prefered_rounds)
static /*@observer@*/const char *SHA_salt_rounds (/*@null@*/int *prefered_rounds)
{
static char rounds_prefix[18];
long rounds;
@@ -120,41 +114,49 @@ static const char *SHA_salt_rounds (int *prefered_rounds)
long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1);
double rand_rounds;
if (-1 == min_rounds && -1 == max_rounds)
if ((-1 == min_rounds) && (-1 == max_rounds)) {
return "";
}
if (-1 == min_rounds)
if (-1 == min_rounds) {
min_rounds = max_rounds;
}
if (-1 == max_rounds)
if (-1 == max_rounds) {
max_rounds = min_rounds;
}
if (min_rounds > max_rounds)
if (min_rounds > max_rounds) {
max_rounds = min_rounds;
}
seedRNG ();
rand_rounds = (double) (max_rounds-min_rounds+1.0) * random ();
rand_rounds /= RAND_MAX;
rounds = min_rounds + rand_rounds;
} else if (0 == *prefered_rounds)
} else if (0 == *prefered_rounds) {
return "";
else
} else {
rounds = *prefered_rounds;
}
/* Sanity checks. The libc should also check this, but this
* protects against a rounds_prefix overflow. */
if (rounds < ROUNDS_MIN)
if (rounds < ROUNDS_MIN) {
rounds = ROUNDS_MIN;
}
if (rounds > ROUNDS_MAX)
if (rounds > ROUNDS_MAX) {
rounds = ROUNDS_MAX;
}
snprintf (rounds_prefix, 18, "rounds=%ld$", rounds);
/* Sanity checks. That should not be necessary. */
rounds_prefix[17] = '\0';
if ('$' != rounds_prefix[16])
if ('$' != rounds_prefix[16]) {
rounds_prefix[17] = '$';
}
return rounds_prefix;
}
@@ -166,7 +168,7 @@ static const char *SHA_salt_rounds (int *prefered_rounds)
#define MAX_SALT_SIZE 16
#define MIN_SALT_SIZE 8
static char *gensalt (unsigned int salt_size)
static /*@observer@*/const char *gensalt (size_t salt_size)
{
static char salt[32];
@@ -179,6 +181,7 @@ static char *gensalt (unsigned int salt_size)
do {
strcat (salt, l64a (random()));
} while (strlen (salt) < salt_size);
salt[salt_size] = '\0';
return salt;
@@ -199,7 +202,7 @@ static char *gensalt (unsigned int salt_size)
* * For the SHA256 and SHA512 method, this specifies the number of rounds
* (if not NULL).
*/
char *crypt_make_salt (const char *meth, void *arg)
/*@observer@*/const char *crypt_make_salt (/*@null@*/const char *meth, /*@null@*/void *arg)
{
/* Max result size for the SHA methods:
* +3 $5$
@@ -216,8 +219,10 @@ char *crypt_make_salt (const char *meth, void *arg)
if (NULL != meth)
method = meth;
else {
if ((method = getdef_str ("ENCRYPT_METHOD")) == NULL)
method = getdef_bool ("MD5_CRYPT_ENAB") ? "MD5" : "DES";
method = getdef_str ("ENCRYPT_METHOD");
if (NULL == method) {
method = getdef_bool ("MD5_CRYPT_ENAB") ? "MD5" : "DES";
}
}
if (0 == strcmp (method, "MD5")) {

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -39,14 +40,21 @@
#include <stdio.h>
#include <grp.h>
#include <errno.h>
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include "getdef.h"
/*
* setup_uid_gid() split in two functions for PAM support -
* pam_setcred() needs to be called after initgroups(), but
* before setuid().
* setup_groups - set the group credentials
* set the group ID to the value from the password file entry
* set the supplementary group IDs
*
* In case of PAM enabled configurations, this shall be called before
* pam_setcred.
*
* Returns 0 on success, or -1 on failure.
*/
int setup_groups (const struct passwd *info)
{
@@ -55,9 +63,10 @@ int setup_groups (const struct passwd *info)
* file.
*/
if (setgid (info->pw_gid) == -1) {
int err = errno;
perror ("setgid");
SYSLOG ((LOG_ERR, "bad group ID `%d' for user `%s': %m\n",
info->pw_gid, info->pw_name));
SYSLOG ((LOG_ERR, "bad group ID `%d' for user `%s': %s\n",
info->pw_gid, info->pw_name, strerror (err)));
closelog ();
return -1;
}
@@ -67,9 +76,10 @@ int setup_groups (const struct passwd *info)
* the group set from the /etc/group file.
*/
if (initgroups (info->pw_name, info->pw_gid) == -1) {
int err = errno;
perror ("initgroups");
SYSLOG ((LOG_ERR, "initgroups failed for user `%s': %m\n",
info->pw_name));
SYSLOG ((LOG_ERR, "initgroups failed for user `%s': %s\n",
info->pw_name, strerror (err)));
closelog ();
return -1;
}
@@ -77,15 +87,21 @@ int setup_groups (const struct passwd *info)
return 0;
}
/*
* change_uid - Set the real UID
*
* Returns 0 on success, or -1 on failure.
*/
int change_uid (const struct passwd *info)
{
/*
* Set the real UID to the UID value in the password file.
*/
if (setuid (info->pw_uid)) {
if (setuid (info->pw_uid) != 0) {
int err = errno;
perror ("setuid");
SYSLOG ((LOG_ERR, "bad user ID `%d' for user `%s': %m\n",
(int) info->pw_uid, info->pw_name));
SYSLOG ((LOG_ERR, "bad user ID `%d' for user `%s': %s\n",
(int) info->pw_uid, info->pw_name, strerror (err)));
closelog ();
return -1;
}
@@ -103,22 +119,30 @@ int change_uid (const struct passwd *info)
* Returns 0 on success, or -1 on failure.
*/
int setup_uid_gid (const struct passwd *info, int is_console)
#if defined (HAVE_INITGROUPS) && ! (defined USE_PAM)
int setup_uid_gid (const struct passwd *info, bool is_console)
#else
int setup_uid_gid (const struct passwd *info)
#endif
{
if (setup_groups (info) < 0)
if (setup_groups (info) < 0) {
return -1;
}
#ifdef HAVE_INITGROUPS
#if defined (HAVE_INITGROUPS) && ! defined (USE_PAM)
if (is_console) {
char *cp = getdef_str ("CONSOLE_GROUPS");
if (cp && add_groups (cp))
if ((NULL != cp) && (add_groups (cp) != 0)) {
perror ("Warning: add_groups");
}
}
#endif /* HAVE_INITGROUPS */
#endif /* HAVE_INITGROUPS && !USE_PAM*/
if (change_uid (info) < 0)
if (change_uid (info) < 0) {
return -1;
}
return 0;
}

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
#ident "$Id$"
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
@@ -52,9 +53,13 @@ static void
addenv_path (const char *varname, const char *dirname, const char *filename)
{
char *buf;
size_t len = strlen (dirname) + strlen (filename) + 2;
int wlen;
buf = xmalloc (len);
wlen = snprintf (buf, len, "%s/%s", dirname, filename);
assert (wlen == (int) len - 1);
buf = xmalloc (strlen (dirname) + strlen (filename) + 2);
sprintf (buf, "%s/%s", dirname, filename);
addenv (varname, buf);
free (buf);
}
@@ -66,31 +71,38 @@ static void read_env_file (const char *filename)
char *cp, *name, *val;
fp = fopen (filename, "r");
if (!fp)
if (NULL == fp) {
return;
}
while (fgets (buf, sizeof buf, fp) == buf) {
cp = strrchr (buf, '\n');
if (!cp)
if (NULL == cp) {
break;
}
*cp = '\0';
cp = buf;
/* ignore whitespace and comments */
while (*cp && isspace (*cp))
while (('\0' != *cp) && isspace (*cp)) {
cp++;
if (*cp == '\0' || *cp == '#')
}
if (('\0' == *cp) || ('#' == *cp)) {
continue;
}
/*
* ignore lines which don't follow the name=value format
* (for example, the "export NAME" shell commands)
*/
name = cp;
while (*cp && !isspace (*cp) && *cp != '=')
while (('\0' != *cp) && !isspace (*cp) && ('=' != *cp)) {
cp++;
if (*cp != '=')
}
if ('=' != *cp) {
continue;
}
/* NUL-terminate the name */
*cp++ = '\0';
*cp = '\0';
cp++;
val = cp;
#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
/*
@@ -174,7 +186,7 @@ static void read_env_file (const char *filename)
*/
addenv (name, val);
}
fclose (fp);
(void) fclose (fp);
}
#endif /* USE_PAM */
@@ -213,9 +225,9 @@ void setup_env (struct passwd *info)
"unable to cd to `%s' for user `%s'\n",
info->pw_dir, info->pw_name));
closelog ();
exit (1);
exit (EXIT_FAILURE);
}
puts (_("No directory, logging in with HOME=/"));
(void) puts (_("No directory, logging in with HOME=/"));
info->pw_dir = temp_pw_dir;
}
@@ -229,8 +241,8 @@ void setup_env (struct passwd *info)
* Create the SHELL environmental variable and export it.
*/
if (info->pw_shell == (char *) 0 || !*info->pw_shell) {
static char temp_pw_shell[] = "/bin/sh";
if ((NULL == info->pw_shell) || ('\0' == *info->pw_shell)) {
static char temp_pw_shell[] = SHELL;
info->pw_shell = temp_pw_shell;
}
@@ -251,7 +263,7 @@ void setup_env (struct passwd *info)
cp = getdef_str ((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
if (!cp) {
if (NULL == cp) {
/* not specified, use a minimal default */
addenv ("PATH=/bin:/usr/bin", NULL);
} else if (strchr (cp, '=')) {
@@ -269,23 +281,30 @@ void setup_env (struct passwd *info)
*/
if (getdef_bool ("MAIL_CHECK_ENAB")) {
if ((cp = getdef_str ("MAIL_DIR")))
cp = getdef_str ("MAIL_DIR");
if (NULL != cp) {
addenv_path ("MAIL", cp, info->pw_name);
else if ((cp = getdef_str ("MAIL_FILE")))
addenv_path ("MAIL", info->pw_dir, cp);
else {
} else {
cp = getdef_str ("MAIL_FILE");
if (NULL != cp) {
addenv_path ("MAIL", info->pw_dir, cp);
} else {
#if defined(MAIL_SPOOL_FILE)
addenv_path ("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
addenv_path ("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
#elif defined(MAIL_SPOOL_DIR)
addenv_path ("MAIL", MAIL_SPOOL_DIR, info->pw_name);
addenv_path ("MAIL", MAIL_SPOOL_DIR, info->pw_name);
#endif
}
}
}
/*
* Read environment from optional config file. --marekm
*/
if ((envf = getdef_str ("ENVIRON_FILE")))
envf = getdef_str ("ENVIRON_FILE");
if (NULL != envf) {
read_env_file (envf);
}
#endif /* !USE_PAM */
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1991, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,14 +47,11 @@ extern size_t newenvc;
* shell begins by trying to figure out what argv[0] is going to
* be for the named process. The user may pass in that argument,
* or it will be the last pathname component of the file with a
* '-' prepended. The first attempt is to just execute the named
* file. If the errno comes back "ENOEXEC", the file is assumed
* at first glance to be a shell script. The first two characters
* must be "#!", in which case "/bin/sh" is executed to process
* the file. If all that fails, give up in disgust ...
* '-' prepended.
* Then, it executes the named file.
*/
int shell (const char *file, const char *arg, char *const envp[])
int shell (const char *file, /*@null@*/const char *arg, char *const envp[])
{
char arg0[1024];
int err;
@@ -82,30 +80,14 @@ int shell (const char *file, const char *arg, char *const envp[])
execle (file, arg, (char *) 0, envp);
err = errno;
/* Linux handles #! in the kernel, and bash doesn't make
sense of "#!" so it wouldn't work anyway... --marekm */
#ifndef __linux__
/*
* It is perfectly OK to have a shell script for a login
* shell, and this code attempts to support that. It
* relies on the standard shell being able to make sense
* of the "#!" magic number.
*/
if (err == ENOEXEC) {
FILE *fp;
if ((fp = fopen (file, "r"))) {
if (getc (fp) == '#' && getc (fp) == '!') {
fclose (fp);
execle ("/bin/sh", "sh",
file, (char *) 0, envp);
err = errno;
} else {
fclose (fp);
}
}
if (access (file, R_OK|X_OK) == 0) {
/*
* Assume this is a shell script (with no shebang).
* Interpret it with /bin/sh
*/
execle (SHELL, "sh", "-", file, (char *)0, envp);
err = errno;
}
#endif
/*
* Obviously something is really wrong - I can't figure out
@@ -117,3 +99,4 @@ int shell (const char *file, const char *arg, char *const envp[])
perror (arg0);
return err;
}

View File

@@ -69,14 +69,16 @@ long strtoday (const char *str)
* which is not what we expect, unless you're a BOFH :-).
* (useradd sets sp_expire = current date for new lusers)
*/
if (!str || *str == '\0')
if ((NULL == str) || ('\0' == *str)) {
return -1;
}
t = get_date (str, (time_t *) 0);
if (t == (time_t) - 1)
if ((time_t) - 1 == t) {
return -1;
}
/* convert seconds to days since 1970-01-01 */
return (t + DAY / 2) / DAY;
return (long) (t + DAY / 2) / DAY;
}
#else /* !USE_GETDATE */
@@ -129,14 +131,16 @@ long strtoday (const char *str)
memzero (&tp, sizeof tp);
for (fmt = date_formats; *fmt; fmt++) {
cp = strptime ((char *) str, *fmt, &tp);
if (!cp || *cp != '\0')
if ((NULL == cp) || ('\0' != *cp)) {
continue;
}
result = mktime (&tp);
if (result == (time_t) - 1)
if ((time_t) - 1 == result) {
continue;
}
return result / DAY; /* success */
return (long) (result / DAY); /* success */
}
return -1;
#else
@@ -151,8 +155,9 @@ long strtoday (const char *str)
* is compiled in ...
*/
if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3)
if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3) {
return -1;
}
/*
* the month, day of the month, and year are checked for
@@ -160,23 +165,28 @@ long strtoday (const char *str)
* 1970 and 2069.
*/
if (month < 1 || month > 12)
if ((month < 1) || (month > 12)) {
return -1;
}
if (day < 1)
if (day < 1) {
return -1;
}
if ((month != 2 || (year % 4) != 0) && day > days[month])
if ( ((2 != month) || ((year % 4) != 0))
&& (day > days[month])) {
return -1;
else if ((month == 2 && (year % 4) == 0) && day > 29)
} else if ((month == 2) && ((year % 4) == 0) && (day > 29)) {
return -1;
}
if (year < 0)
if (year < 0) {
return -1;
else if (year <= 69)
} else if (year <= 69) {
year += 2000;
else if (year <= 99)
} else if (year <= 99) {
year += 1900;
}
/*
* On systems with 32-bit signed time_t, time wraps around in 2038
@@ -184,8 +194,9 @@ long strtoday (const char *str)
* This limit can be removed once no one is using 32-bit systems
* anymore :-). --marekm
*/
if (year < 1970 || year > 2037)
if ((year < 1970) || (year > 2037)) {
return -1;
}
/*
* the total number of days is the total number of days in all

View File

@@ -58,7 +58,7 @@ void subsystem (const struct passwd *pw)
printf (_("Invalid root directory '%s'\n"), pw->pw_dir);
SYSLOG ((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
closelog ();
exit (1);
exit (EXIT_FAILURE);
}
/*
@@ -71,6 +71,6 @@ void subsystem (const struct passwd *pw)
pw->pw_dir);
SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
closelog ();
exit (1);
exit (EXIT_FAILURE);
}
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1992, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,10 +41,11 @@
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
/*
* sulog - log a SU command execution result
*/
void sulog (const char *tty, int success, const char *oldname, const char *name)
void sulog (const char *tty, bool success, const char *oldname, const char *name)
{
char *sulog_file;
time_t now;
@@ -74,25 +76,29 @@ void sulog (const char *tty, int success, const char *oldname, const char *name)
oldgid = 0;
}
fp = fopen (sulog_file, "a+");
umask (oldmask);
(void) umask (oldmask);
if ((oldgid != 0) && (setgid (oldgid) != 0)) {
perror ("setgid");
SYSLOG ((LOG_ERR,
"can't switch back to group `%d' in sulog",
oldgid));
/* Do not return if the group permission were raised. */
exit (1);
exit (EXIT_FAILURE);
}
if (fp == (FILE *) 0)
if (fp == (FILE *) 0) {
return; /* can't open or create logfile */
}
time (&now);
(void) time (&now);
tm = localtime (&now);
fprintf (fp, "SU %.02d/%.02d %.02d:%.02d %c %s %s-%s\n",
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
success ? '+' : '-', tty, oldname, name);
fflush (fp);
(void) fflush (fp);
fsync (fileno (fp));
fclose (fp);
/* TODO: log if failure */
}

72
libmisc/system.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2009 , Dan Walsh <dwalsh@redhat.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdio.h>
#include <sys/wait.h>
#include <fcntl.h>
#include "prototypes.h"
#include "defines.h"
int safe_system (const char *command,
const char *argv[],
const char *env[],
int ignore_stderr)
{
int status = -1;
int fd;
pid_t pid;
pid = fork();
if (pid < 0) {
return -1;
}
if (pid) { /* Parent */
if (waitpid (pid, &status, 0) > 0) {
return status;
} else {
return -1;
}
}
fd = open ("/dev/null", O_RDWR);
/* Child */
dup2 (fd, 0); // Close Stdin
if (ignore_stderr) {
dup2 (fd, 2); // Close Stderr
}
execve (command, (char *const *) argv, (char *const *) env);
fprintf (stderr, _("Failed to exec '%s'\n"), argv[0]);
exit (EXIT_FAILURE);
}

View File

@@ -2,6 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,30 +50,41 @@ void ttytype (const char *line)
char type[BUFSIZ];
char port[BUFSIZ];
if (getenv ("TERM"))
if (getenv ("TERM") != NULL) {
return;
if ((typefile = getdef_str ("TTYTYPE_FILE")) == NULL)
}
typefile = getdef_str ("TTYTYPE_FILE");
if (NULL == typefile) {
return;
if (access (typefile, F_OK))
}
if (access (typefile, F_OK) != 0) {
return;
}
if (!(fp = fopen (typefile, "r"))) {
fp = fopen (typefile, "r");
if (NULL == fp) {
perror (typefile);
return;
}
while (fgets (buf, sizeof buf, fp)) {
if (buf[0] == '#')
while (fgets (buf, (int) sizeof buf, fp) == buf) {
if (buf[0] == '#') {
continue;
}
if ((cp = strchr (buf, '\n')))
cp = strchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
if (sscanf (buf, "%s %s", type, port) == 2 &&
strcmp (line, port) == 0)
if ((sscanf (buf, "%s %s", type, port) == 2) &&
(strcmp (line, port) == 0)) {
break;
}
}
if (!feof (fp) && !ferror (fp))
if ((feof (fp) == 0) && (ferror (fp) == 0)) {
addenv ("TERM", type);
}
fclose (fp);
(void) fclose (fp);
}

View File

@@ -33,6 +33,8 @@
#include <config.h>
#ifndef USE_PAM
#ident "$Id$"
#include <stdio.h>
@@ -40,6 +42,7 @@
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
/*
* tz - return local timezone name
*
@@ -53,11 +56,9 @@ char *tz (const char *fname)
const char *def_tz = "TZ=CST6CDT";
if ((fp = fopen (fname, "r")) == NULL ||
fgets (tzbuf, sizeof (tzbuf), fp) == NULL) {
#ifndef USE_PAM
fgets (tzbuf, (int) sizeof (tzbuf), fp) == NULL) {
if (!(def_tz = getdef_str ("ENV_TZ")) || def_tz[0] == '/')
def_tz = "TZ=CST6CDT";
#endif /* !USE_PAM */
strcpy (tzbuf, def_tz);
} else
@@ -68,3 +69,7 @@ char *tz (const char *fname)
return tzbuf;
}
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */

View File

@@ -50,14 +50,21 @@
#endif
#include "prototypes.h"
void set_filesize_limit (int blocks)
int set_filesize_limit (int blocks)
{
int ret = -1;
#if HAVE_ULIMIT_H
ulimit (UL_SETFSIZE, blocks);
if (ulimit (UL_SETFSIZE, blocks) != -1) {
ret = 0;
}
#elif defined(RLIMIT_FSIZE)
struct rlimit rlimit_fsize;
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
rlimit_fsize.rlim_cur = 512L * blocks;
rlimit_fsize.rlim_max = rlimit_fsize.rlim_cur;
ret = setrlimit (RLIMIT_FSIZE, &rlimit_fsize);
#endif
return ret;
}

228
libmisc/user_busy.c Normal file
View File

@@ -0,0 +1,228 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2000 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: $"
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include "defines.h"
#include "prototypes.h"
#ifdef __linux__
static int check_status (const char *sname, uid_t uid);
static int user_busy_processes (uid_t uid);
#else /* !__linux__ */
static int user_busy_utmp (const char *name);
#endif /* !__linux__ */
/*
* user_busy - check if an user if currently running processes
*/
int user_busy (const char *name, uid_t uid)
{
/* There are no standard ways to get the list of processes.
* An option could be to run an external tool (ps).
*/
#ifdef __linux__
/* On Linux, directly parse /proc */
return user_busy_processes (uid);
#else /* !__linux__ */
/* If we cannot rely on /proc, check is there is a record in utmp
* indicating that the user is still logged in */
return user_busy_utmp (name);
#endif /* !__linux__ */
}
#ifndef __linux__
static int user_busy_utmp (const char *name)
{
#ifdef USE_UTMPX
struct utmpx *utent;
setutxent ();
while ((utent = getutxent ()) != NULL)
#else /* !USE_UTMPX */
struct utmp *utent;
setutent ();
while ((utent = getutent ()) != NULL)
#endif /* !USE_UTMPX */
{
if (utent->ut_type != USER_PROCESS) {
continue;
}
if (strncmp (utent->ut_user, name, sizeof utent->ut_user) != 0) {
continue;
}
if (kill (utent->ut_pid, 0) != 0) {
continue;
}
return 1;
}
return 0;
}
#endif /* !__linux__ */
#ifdef __linux__
static int check_status (const char *sname, uid_t uid)
{
/* 40: /proc/xxxxxxxxxx/task/xxxxxxxxxx/status + \0 */
char status[40];
char line[1024];
FILE *sfile;
snprintf (status, 40, "/proc/%s/status", sname);
status[39] = '\0';
sfile = fopen (status, "r");
if (NULL == sfile) {
return 0;
}
while (fgets (line, sizeof (line), sfile) == line) {
if (strncmp (line, "Uid:\t", 5) == 0) {
unsigned long ruid, euid, suid;
assert (uid == (unsigned long) uid);
if (sscanf (line,
"Uid:\t%lu\t%lu\t%lu\n",
&ruid, &euid, &suid) == 3) {
if ( (ruid == (unsigned long) uid)
|| (euid == (unsigned long) uid)
|| (suid == (unsigned long) uid)) {
(void) fclose (sfile);
return 1;
}
} else {
/* Ignore errors. This is just a best effort. */
}
(void) fclose (sfile);
return 0;
}
}
(void) fclose (sfile);
return 0;
}
static int user_busy_processes (uid_t uid)
{
DIR *proc;
struct dirent *ent;
char *tmp_d_name;
pid_t pid;
DIR *task_dir;
/* 22: /proc/xxxxxxxxxx/task + \0 */
char task_path[22];
char root_path[22];
struct stat sbroot;
struct stat sbroot_process;
proc = opendir ("/proc");
if (proc == NULL) {
perror ("opendir /proc");
return 0;
}
if (stat ("/", &sbroot) != 0) {
perror ("stat (\"/\")");
(void) closedir (proc);
return 0;
}
while ((ent = readdir (proc)) != NULL) {
tmp_d_name = ent->d_name;
/*
* Ingo Molnar's patch introducing NPTL for 2.4 hides
* threads in the /proc directory by prepending a period.
* This patch is applied by default in some RedHat
* kernels.
*/
if ( (strcmp (tmp_d_name, ".") == 0)
|| (strcmp (tmp_d_name, "..") == 0)) {
continue;
}
if (*tmp_d_name == '.') {
tmp_d_name++;
}
/* Check if this is a valid PID */
if (get_pid (tmp_d_name, &pid) == 0) {
continue;
}
/* Check if the process is in our chroot */
snprintf (root_path, 22, "/proc/%lu/root", (unsigned long) pid);
root_path[21] = '\0';
if (stat (root_path, &sbroot_process) != 0) {
continue;
}
if ( (sbroot.st_dev != sbroot_process.st_dev)
|| (sbroot.st_ino != sbroot_process.st_ino)) {
continue;
}
if (check_status (tmp_d_name, uid) != 0) {
(void) closedir (proc);
return 1;
}
snprintf (task_path, 22, "/proc/%lu/task", (unsigned long) pid);
task_path[21] = '\0';
task_dir = opendir (task_path);
if (task_dir != NULL) {
while ((ent = readdir (task_dir)) != NULL) {
pid_t tid;
if (get_pid (ent->d_name, &tid) == 0) {
continue;
}
if (tid == pid) {
continue;
}
if (check_status (task_path+6, uid) != 0) {
(void) closedir (proc);
return 1;
}
}
(void) closedir (task_dir);
} else {
/* Ignore errors. This is just a best effort */
}
}
(void) closedir (proc);
return 0;
}
#endif /* __linux__ */

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,193 +37,102 @@
#include <utmp.h>
#if HAVE_UTMPX_H
#ifdef USE_UTMPX
#include <utmpx.h>
#endif
#include <fcntl.h>
#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#ident "$Id$"
#if HAVE_UTMPX_H
struct utmpx utxent;
#endif
struct utmp utent;
#define NO_UTENT \
_("No utmp entry. You must exec \"login\" from the lowest level \"sh\"")
#define NO_TTY \
_("Unable to determine your tty name.")
/*
* checkutmp - see if utmp file is correct for this process
*
* System V is very picky about the contents of the utmp file
* and requires that a slot for the current process exist.
* The utmp file is scanned for an entry with the same process
* ID. If no entry exists the process exits with a message.
*
* The "picky" flag is for network and other logins that may
* use special flags. It allows the pid checks to be overridden.
* This means that getty should never invoke login with any
* command line flags.
* is_my_tty -- determine if "tty" is the same TTY stdin is using
*/
#if defined(__linux__) /* XXX */
void checkutmp (int picky)
static bool is_my_tty (const char *tty)
{
/* full_tty shall be at least sizeof utmp.ut_line + 5 */
char full_tty[200];
/* tmptty shall be bigger than full_tty */
static char tmptty[sizeof (full_tty)+1];
if ('/' != *tty) {
(void) snprintf (full_tty, sizeof full_tty, "/dev/%s", tty);
tty = &full_tty[0];
}
if ('\0' == tmptty[0]) {
const char *tname = ttyname (STDIN_FILENO);
if (NULL != tname) {
(void) strncpy (tmptty, tname, sizeof tmptty);
tmptty[sizeof (tmptty) - 1] = '\0';
}
}
if (NULL == tmptty) {
(void) puts (_("Unable to determine your tty name."));
exit (EXIT_FAILURE);
} else if (strncmp (tty, tmptty, sizeof (tmptty)) != 0) {
return false;
} else {
return true;
}
}
/*
* get_current_utmp - return the most probable utmp entry for the current
* session
*
* The utmp file is scanned for an entry with the same process ID.
* The line enterred by the *getty / telnetd, etc. should also match
* the current terminal.
*
* When an entry is returned by get_current_utmp, and if the utmp
* structure has a ut_id field, this field should be used to update
* the entry information.
*
* Return NULL if no entries exist in utmp for the current process.
*/
/*@null@*/ /*@only@*/struct utmp *get_current_utmp (void)
{
char *line;
struct utmp *ut;
pid_t pid = getpid ();
struct utmp *ret = NULL;
setutent ();
/* First, try to find a valid utmp entry for this process. */
while ((ut = getutent ()))
if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
(ut->ut_type == LOGIN_PROCESS
|| ut->ut_type == USER_PROCESS))
while ((ut = getutent ()) != NULL) {
if ( (ut->ut_pid == getpid ())
#ifdef HAVE_STRUCT_UTMP_UT_ID
&& ('\0' != ut->ut_id[0])
#endif
#ifdef HAVE_STRUCT_UTMP_UT_TYPE
&& ( (LOGIN_PROCESS == ut->ut_type)
|| (USER_PROCESS == ut->ut_type))
#endif
/* A process may have failed to close an entry
* Check if this entry refers to the current tty */
&& is_my_tty (ut->ut_line)) {
break;
/* If there is one, just use it, otherwise create a new one. */
if (ut) {
utent = *ut;
} else {
if (picky) {
puts (NO_UTENT);
exit (1);
}
line = ttyname (0);
if (!line) {
puts (NO_TTY);
exit (1);
}
if (strncmp (line, "/dev/", 5) == 0)
line += 5;
memset ((void *) &utent, 0, sizeof utent);
utent.ut_type = LOGIN_PROCESS;
utent.ut_pid = pid;
strncpy (utent.ut_line, line, sizeof utent.ut_line);
/* XXX - assumes /dev/tty?? */
strncpy (utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id);
strcpy (utent.ut_user, "LOGIN");
utent.ut_time = time (NULL);
}
}
#elif defined(LOGIN_PROCESS)
void checkutmp (int picky)
{
char *line;
struct utmp *ut;
#if HAVE_UTMPX_H
struct utmpx *utx;
#endif
pid_t pid = getpid ();
#if HAVE_UTMPX_H
setutxent ();
#endif
setutent ();
if (picky) {
#if HAVE_UTMPX_H
while ((utx = getutxent ()))
if (utx->ut_pid == pid)
break;
if (utx)
utxent = *utx;
#endif
while ((ut = getutent ()))
if (ut->ut_pid == pid)
break;
if (ut)
utent = *ut;
#if HAVE_UTMPX_H
endutxent ();
#endif
endutent ();
if (!ut) {
puts (NO_UTENT);
exit (1);
}
#ifndef UNIXPC
/*
* If there is no ut_line value in this record, fill
* it in by getting the TTY name and stuffing it in
* the structure. The UNIX/PC is broken in this regard
* and needs help ...
*/
if (utent.ut_line[0] == '\0')
#endif /* !UNIXPC */
{
if (!(line = ttyname (0))) {
puts (NO_TTY);
exit (1);
}
if (strncmp (line, "/dev/", 5) == 0)
line += 5;
strncpy (utent.ut_line, line, sizeof utent.ut_line);
#if HAVE_UTMPX_H
strncpy (utxent.ut_line, line, sizeof utxent.ut_line);
#endif
}
} else {
if (!(line = ttyname (0))) {
puts (NO_TTY);
exit (1);
}
if (strncmp (line, "/dev/", 5) == 0)
line += 5;
strncpy (utent.ut_line, line, sizeof utent.ut_line);
if ((ut = getutline (&utent)))
strncpy (utent.ut_id, ut->ut_id, sizeof ut->ut_id);
strcpy (utent.ut_user, "LOGIN");
utent.ut_pid = getpid ();
utent.ut_type = LOGIN_PROCESS;
utent.ut_time = time (NULL);
#if HAVE_UTMPX_H
strncpy (utxent.ut_line, line, sizeof utxent.ut_line);
if ((utx = getutxline (&utxent)))
strncpy (utxent.ut_id, utx->ut_id, sizeof utxent.ut_id);
strcpy (utxent.ut_user, "LOGIN");
utxent.ut_pid = utent.ut_pid;
utxent.ut_type = utent.ut_type;
if (sizeof (utxent.ut_tv) == sizeof (struct timeval))
gettimeofday ((struct timeval *) &utxent.ut_tv, NULL);
else {
struct timeval tv;
gettimeofday (&tv, NULL);
utxent.ut_tv.tv_sec = tv.tv_sec;
utxent.ut_tv.tv_usec = tv.tv_usec;
}
utent.ut_time = utxent.ut_tv.tv_sec;
#endif
if (NULL != ut) {
ret = (struct utmp *) xmalloc (sizeof (*ret));
memcpy (ret, ut, sizeof (*ret));
}
endutent ();
return ret;
}
#endif
/*
* Some systems already have updwtmp() and possibly updwtmpx(). Others
* don't, so we re-implement these functions if necessary. --marekm
* don't, so we re-implement these functions if necessary.
*/
#ifndef HAVE_UPDWTMP
static void updwtmp (const char *filename, const struct utmp *ut)
{
@@ -237,7 +146,7 @@ static void updwtmp (const char *filename, const struct utmp *ut)
}
#endif /* ! HAVE_UPDWTMP */
#ifdef HAVE_UTMPX_H
#ifdef USE_UTMPX
#ifndef HAVE_UPDWTMPX
static void updwtmpx (const char *filename, const struct utmpx *utx)
{
@@ -250,131 +159,297 @@ static void updwtmpx (const char *filename, const struct utmpx *utx)
}
}
#endif /* ! HAVE_UPDWTMPX */
#endif /* ! HAVE_UTMPX_H */
#endif /* ! USE_UTMPX */
/*
* setutmp - put a USER_PROCESS entry in the utmp file
* prepare_utmp - prepare an utmp entry so that it can be logged in a
* utmp/wtmp file.
*
* setutmp changes the type of the current utmp entry to
* USER_PROCESS. the wtmp file will be updated as well.
* It accepts an utmp entry in input (ut) to return an entry with
* the right ut_id. This is typically an entry returned by
* get_current_utmp
* If ut is NULL, ut_id will be forged based on the line argument.
*
* The ut_host field of the input structure may also be kept, and is
* used to define the ut_addr/ut_addr_v6 fields. (if these fields
* exist)
*
* Other fields are discarded and filed with new values (if they
* exist).
*
* The returned structure shall be freed by the caller.
*/
#if defined(__linux__) /* XXX */
void setutmp (const char *name, const char *line, const char *host)
/*@only@*/struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut)
{
utent.ut_type = USER_PROCESS;
strncpy (utent.ut_user, name, sizeof utent.ut_user);
utent.ut_time = time (NULL);
/* other fields already filled in by checkutmp above */
setutent ();
pututline (&utent);
endutent ();
updwtmp (_WTMP_FILE, &utent);
struct timeval tv;
char *hostname = NULL;
struct utmp *utent;
assert (NULL != name);
assert (NULL != line);
if ( (NULL != host)
&& ('\0' != host[0])) {
hostname = (char *) xmalloc (strlen (host) + 1);
strcpy (hostname, host);
#ifdef HAVE_STRUCT_UTMP_UT_HOST
} else if ( (NULL != ut)
&& (NULL != ut->ut_host)
&& ('\0' != ut->ut_host[0])) {
hostname = (char *) xmalloc (sizeof (ut->ut_host) + 1);
strncpy (hostname, ut->ut_host, sizeof (ut->ut_host));
hostname[sizeof (ut->ut_host)] = '\0';
#endif /* HAVE_STRUCT_UTMP_UT_HOST */
}
if (strncmp(line, "/dev/", 5) == 0) {
line += 5;
}
utent = (struct utmp *) xmalloc (sizeof (*utent));
memzero (utent, sizeof (*utent));
#ifdef HAVE_STRUCT_UTMP_UT_TYPE
utent->ut_type = USER_PROCESS;
#endif /* HAVE_STRUCT_UTMP_UT_TYPE */
utent->ut_pid = getpid ();
strncpy (utent->ut_line, line, sizeof (utent->ut_line));
#ifdef HAVE_STRUCT_UTMP_UT_ID
if (NULL != ut) {
strncpy (utent->ut_id, ut->ut_id, sizeof (utent->ut_id));
} else {
/* XXX - assumes /dev/tty?? */
strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id));
}
#endif /* HAVE_STRUCT_UTMP_UT_ID */
#ifdef HAVE_STRUCT_UTMP_UT_NAME
strncpy (utent->ut_name, name, sizeof (utent->ut_name));
#endif /* HAVE_STRUCT_UTMP_UT_NAME */
#ifdef HAVE_STRUCT_UTMP_UT_USER
strncpy (utent->ut_user, name, sizeof (utent->ut_user));
#endif /* HAVE_STRUCT_UTMP_UT_USER */
if (NULL != hostname) {
struct addrinfo *info = NULL;
#ifdef HAVE_STRUCT_UTMP_UT_HOST
strncpy (utent->ut_host, hostname, sizeof (utent->ut_host));
#endif /* HAVE_STRUCT_UTMP_UT_HOST */
#ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
utent->ut_syslen = MIN (strlen (hostname),
sizeof (utent->ut_host));
#endif /* HAVE_STRUCT_UTMP_UT_SYSLEN */
#if defined(HAVE_STRUCT_UTMP_UT_ADDR) || defined(HAVE_STRUCT_UTMP_UT_ADDR_V6)
if (getaddrinfo (hostname, NULL, NULL, &info) == 0) {
/* getaddrinfo might not be reliable.
* Just try to log what may be useful.
*/
if (info->ai_family == AF_INET) {
struct sockaddr_in *sa =
(struct sockaddr_in *) info->ai_addr;
#ifdef HAVE_STRUCT_UTMP_UT_ADDR
memcpy (&(utent->ut_addr),
&(sa->sin_addr),
MIN (sizeof (utent->ut_addr),
sizeof (sa->sin_addr)));
#endif /* HAVE_STRUCT_UTMP_UT_ADDR */
#ifdef HAVE_STRUCT_UTMP_UT_ADDR_V6
memcpy (utent->ut_addr_v6,
&(sa->sin_addr),
MIN (sizeof (utent->ut_addr_v6),
sizeof (sa->sin_addr)));
} else if (info->ai_family == AF_INET6) {
struct sockaddr_in6 *sa =
(struct sockaddr_in6 *) info->ai_addr;
memcpy (utent->ut_addr_v6,
&(sa->sin6_addr),
MIN (sizeof (utent->ut_addr_v6),
sizeof (sa->sin6_addr)));
#endif /* HAVE_STRUCT_UTMP_UT_ADDR_V6 */
}
freeaddrinfo (info);
}
#endif /* HAVE_STRUCT_UTMP_UT_ADDR || HAVE_STRUCT_UTMP_UT_ADDR_V6 */
free (hostname);
}
/* ut_exit is only for DEAD_PROCESS */
utent->ut_session = getsid (0);
if (gettimeofday (&tv, NULL) == 0) {
#ifdef HAVE_STRUCT_UTMP_UT_TIME
utent->ut_time = tv.tv_sec;
#endif /* HAVE_STRUCT_UTMP_UT_TIME */
#ifdef HAVE_STRUCT_UTMP_UT_XTIME
utent->ut_xtime = tv.tv_usec;
#endif /* HAVE_STRUCT_UTMP_UT_XTIME */
#ifdef HAVE_STRUCT_UTMP_UT_TV
utent->ut_tv.tv_sec = tv.tv_sec;
utent->ut_tv.tv_usec = tv.tv_usec;
#endif /* HAVE_STRUCT_UTMP_UT_TV */
}
return utent;
}
#elif HAVE_UTMPX_H
void setutmp (const char *name, const char *line, const char *host)
/*
* setutmp - Update an entry in utmp and log an entry in wtmp
*
* Return 1 on failure and 0 on success.
*/
int setutmp (struct utmp *ut)
{
struct utmp *utmp, utline;
struct utmpx *utmpx, utxline;
pid_t pid = getpid ();
int found_utmpx = 0, found_utmp = 0;
int err = 0;
/*
* The canonical device name doesn't include "/dev/"; skip it
* if it is already there.
*/
assert (NULL != ut);
if (strncmp (line, "/dev/", 5) == 0)
setutent ();
if (pututline (ut) == NULL) {
err = 1;
}
endutent ();
updwtmp (_WTMP_FILE, ut);
return err;
}
#ifdef USE_UTMPX
/*
* prepare_utmpx - the UTMPX version for prepare_utmp
*/
/*@only@*/struct utmpx *prepare_utmpx (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut)
{
struct timeval tv;
char *hostname = NULL;
struct utmpx *utxent;
assert (NULL != name);
assert (NULL != line);
if ( (NULL != host)
&& ('\0' != host[0])) {
hostname = (char *) xmalloc (strlen (host) + 1);
strcpy (hostname, host);
#ifdef HAVE_STRUCT_UTMP_UT_HOST
} else if ( (NULL != ut)
&& (NULL != ut->ut_host)
&& ('\0' != ut->ut_host[0])) {
hostname = (char *) xmalloc (sizeof (ut->ut_host) + 1);
strncpy (hostname, ut->ut_host, sizeof (ut->ut_host));
hostname[sizeof (ut->ut_host)] = '\0';
#endif /* HAVE_STRUCT_UTMP_UT_TYPE */
}
if (strncmp(line, "/dev/", 5) == 0) {
line += 5;
}
/*
* Update utmpx. We create an empty entry in case there is
* no matching entry in the utmpx file.
*/
utxent = (struct utmpx *) xmalloc (sizeof (*utxent));
memzero (utxent, sizeof (*utxent));
utxent->ut_type = USER_PROCESS;
utxent->ut_pid = getpid ();
strncpy (utxent->ut_line, line, sizeof (utxent->ut_line));
/* existence of ut->ut_id is enforced by configure */
if (NULL != ut) {
strncpy (utxent->ut_id, ut->ut_id, sizeof (utxent->ut_id));
} else {
/* XXX - assumes /dev/tty?? */
strncpy (utxent->ut_id, line + 3, sizeof (utxent->ut_id));
}
#ifdef HAVE_STRUCT_UTMPX_UT_NAME
strncpy (utxent->ut_name, name, sizeof (utxent->ut_name));
#endif /* HAVE_STRUCT_UTMPX_UT_NAME */
strncpy (utxent->ut_user, name, sizeof (utxent->ut_user));
if (NULL != hostname) {
struct addrinfo *info = NULL;
#ifdef HAVE_STRUCT_UTMPX_UT_HOST
strncpy (utxent->ut_host, hostname, sizeof (utxent->ut_host));
#endif /* HAVE_STRUCT_UTMPX_UT_HOST */
#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
utxent->ut_syslen = MIN (strlen (hostname),
sizeof (utxent->ut_host));
#endif /* HAVE_STRUCT_UTMPX_UT_SYSLEN */
#if defined(HAVE_STRUCT_UTMPX_UT_ADDR) || defined(HAVE_STRUCT_UTMPX_UT_ADDR_V6)
if (getaddrinfo (hostname, NULL, NULL, &info) == 0) {
/* getaddrinfo might not be reliable.
* Just try to log what may be useful.
*/
if (info->ai_family == AF_INET) {
struct sockaddr_in *sa =
(struct sockaddr_in *) info->ai_addr;
#ifdef HAVE_STRUCT_UTMPX_UT_ADDR
memcpy (utxent->ut_addr,
&(sa->sin_addr),
MIN (sizeof (utxent->ut_addr),
sizeof (sa->sin_addr)));
#endif /* HAVE_STRUCT_UTMPX_UT_ADDR */
#ifdef HAVE_STRUCT_UTMPX_UT_ADDR_V6
memcpy (utxent->ut_addr_v6,
&(sa->sin_addr),
MIN (sizeof (utxent->ut_addr_v6),
sizeof (sa->sin_addr)));
} else if (info->ai_family == AF_INET6) {
struct sockaddr_in6 *sa =
(struct sockaddr_in6 *) info->ai_addr;
memcpy (utxent->ut_addr_v6,
&(sa->sin6_addr),
MIN (sizeof (utxent->ut_addr_v6),
sizeof (sa->sin6_addr)));
#endif /* HAVE_STRUCT_UTMPX_UT_ADDR_V6 */
}
freeaddrinfo (info);
}
#endif /* HAVE_STRUCT_UTMPX_UT_ADDR || HAVE_STRUCT_UTMPX_UT_ADDR_V6 */
free (hostname);
}
/* ut_exit is only for DEAD_PROCESS */
utxent->ut_session = getsid (0);
if (gettimeofday (&tv, NULL) == 0) {
#ifdef HAVE_STRUCT_UTMPX_UT_TIME
utxent->ut_time = tv.tv_sec;
#endif /* HAVE_STRUCT_UTMPX_UT_TIME */
#ifdef HAVE_STRUCT_UTMPX_UT_XTIME
utxent->ut_xtime = tv.tv_usec;
#endif /* HAVE_STRUCT_UTMPX_UT_XTIME */
utxent->ut_tv.tv_sec = tv.tv_sec;
utxent->ut_tv.tv_usec = tv.tv_usec;
}
return utxent;
}
/*
* setutmpx - the UTMPX version for setutmp
*/
int setutmpx (struct utmpx *utx)
{
int err = 0;
assert (NULL != utx);
setutxent ();
setutent ();
while (utmpx = getutxent ()) {
if (utmpx->ut_pid == pid) {
found_utmpx = 1;
break;
}
}
while (utmp = getutent ()) {
if (utmp->ut_pid == pid) {
found_utmp = 1;
break;
}
if (pututxline (utx) == NULL) {
err = 1;
}
endutxent ();
/*
* If the entry matching `pid' cannot be found, create a new
* entry with the device name in it.
*/
updwtmpx (_WTMP_FILE "x", utx);
if (!found_utmpx) {
memset ((void *) &utxline, 0, sizeof utxline);
strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
utxline.ut_pid = getpid ();
} else {
utxline = *utmpx;
if (strncmp (utxline.ut_line, "/dev/", 5) == 0) {
memmove (utxline.ut_line, utxline.ut_line + 5,
sizeof utxline.ut_line - 5);
utxline.ut_line[sizeof utxline.ut_line - 5] = '\0';
}
}
if (!found_utmp) {
memset ((void *) &utline, 0, sizeof utline);
strncpy (utline.ut_line, utxline.ut_line,
sizeof utline.ut_line);
utline.ut_pid = utxline.ut_pid;
} else {
utline = *utmp;
if (strncmp (utline.ut_line, "/dev/", 5) == 0) {
memmove (utline.ut_line, utline.ut_line + 5,
sizeof utline.ut_line - 5);
utline.ut_line[sizeof utline.ut_line - 5] = '\0';
}
}
/*
* Fill in the fields in the utmpx entry and write it out. Do
* the utmp entry at the same time to make sure things don't
* get messed up.
*/
strncpy (utxline.ut_user, name, sizeof utxline.ut_user);
strncpy (utline.ut_user, name, sizeof utline.ut_user);
utline.ut_type = utxline.ut_type = USER_PROCESS;
if (sizeof (utxline.ut_tv) == sizeof (struct timeval))
gettimeofday ((struct timeval *) &utxline.ut_tv, NULL);
else {
struct timeval tv;
gettimeofday (&tv, NULL);
utxline.ut_tv.tv_sec = tv.tv_sec;
utxline.ut_tv.tv_usec = tv.tv_usec;
}
utline.ut_time = utxline.ut_tv.tv_sec;
strncpy (utxline.ut_host, host ? host : "", sizeof utxline.ut_host);
pututxline (&utxline);
pututline (&utline);
updwtmpx (_WTMP_FILE "x", &utxline);
updwtmp (_WTMP_FILE, &utline);
utxent = utxline;
utent = utline;
return err;
}
#endif /* USE_UTMPX */
#endif

View File

@@ -2,7 +2,7 @@
* Copyright (c) 1989 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* Copyright (c) 2007 - 2008, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
* is used to indicate that a dummy salt must be used to encrypt the
* password anyway.
*/
int valid (const char *password, const struct passwd *ent)
bool valid (const char *password, const struct passwd *ent)
{
const char *encrypted;
const char *salt;
@@ -61,18 +61,19 @@ int valid (const char *password, const struct passwd *ent)
* routine is meant to waste CPU time.
*/
if (ent->pw_name && !ent->pw_passwd[0]) {
if (!password[0])
return (1); /* user entered nothing */
else
return (0); /* user entered something! */
if ((NULL != ent->pw_name) && ('\0' == ent->pw_passwd[0])) {
if ('\0' == password[0]) {
return true; /* user entered nothing */
} else {
return false; /* user entered something! */
}
}
/*
* If there is no entry then we need a salt to use.
*/
if (ent->pw_name == (char *) 0 || ent->pw_passwd[0] == '\0') {
if ((NULL == ent->pw_name) || ('\0' == ent->pw_passwd[0])) {
salt = "xx";
} else {
salt = ent->pw_passwd;
@@ -93,9 +94,11 @@ int valid (const char *password, const struct passwd *ent)
* cause non-existent users to not be validated.
*/
if (ent->pw_name && strcmp (encrypted, ent->pw_passwd) == 0)
return (1);
else
return (0);
if ( (NULL != ent->pw_name)
&& (strcmp (encrypted, ent->pw_passwd) == 0)) {
return true;
} else {
return false;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 - 2008, Nicolas François
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <config.h>
#include <errno.h>
#include "prototypes.h"
#define XFUNCTION_NAME XPREFIX (FUNCTION_NAME)
@@ -64,7 +64,7 @@
#define STRINGIZE(name) STRINGIZE1 (name)
#define STRINGIZE1(name) #name
LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME)
/*@null@*/ /*@only@*/LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME)
{
#if HAVE_FUNCTION_R
LOOKUP_TYPE *result=NULL;
@@ -79,7 +79,7 @@ LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME)
exit (13);
}
do {
while (true) {
int status;
LOOKUP_TYPE *resbuf = NULL;
buffer = (char *)realloc (buffer, length);
@@ -91,7 +91,7 @@ LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME)
errno = 0;
status = REENTRANT_NAME(ARG_NAME, result, buffer,
length, &resbuf);
if (!status && (resbuf == result)) {
if ((0 ==status) && (resbuf == result)) {
/* Build a result structure that can be freed by
* the shadow *_free functions. */
LOOKUP_TYPE *ret_result = DUP_FUNCTION(result);
@@ -106,8 +106,14 @@ LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME)
return NULL;
}
length *= 4;
} while (length < MAX_LENGTH);
if (length <= ((size_t)-1 / 4)) {
length *= 4;
} else if (length == (size_t) -1) {
break;
} else {
length = (size_t) -1;
}
}
free(buffer);
free(result);

Some files were not shown because too many files have changed in this diff Show More