Exemple #1
0
int spw_close (void)
{
	int retval = 0;
#ifdef WITH_TCB
	bool use_tcb = getdef_bool ("USE_TCB");

	if (use_tcb && (shadowtcb_drop_priv () == SHADOWTCB_FAILURE)) {
		return 0;
	}
#endif				/* WITH_TCB */
	retval = commonio_close (&shadow_db);
#ifdef WITH_TCB
	if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) {
		return 0;
	}
#endif				/* WITH_TCB */
	return retval;
}
Exemple #2
0
static int remove_tcbdir (const char *user_name, uid_t user_id)
{
	char *buf;
	int ret = 0;
	size_t bufsize = (sizeof TCB_DIR) + strlen (user_name) + 2;

	if (!getdef_bool ("USE_TCB")) {
		return 0;
	}

	buf = malloc (buflen);
	if (NULL == buf) {
		fprintf (stderr, _("%s: Can't allocate memory, "
		                   "tcb entry for %s not removed.\n"),
		         Prog, user_name);
		return 1;
	}
	snprintf (buf, buflen, TCB_DIR "/%s", user_name);
	if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
		fprintf (stderr, _("%s: Cannot drop privileges: %s\n"),
		         Prog, strerror (errno));
		shadowtcb_gain_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) != 0) {
		fprintf (stderr, _("%s: Cannot remove the content of %s: %s\n"),
		         Prog, buf, strerror (errno));
		shadowtcb_gain_priv ();
		free (buf);
		return 1;
	}
	shadowtcb_gain_priv ();
	free (buf);
	if (shadowtcb_remove (user_name) == SHADOWTCB_FAILURE) {
		fprintf (stderr, _("%s: Cannot remove tcb files for %s: %s\n"),
		         Prog, user_name, strerror (errno));
		ret = 1;
	}
	return ret;
}
Exemple #3
0
int spw_unlock (void)
{
#ifdef WITH_TCB
	int retval = 0;

	if (!getdef_bool ("USE_TCB")) {
#endif				/* WITH_TCB */
		return commonio_unlock (&shadow_db);
#ifdef WITH_TCB
	}
	if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
		return 0;
	}
	if (ulckpwdf_tcb () == 0) {
		shadow_db.locked = 0;
		retval = 1;
	}
	if (shadowtcb_gain_priv () == SHADOWTCB_FAILURE) {
		return 0;
	}
	return retval;
#endif				/* WITH_TCB */
}
Exemple #4
0
static void
vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
{
	const char *editor;
	pid_t pid;
	struct stat st1, st2;
	int status;
	FILE *f;
	/* FIXME: the following should have variable sizes */
	char filebackup[1024], fileedit[1024];
	char *to_rename;

	snprintf (filebackup, sizeof filebackup, "%s-", file);
#ifdef WITH_TCB
	if (tcb_mode) {
		if (   (mkdir (TCB_DIR "/" SHADOWTCB_SCRATCHDIR, 0700) != 0)
		    && (errno != EEXIST)) {
			vipwexit (_("failed to create scratch directory"), errno, 1);
		}
		if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
			vipwexit (_("failed to drop privileges"), errno, 1);
		}
		snprintf (fileedit, sizeof fileedit,
		          TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s",
		          user);
	} else {
#endif				/* WITH_TCB */
		snprintf (fileedit, sizeof fileedit, "%s.edit", file);
#ifdef WITH_TCB
	}
#endif				/* WITH_TCB */
	unlock = file_unlock;
	filename = file;
	fileeditname = fileedit;

	if (access (file, F_OK) != 0) {
		vipwexit (file, 1, 1);
	}
#ifdef WITH_SELINUX
	/* if SE Linux is enabled then set the context of all new files
	   to be the context of the file we are editing */
	if (is_selinux_enabled () != 0) {
		security_context_t passwd_context=NULL;
		int ret = 0;
		if (getfilecon (file, &passwd_context) < 0) {
			vipwexit (_("Couldn't get file context"), errno, 1);
		}
		ret = setfscreatecon (passwd_context);
		freecon (passwd_context);
		if (0 != ret) {
			vipwexit (_("setfscreatecon () failed"), errno, 1);
		}
	}
#endif				/* WITH_SELINUX */
#ifdef WITH_TCB
	if (tcb_mode && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) {
		vipwexit (_("failed to gain privileges"), errno, 1);
	}
#endif				/* WITH_TCB */
	if (file_lock () == 0) {
		vipwexit (_("Couldn't lock file"), errno, 5);
	}
	filelocked = true;
#ifdef WITH_TCB
	if (tcb_mode && (shadowtcb_drop_priv () == SHADOWTCB_FAILURE)) {
		vipwexit (_("failed to drop privileges"), errno, 1);
	}
