2010-01-30 Paweł Hajdan, Jr. <phajdan.jr@gentoo.org>

* NEWS: Add support for TCB.
	* lib/tcbfuncs.h, lib/tcbfuncs.c, lib/Makefile.am: New library to
	support TCB.
	* lib/prototypes, libmisc/copydir.c (remove_tree): Add boolean
	parameter remove_root.
	* configure.in: Add conditional WITH_TCB.
	* src/userdel.c, src/usermod.c: Add support for TCB. Update call to
	remove_tree().
	* src/pwconv.c, src/pwunconv.c: Should not be used with TCB enabled.
	* src/vipw.c: Add support for TCB. Update call to remove_tree().
	* src/useradd.c: Add support for TCB. Open the shadow file outside
	of open_files().
	* src/chage.c: Add support for TCB.
	* src/Makefile.am: Install passwd sgid shadow when TCB is enabled.
	* lib/getdefs.c, man/vipw.8.xml, man/login.defs.5.xml,
	man/login.defs/TCB_AUTH_GROUP.xml, man/login.defs/USE_TCB.xml,
	man/login.defs/TCB_SYMLINKS.xml, man/generate_mans.mak,
	man/generate_mans.deps, man/Makefile.am: New configuration
	parameters: TCB_AUTH_GROUP, TCB_SYMLINKS, USE_TCB.
	* lib/shadowio.c, lib/commonio.c: Add support for TCB.
This commit is contained in:
nekral-guest
2010-03-04 18:11:13 +00:00
parent 5ba95d4c53
commit 391a384715
27 changed files with 1067 additions and 44 deletions

View File

@@ -5,6 +5,7 @@ EXTRA_DIST = \
ubindir = ${prefix}/bin
usbindir = ${prefix}/sbin
suidperms = 4755
sgidperms = 2755
INCLUDES = \
-I${top_srcdir}/lib \
@@ -53,7 +54,13 @@ if ACCT_TOOLS_SETUID
suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
endif
if WITH_TCB
suidubins -= passwd
shadowsgidubins = passwd
endif
LDADD = $(INTLLIBS) \
$(LIBTCB) \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/lib/libshadow.la
AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\"
@@ -114,3 +121,9 @@ install-am: all-am
for i in $(suidubins); do \
chmod -f $(suidperms) $(DESTDIR)$(ubindir)/$$i; \
done
if WITH_TCB
for i in $(shadowsgidubins); do \
chown root:shadow $(DESTDIR)$(ubindir)/$$i; \
chmod -f $(sgidperms) $(DESTDIR)$(ubindir)/$$i; \
done
endif

View File

@@ -56,6 +56,9 @@
#include "defines.h"
#include "pwio.h"
#include "shadowio.h"
#ifdef WITH_TCB
#include "tcbfuncs.h"
#endif
/*@-exitarg@*/
#include "exitcodes.h"
@@ -853,6 +856,10 @@ int main (int argc, char **argv)
}
STRFCPY (user_name, pw->pw_name);
#ifdef WITH_TCB
if (!shadowtcb_set_user(pw->pw_name))
fail_exit(E_NOPERM);
#endif
user_uid = pw->pw_uid;
sp = spw_locate (argv[optind]);

View File

@@ -133,6 +133,11 @@ int main (int argc, char **argv)
OPENLOG ("pwconv");
if (getdef_bool("USE_TCB")) {
fprintf(stderr, _("%s: can't work with tcb enabled\n"), Prog);
fail_exit(E_FAILURE);
}
if (pw_lock () == 0) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),

View File

