Exemple #1
0
/*
 * Output the /etc/motd file.
 *
 * It determines the name of a login announcement file and outputs it to the
 * user's terminal at login time.  The MOTD_FILE configuration option is a
 * colon-delimited list of filenames.  An empty MOTD_FILE option disables
 * message-of-the-day printing completely.
 */
static void motd(void)
{
	char *motdlist, *motdfile;
	const char *mb;

	mb = getlogindefs_str("MOTD_FILE", _PATH_MOTDFILE);
	if (!mb || !*mb)
		return;

	motdlist = xstrdup(mb);

	for (motdfile = strtok(motdlist, ":"); motdfile;
	     motdfile = strtok(NULL, ":")) {

		struct stat st;
		int fd;

		fd = open(motdfile, O_RDONLY, 0);
		if (fd < 0)
			continue;
		if (!fstat(fd, &st) && st.st_size)
			sendfile(fileno(stdout), fd, NULL, st.st_size);
		close(fd);
	}

	free(motdlist);
}
Exemple #2
0
static void chown_tty(struct login_context *cxt)
{
	const char *grname;
	uid_t uid = cxt->pwd->pw_uid;
	gid_t gid = cxt->pwd->pw_gid;

	grname = getlogindefs_str("TTYGROUP", TTYGRPNAME);
	if (grname && *grname) {
		struct group *gr = getgrnam(grname);
		if (gr)	/* group by name */
			gid = gr->gr_gid;
		else	/* group by ID */
			gid = (gid_t) getlogindefs_num("TTYGROUP", gid);
	}
	if (fchown(0, uid, gid))				/* tty */
		chown_err(cxt->tty_name, uid, gid);
	if (fchmod(0, cxt->tty_mode))
		chmod_err(cxt->tty_name, cxt->tty_mode);

#ifdef LOGIN_CHOWN_VCS
	if (is_consoletty(0)) {
		if (chown(cxt->vcsn, uid, gid))			/* vcs */
			chown_err(cxt->vcsn, uid, gid);
		if (chmod(cxt->vcsn, cxt->tty_mode))
			chmod_err(cxt->vcsn, cxt->tty_mode);

		if (chown(cxt->vcsan, uid, gid))		/* vcsa */
			chown_err(cxt->vcsan, uid, gid);
		if (chmod(cxt->vcsan, cxt->tty_mode))
			chmod_err(cxt->vcsan, cxt->tty_mode);
	}
#endif
}
Exemple #3
0
/*
 * Check per accout or global hush-login setting.
 *
 * Hushed mode is enabled:
 *
 * a) if global (e.g. /etc/hushlogins) hush file exists:
 *     1) for ALL ACCOUNTS if the file is empty
 *     2) for the current user if the username or shell are found in the file
 *
 * b) if ~/.hushlogin file exists
 *
 * The ~/.hushlogin is ignored if the global hush file exists.
 *
 * The HUSHLOGIN_FILE login.def variable overwrites the default hush filename.
 *
 * Note that shadow-utils login(1) does not support "a1)". The "a1)" is
 * necessary if you want to use PAM for "Last login" message.
 *
 * -- Karel Zak <*****@*****.**> (26-Aug-2011)
 *
 *
 * Per-account check requires some explanation: As root we may not be able to
 * read the directory of the user if it is on an NFS mounted filesystem. We
 * temporarily set our effective uid to the user-uid making sure that we keep
 * root privs. in the real uid.
 *
 * A portable solution would require a fork(), but we rely on Linux having the
 * BSD setreuid()
 */
static int get_hushlogin_status(struct passwd *pwd)
{
	const char *files[] = { _PATH_HUSHLOGINS, _PATH_HUSHLOGIN, NULL };
	const char *file;
	char buf[BUFSIZ];
	int i;

	file = getlogindefs_str("HUSHLOGIN_FILE", NULL);
	if (file) {
		if (!*file)
			return 0;	/* empty HUSHLOGIN_FILE defined */

		files[0] = file;
		files[1] = NULL;
	}

	for (i = 0; files[i]; i++) {
		int ok = 0;

		file = files[i];

		/* Global hush-file*/
		if (*file == '/') {
			struct stat st;
			FILE *f;

			if (stat(file, &st) != 0)
				continue;	/* file does not exist */

			if (st.st_size == 0)
				return 1;	/* for all accounts */

			f = fopen(file, "r");
			if (!f)
				continue;	/* ignore errors... */

			while (ok == 0 && fgets(buf, sizeof(buf), f)) {
				buf[strlen(buf) - 1] = '\0';
				ok = !strcmp(buf, *buf == '/' ? pwd->pw_shell :
								pwd->pw_name);
			}
			fclose(f);
			if (ok)
				return 1;	/* found username/shell */

			return 0;		/* ignore per-account files */
		}

		/* Per-account setting */
		if (strlen(pwd->pw_dir) + sizeof(file) + 2 > sizeof(buf))
			continue;
		else {
			uid_t ruid = getuid();
			gid_t egid = getegid();

			sprintf(buf, "%s/%s", pwd->pw_dir, file);
			setregid(-1, pwd->pw_gid);
			setreuid(0, pwd->pw_uid);
			ok = effective_access(buf, O_RDONLY) == 0;
			setuid(0);	/* setreuid doesn't do it alone! */
			setreuid(ruid, 0);
			setregid(-1, egid);

			if (ok)
				return 1;	/* enabled by user */
		}
	}

	return 0;
}