#endif				/* WITH_TCB */

	/* edited copy has same owners, perm */
	if (stat (file, &st1) != 0) {
		vipwexit (file, 1, 1);
	}
	f = fopen (file, "r");
	if (NULL == f) {
		vipwexit (file, 1, 1);
	}
#ifdef WITH_TCB
	if (tcb_mode && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE))
		vipwexit (_("failed to gain privileges"), errno, 1);
#endif				/* WITH_TCB */
	if (create_backup_file (f, fileedit, &st1) != 0) {
		vipwexit (_("Couldn't make backup"), errno, 1);
	}
	(void) fclose (f);
	createedit = true;

	editor = getenv ("VISUAL");
	if (NULL == editor) {
		editor = getenv ("EDITOR");
	}
	if (NULL == editor) {
		editor = DEFAULT_EDITOR;
	}

	pid = fork ();
	if (-1 == pid) {
		vipwexit ("fork", 1, 1);
	} else if (0 == pid) {
		/* use the system() call to invoke the editor so that it accepts
		   command line args in the EDITOR and VISUAL environment vars */
		char *buf;

		buf = (char *) malloc (strlen (editor) + strlen (fileedit) + 2);
		snprintf (buf, strlen (editor) + strlen (fileedit) + 2,
			  "%s %s", editor, fileedit);
		if (system (buf) != 0) {
			fprintf (stderr, "%s: %s: %s\n", progname, editor,
			         strerror (errno));
			exit (1);
		} else {
			exit (0);
		}
	}

	for (;;) {
		pid = waitpid (pid, &status, WUNTRACED);
		if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
			/* The child (editor) was suspended.
			 * Suspend vipw. */
			kill (getpid (), SIGSTOP);
			/* wake child when resumed */
			kill (pid, SIGCONT);
		} else {
			break;
		}
	}

	if (   (-1 == pid)
	    || (WIFEXITED (status) == 0)
	    || (WEXITSTATUS (status) != 0)) {
		vipwexit (editor, 1, 1);
	}

	if (stat (fileedit, &st2) != 0) {
		vipwexit (fileedit, 1, 1);
	}
	if (st1.st_mtime == st2.st_mtime) {
		vipwexit (0, 0, 0);
	}
#ifdef WITH_SELINUX
	/* unset the fscreatecon */
	if (is_selinux_enabled () != 0) {
		if (setfscreatecon (NULL) != 0) {
			vipwexit (_("setfscreatecon () failed"), errno, 1);
		}
	}
#endif				/* WITH_SELINUX */

	/*
	 * XXX - here we should check fileedit for errors; if there are any,
	 * ask the user what to do (edit again, save changes anyway, or quit
	 * without saving). Use pwck or grpck to do the check.  --marekm
	 */
	createedit = false;
#ifdef WITH_TCB
	if (tcb_mode) {
		f = fopen (fileedit, "r");
		if (NULL == f) {
			vipwexit (_("failed to open scratch file"), errno, 1);
		}
		if (unlink (fileedit) != 0) {
			vipwexit (_("failed to unlink scratch file"), errno, 1);
		}
		if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
			vipwexit (_("failed to drop privileges"), errno, 1);
		}
		if (stat (file, &st1) != 0) {
			vipwexit (_("failed to stat edited file"), errno, 1);
		}
		to_rename = malloc (strlen (file) + 2);
		if (NULL == 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) != 0) {
			free (to_rename);
			vipwexit (_("failed to create backup file"), errno, 1);
		}
		(void) fclose (f);
	} else {
#endif				/* WITH_TCB */
		to_rename = fileedit;
#ifdef WITH_TCB
	}
#endif				/* WITH_TCB */
	unlink (filebackup);
	link (file, filebackup);
	if (rename (to_rename, file) == -1) {
		fprintf (stderr,
		         _("%s: can't restore %s: %s (your changes are in %s)\n"),
		         progname, file, strerror (errno), to_rename);
#ifdef WITH_TCB
		if (tcb_mode) {
			free (to_rename);
		}
#endif				/* WITH_TCB */
		vipwexit (0, 0, 1);
	}

#ifdef WITH_TCB
	if (tcb_mode) {
		free (to_rename);
		if (shadowtcb_gain_priv () == SHADOWTCB_FAILURE) {
			vipwexit (_("failed to gain privileges"), errno, 1);
		}
	}
#endif				/* WITH_TCB */

	if ((*file_unlock) () == 0) {
		fprintf (stderr, _("%s: failed to unlock %s\n"), progname, fileeditname);
		SYSLOG ((LOG_ERR, "failed to unlock %s", fileeditname));
		/* continue */
	}
	SYSLOG ((LOG_INFO, "file %s edited", fileeditname));
}