@@ -93,6 +93,11 @@ int main (int argc, char **argv)
OPENLOG ("pwunconv");
if (getdef_bool("USE_TCB")) {
fprintf(stderr, _("%s: can't work with tcb enabled\n"), Prog);
exit(1);
}
if (!spw_file_present ()) {
/* shadow not installed, do nothing */
exit (0);

View File

@@ -65,6 +65,9 @@
#include "sgroupio.h"
#endif
#include "shadowio.h"
#ifdef WITH_TCB
#include "tcbfuncs.h"
#endif
#ifndef SKEL_DIR
#define SKEL_DIR "/etc/skel"
@@ -192,6 +195,7 @@ static void grp_update (void);
static void process_flags (int argc, char **argv);
static void close_files (void);
static void open_files (void);
static void open_shadow (void);
static void faillog_reset (uid_t);
static void lastlog_reset (uid_t);
static void usr_update (void);
@@ -1429,21 +1433,8 @@ static void open_files (void)
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
fail_exit (E_PW_UPDATE);
}
if (is_shadow_pwd) {
if (spw_lock () == 0) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, spw_dbname ());
fail_exit (E_PW_UPDATE);
}
spw_locked = true;
if (spw_open (O_RDWR) == 0) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, spw_dbname ());
fail_exit (E_PW_UPDATE);
}
}
/* shadow file will be opened by open_shadow(); */
/*
* Lock and open the group file.
@@ -1478,6 +1469,25 @@ static void open_files (void)
#endif
}
static void open_shadow (void)
{
if (!is_shadow_pwd)
return;
if (!spw_lock ()) {
fprintf(stderr,
_("%s: cannot lock shadow password file\n"),
Prog);
fail_exit(E_PW_UPDATE);
}
spw_locked = true;
if (!spw_open (O_RDWR)) {
fprintf(stderr,
_("%s: cannot open shadow password file\n"),
Prog);
fail_exit(E_PW_UPDATE);
}
}
static char *empty_list = NULL;
/*
@@ -1990,6 +2000,16 @@ int main (int argc, char **argv)
}
}
#ifdef WITH_TCB
if (getdef_bool("USE_TCB")) {
if (!shadowtcb_create(user_name, user_id)) {
fprintf(stderr, "Failed to create tcb directory for %s\n", user_name);
fail_exit (E_UID_IN_USE);
}
}
#endif
open_shadow();
/* do we have to add a group for that user? This is why we need to
* open the group files in the open_files() function --gafton */
if (Uflg) {

View File

@@ -59,6 +59,10 @@
#ifdef SHADOWGRP
#include "sgroupio.h"
#endif
#ifdef WITH_TCB
#include <tcb.h>
#include "tcbfuncs.h"
#endif
/*@-exitarg@*/
#include "exitcodes.h"
@@ -107,6 +111,9 @@ static bool path_prefix (const char *, const char *);
#endif
static int is_owner (uid_t, const char *);
static int remove_mailbox (void);
#ifdef WITH_TCB
static int remove_tcbdir (const char *user_name, uid_t user_id);
#endif
/*
* usage - display usage message and exit
@@ -731,6 +738,49 @@ static int remove_mailbox (void)
return errors;
}
#ifdef WITH_TCB
static int remove_tcbdir (const char *user_name, uid_t user_id)
{
char *buf;
int ret = 0;
if (!getdef_bool("USE_TCB"))
return 0;
buf = malloc(strlen(TCB_DIR) + strlen(user_name) + 2);
if (!buf) {
fprintf(stderr, "Can't allocate memory, "
"tcb entry for %s not removed.\n",
user_name);
return 1;
}
snprintf(buf, strlen(TCB_DIR) + strlen(user_name) + 2,
TCB_DIR "/%s", user_name);
if (!shadowtcb_drop_priv()) {
perror("shadowtcb_drop_priv");
free(buf);
return 1;
}
/* Only remove directory contents with dropped privileges.
* We will regain them and remove the user's tcb directory afterwards.
*/
if (remove_tree(buf, false)) {
perror("remove_tree");
shadowtcb_gain_priv();
free(buf);
return 1;
}
shadowtcb_gain_priv();
free(buf);
if (!shadowtcb_remove(user_name)) {
fprintf(stderr, "Cannot remove tcb files for %s: %s\n",
user_name, strerror(errno));
ret = 1;
}
return ret;
}
#endif
/*
* main - userdel command
*/
@@ -851,6 +901,10 @@ int main (int argc, char **argv)
user_id = pwd->pw_uid;
user_home = xstrdup (pwd->pw_dir);
}
#ifdef WITH_TCB
if (!shadowtcb_set_user(user_name))
exit (E_NOTFOUND);
#endif
#ifdef USE_NIS
/*
@@ -951,7 +1005,7 @@ int main (int argc, char **argv)
#endif
if (rflg) {
if (remove_tree (user_home) != 0) {
if (remove_tree (user_home, true) != 0) {
fprintf (stderr,
_("%s: error removing directory %s\n"),
Prog, user_home);
@@ -996,6 +1050,10 @@ int main (int argc, char **argv)
user_cancel (user_name);
close_files ();
#ifdef WITH_TCB
errors += remove_tcbdir(user_name, user_id);
#endif
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");

View File

@@ -63,6 +63,9 @@
#include "sgroupio.h"
#endif
#include "shadowio.h"
#ifdef WITH_TCB
#include "tcbfuncs.h"
#endif
/*
* exit status values
@@ -1438,7 +1441,7 @@ static void move_home (void)
if (copy_tree (user_home, user_newhome,
uflg ? (long int)user_newid : -1,
gflg ? (long int)user_newgid : -1) == 0) {
if (remove_tree (user_home) != 0) {
if (remove_tree (user_home, true) != 0) {
fprintf (stderr,
_("%s: warning: failed to completely remove old home directory %s"),
Prog, user_home);
@@ -1456,7 +1459,7 @@ static void move_home (void)
/* TODO: do some cleanup if the copy
* was started */
(void) remove_tree (user_newhome);
(void) remove_tree (user_newhome, true);
}
fprintf (stderr,
_("%s: cannot rename directory %s to %s\n"),
@@ -1655,7 +1658,7 @@ static void move_mailbox (void)
return;
}
if (uflg) {
if (fchown (fd, user_newid, (gid_t) - 1) < 0) {
if (fchown (fd, user_newid, (gid_t) -1) < 0) {
perror (_("failed to change mailbox owner"));
}
#ifdef WITH_AUDIT
@@ -1770,6 +1773,11 @@ int main (int argc, char **argv)
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#ifdef WITH_TCB
if (!shadowtcb_set_user(user_name))
exit(E_PW_UPDATE);
#endif
/*
* Do the hard stuff - open the files, change the user entries,
* change the home directory, then close and update the files.
@@ -1784,6 +1792,13 @@ int main (int argc, char **argv)
}
close_files ();
#ifdef WITH_TCB
if ((user_newname || user_newid != -1) &&
!shadowtcb_move(user_newname, user_newid)) {
exit(E_PW_UPDATE);
}
#endif
nscd_flush_cache ("passwd");
nscd_flush_cache ("group");

View File

@@ -48,6 +48,10 @@
#include "shadowio.h"
/*@-exitarg@*/
#include "exitcodes.h"
#ifdef WITH_TCB
#include <tcb.h>
#include "tcbfuncs.h"
#endif
#define MSG_WARN_EDIT_OTHER_FILE _( \
"You have modified %s.\n"\
@@ -62,6 +66,8 @@ static bool filelocked = false;
static bool createedit = false;
static int (*unlock) (void);
static bool quiet = false;
static const char *user = NULL;
static bool tcb_mode = false;
/* local function prototypes */
static void usage (int status);
@@ -83,6 +89,9 @@ static void usage (int status)
" -p, --passwd edit passwd database\n"
" -q, --quiet quiet mode\n"
" -s, --shadow edit shadow or gshadow database\n"
#ifdef WITH_TCB
" -u, --user which user's tcb shadow file to edit\n"
#endif
"\n"), (E_SUCCESS != status) ? stderr : stdout);
exit (status);
}
@@ -175,6 +184,8 @@ static void vipwexit (const char *msg, int syserr, int ret)
#define DEFAULT_EDITOR "vi"
#endif
#define SHADOWTCB_SCRATCHDIR ":tmp"
/*
*
*/
@@ -187,9 +198,23 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
int status;
FILE *f;
char filebackup[1024], fileedit[1024];
char *to_rename;
snprintf (filebackup, sizeof filebackup, "%s-", file);
snprintf (fileedit, sizeof fileedit, "%s.edit", file);
#ifdef WITH_TCB
if (tcb_mode) {
if (mkdir(TCB_DIR "/" SHADOWTCB_SCRATCHDIR, 0700) && errno != EEXIST)
vipwexit (_("failed to create scratch directory"), errno, 1);
if (!shadowtcb_drop_priv())
vipwexit (_("failed to drop privileges"), errno, 1);
snprintf(fileedit, sizeof fileedit,
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s", user);
} else {
#endif
snprintf (fileedit, sizeof fileedit, "%s.edit", file);
#ifdef WITH_TCB
}
#endif
unlock = file_unlock;
filename = file;
fileeditname = fileedit;
@@ -212,11 +237,19 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
vipwexit (_("setfscreatecon () failed"), errno, 1);
}
}
#endif
#ifdef WITH_TCB
if (tcb_mode && !shadowtcb_gain_priv())
vipwexit (_("failed to gain privileges"), errno, 1);
#endif
if (file_lock () == 0) {
vipwexit (_("Couldn't lock file"), errno, 5);
}
filelocked = true;
#ifdef WITH_TCB
if (tcb_mode && !shadowtcb_drop_priv())
vipwexit (_("failed to drop privileges"), errno, 1);
#endif
/* edited copy has same owners, perm */
if (stat (file, &st1) != 0) {
@@ -226,6 +259,10 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
if (NULL == f) {
vipwexit (file, 1, 1);
}
#ifdef WITH_TCB
if (tcb_mode && !shadowtcb_gain_priv())
vipwexit (_("failed to gain privileges"), errno, 1);
#endif
if (create_backup_file (f, fileedit, &st1) != 0) {
vipwexit (_("Couldn't make backup"), errno, 1);
}
@@ -300,15 +337,49 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
* without saving). Use pwck or grpck to do the check. --marekm
*/
createedit = false;
#ifdef WITH_TCB
if (tcb_mode) {
if (!(f = fopen(fileedit, "r")))
vipwexit (_("failed to open scratch file"), errno, 1);
if (unlink(fileedit))
vipwexit (_("failed to unlink scratch file"), errno, 1);
if (!shadowtcb_drop_priv())
vipwexit (_("failed to drop privileges"), errno, 1);
if (stat(file, &st1))
vipwexit (_("failed to stat edited file"), errno, 1);
to_rename = malloc(strlen(file) + 2);
if (!to_rename)
vipwexit (_("failed to allocate memory"), errno, 1);
snprintf(to_rename, strlen(file) + 2, "%s+", file);
if (create_backup_file(f, to_rename, &st1)) {
free(to_rename);
vipwexit (_("failed to create backup file"), errno, 1);
}
} else {
#endif
to_rename = fileedit;
#ifdef WITH_TCB
}
#endif
unlink (filebackup);
link (file, filebackup);
if (rename (fileedit, file) == -1) {
if (rename (to_rename, file) == -1) {
fprintf (stderr,
_("%s: can't restore %s: %s (your changes are in %s)\n"),
progname, file, strerror (errno), fileedit);
progname, file, strerror (errno), to_rename);
if (tcb_mode)
free(to_rename);
vipwexit (0, 0, 1);
}
#ifdef WITH_TCB
if (tcb_mode) {
free(to_rename);
if (!shadowtcb_gain_priv())
vipwexit (_("failed to gain privileges"), errno, 1);
}
#endif
if ((*file_unlock) () == 0) {
fprintf (stderr, _("%s: failed to unlock %s\n"), progname, fileeditname);
SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname));
@@ -343,11 +414,18 @@ int main (int argc, char **argv)
{"passwd", no_argument, NULL, 'p'},
{"quiet", no_argument, NULL, 'q'},
{"shadow", no_argument, NULL, 's'},
#ifdef WITH_TCB
{"user", required_argument, NULL, 'u'},
#endif
{NULL, 0, NULL, '\0'}
};
while ((c =
getopt_long (argc, argv, "ghpqs",
long_options, NULL)) != -1) {
while ((c = getopt_long (argc, argv,
#ifdef WITH_TCB
"ghpqsu:",
#else
"ghpqs",
#endif
long_options, NULL)) != -1) {
switch (c) {
case 'g':
do_vipw = false;
@@ -364,6 +442,9 @@ int main (int argc, char **argv)
case 's':
editshadow = true;
break;
case 'u':
user = optarg;
break;
default:
usage (E_USAGE);
}
@@ -372,9 +453,20 @@ int main (int argc, char **argv)
if (do_vipw) {
if (editshadow) {
vipwedit (SHADOW_FILE, spw_lock, spw_unlock);
#ifdef WITH_TCB
if (getdef_bool("USE_TCB") && user) {
if (!shadowtcb_set_user(user)) {
fprintf (stderr,
_("%s: failed to find tcb directory for %s\n"),
progname, user);
return E_SHADOW_NOTFOUND;
}
tcb_mode = true;
}
#endif
vipwedit (spw_dbname (), spw_lock, spw_unlock);
printf (MSG_WARN_EDIT_OTHER_FILE,
SHADOW_FILE,
spw_dbname (),
PASSWD_FILE,
"vipw");
} else {