Example #1
0
int mkdir_main(int argc, char **argv)
{
	mode_t mode = (mode_t)(-1);
	int status = EXIT_SUCCESS;
	int flags = 0;
	unsigned opt;
	char *smode;
#if ENABLE_SELINUX
	security_context_t scontext;
#endif

#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
	applet_long_options = mkdir_longopts;
#endif
	opt = getopt32(argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
	if (opt & 1) {
		mode = 0777;
		if (!bb_parse_mode(smode, &mode)) {
			bb_error_msg_and_die("invalid mode '%s'", smode);
		}
	}
	if (opt & 2)
		flags |= FILEUTILS_RECUR;
#if ENABLE_SELINUX
	if (opt & 4) {
		selinux_or_die();
		setfscreatecon_or_die(scontext);
	}
#endif

	if (optind == argc) {
		bb_show_usage();
	}

	argv += optind;

	do {
		if (bb_make_directory(*argv, mode, flags)) {
			status = EXIT_FAILURE;
		}
	} while (*++argv);

	return status;
}
Example #2
0
mode_t getopt_mk_fifo_nod(int argc, char **argv)
{
	mode_t mode = 0666;
	char *smode = NULL;
#if ENABLE_SELINUX
	security_context_t scontext;
#endif
	int opt;
	opt = getopt32(argc, argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext));
	if (opt & 1) {
		if (bb_parse_mode(smode, &mode))
			umask(0);
	}

#if ENABLE_SELINUX
	if (opt & 2) {
		selinux_or_die();
		setfscreatecon_or_die(scontext);
	}
#endif

	return mode;
}
Example #3
0
int sulogin_main(int argc, char **argv)
{
	char *cp;
	int timeout = 0;
	char *timeout_arg;
	const char * const *p;
	struct passwd *pwd;
	const char *shell;
#if ENABLE_FEATURE_SHADOWPASSWDS
	/* Using _r function to avoid pulling in static buffers */
	char buffer[256];
	struct spwd spw;
	struct spwd *result;
#endif

	logmode = LOGMODE_BOTH;
	openlog(applet_name, 0, LOG_AUTH);

	if (getopt32(argc, argv, "t:", &timeout_arg)) {
		timeout = xatoi_u(timeout_arg);
	}

	if (argv[optind]) {
		close(0);
		close(1);
		dup(xopen(argv[optind], O_RDWR));
		close(2);
		dup(0);
	}

	if (!isatty(0) || !isatty(1) || !isatty(2)) {
		logmode = LOGMODE_SYSLOG;
		bb_error_msg_and_die("not a tty");
	}

	/* Clear out anything dangerous from the environment */
	for (p = forbid; *p; p++)
		unsetenv(*p);

	signal(SIGALRM, catchalarm);

	pwd = getpwuid(0);
	if (!pwd) {
		goto auth_error;
	}

#if ENABLE_FEATURE_SHADOWPASSWDS
	if (getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result)) {
		goto auth_error;
	}
	pwd->pw_passwd = spw.sp_pwdp;
#endif

	while (1) {
		/* cp points to a static buffer that is zeroed every time */
		cp = bb_askpass(timeout,
				"Give root password for system maintenance\n"
				"(or type Control-D for normal startup):");

		if (!cp || !*cp) {
			bb_info_msg("Normal startup");
			return 0;
		}
		if (strcmp(pw_encrypt(cp, pwd->pw_passwd), pwd->pw_passwd) == 0) {
			break;
		}
		bb_do_delay(FAIL_DELAY);
		bb_error_msg("login incorrect");
	}
	memset(cp, 0, strlen(cp));
	signal(SIGALRM, SIG_DFL);

	bb_info_msg("System Maintenance Mode");

	USE_SELINUX(renew_current_security_context());

	shell = getenv("SUSHELL");
	if (!shell) shell = getenv("sushell");
	if (!shell) {
		shell = "/bin/sh";
		if (pwd->pw_shell[0])
			shell = pwd->pw_shell;
	}
	run_shell(shell, 1, 0, 0);
	/* never returns */

auth_error:
	bb_error_msg_and_die("no password entry for 'root'");
}
Example #4
0
int id_main(int argc UNUSED_PARAM, char **argv)
{
	uid_t ruid;
	gid_t rgid;
	uid_t euid;
	gid_t egid;
	unsigned opt;
	int i;
	int status = EXIT_SUCCESS;
	const char *prefix;
	const char *username;
#if ENABLE_SELINUX
	security_context_t scontext = NULL;
#endif
	/* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
	/* Don't allow more than one username */
	opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
			 USE_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G");
	opt = getopt32(argv, "rnugG" USE_SELINUX("Z"));

	username = argv[optind];
	if (username) {
		struct passwd *p = xgetpwnam(username);
		euid = ruid = p->pw_uid;
		egid = rgid = p->pw_gid;
	} else {
		egid = getegid();
		rgid = getgid();
		euid = geteuid();
		ruid = getuid();
	}
	/* JUST_ALL_GROUPS ignores -r PRINT_REAL flag even if man page for */
	/* id says: print the real ID instead of the effective ID, with -ugG */
	/* in fact in this case egid is always printed if egid != rgid */
	if (!opt || (opt & JUST_ALL_GROUPS)) {
		gid_t *groups;
		int n;

		if (!opt) {
			/* Default Mode */
			status |= print_user(ruid, "uid=");
			status |= print_group(rgid, " gid=");
			if (euid != ruid)
				status |= print_user(euid, " euid=");
			if (egid != rgid)
				status |= print_group(egid, " egid=");
		} else {
			/* JUST_ALL_GROUPS */
			status |= print_group(rgid, NULL);
			if (egid != rgid)
				status |= print_group(egid, " ");
		}
		/* We are supplying largish buffer, trying
		 * to not run get_groups() twice. That might be slow
		 * ("user database in remote SQL server" case) */
		groups = xmalloc(64 * sizeof(gid_t));
		n = 64;
		if (get_groups(username, rgid, groups, &n) < 0) {
			/* Need bigger buffer after all */
			groups = xrealloc(groups, n * sizeof(gid_t));
			get_groups(username, rgid, groups, &n);
		}
		if (n > 0) {
			/* Print the list */
			prefix = " groups=";
			for (i = 0; i < n; i++) {
				if (opt && (groups[i] == rgid || groups[i] == egid))
					continue;
				status |= print_group(groups[i], opt ? " " : prefix);
				prefix = ",";
			}
		} else if (n < 0) { /* error in get_groups() */
			if (!ENABLE_DESKTOP)
				bb_error_msg_and_die("cannot get groups");
			else
				return EXIT_FAILURE;
		}
		if (ENABLE_FEATURE_CLEAN_UP)
			free(groups);
#if ENABLE_SELINUX
		if (is_selinux_enabled()) {
			if (getcon(&scontext) == 0)
				printf(" context=%s", scontext);
		}
#endif
	} else if (opt & PRINT_REAL) {
		euid = ruid;
		egid = rgid;
	}

	if (opt & JUST_USER)
		status |= print_user(euid, NULL);
	else if (opt & JUST_GROUP)
		status |= print_group(egid, NULL);
#if ENABLE_SELINUX
	else if (opt & JUST_CONTEXT) {
		selinux_or_die();
		if (username || getcon(&scontext)) {
			bb_error_msg_and_die("can't get process context%s",
				username ? " for a different user" : "");
		}
		fputs(scontext, stdout);
	}
	/* freecon(NULL) seems to be harmless */
	if (ENABLE_FEATURE_CLEAN_UP)
		freecon(scontext);
#endif
	bb_putchar('\n');
	fflush_stdout_and_exit(status);
}
Example #5
0
int netstat_main(int argc, char **argv)
{
	int opt;
	int new_flags=0;
	int showroute = 0, extended = 0;
#ifdef CONFIG_FEATURE_IPV6
	int inet=1;
	int inet6=1;
#else
# define inet 1
# define inet6 0
#endif
	while ((opt = getopt(argc, argv, "laenrtuwx" USE_SELINUX("Z"))) != -1)
		switch (opt) {
		case 'l':
			flags &= ~NETSTAT_CONNECTED;
			flags |= NETSTAT_LISTENING;
			break;
		case 'a':
			flags |= NETSTAT_LISTENING | NETSTAT_CONNECTED;
			break;
		case 'n':
			flags |= NETSTAT_NUMERIC;
			break;
		case 'r':
			showroute = 1;
			break;
		case 'e':
			extended = 1;
			break;
		case 't':
			new_flags |= NETSTAT_TCP;
			break;
		case 'u':
			new_flags |= NETSTAT_UDP;
			break;
		case 'w':
			new_flags |= NETSTAT_RAW;
			break;
		case 'x':
			new_flags |= NETSTAT_UNIX;
			break;
#ifdef CONFIG_SELINUX
		case 'Z':
			if (!is_selinux_enabled())
				bb_error_msg_and_die("SELinux is not enabled on this machine.");
			flags |= NETSTAT_SELINUX;
			break;
#endif
		default:
			bb_show_usage();
		}
	if ( showroute ) {
#ifdef CONFIG_ROUTE
		displayroutes ( flags & NETSTAT_NUMERIC, !extended );
		return 0;
#else
		bb_error_msg_and_die( "-r (display routing table) is not compiled in." );
#endif
	}

	if (new_flags) {
		flags &= ~(NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW|NETSTAT_UNIX);
		flags |= new_flags;
	}
	if (flags&(NETSTAT_TCP|NETSTAT_UDP|NETSTAT_RAW)) {
		printf("Active Internet connections ");	/* xxx */

		if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))==(NETSTAT_LISTENING|NETSTAT_CONNECTED))
			printf("(servers and established)");
		else {
			if (flags&NETSTAT_LISTENING)
				printf("(only servers)");
			else
				printf("(w/o servers)");
		}
		printf("\nProto Recv-Q Send-Q Local Address           Foreign Address         State      \n");
	}
	if (inet && flags&NETSTAT_TCP)
		do_info(_PATH_PROCNET_TCP,"AF INET (tcp)",tcp_do_one);
#ifdef CONFIG_FEATURE_IPV6
	if (inet6 && flags&NETSTAT_TCP)
		do_info(_PATH_PROCNET_TCP6,"AF INET6 (tcp)",tcp_do_one);
#endif
	if (inet && flags&NETSTAT_UDP)
		do_info(_PATH_PROCNET_UDP,"AF INET (udp)",udp_do_one);
#ifdef CONFIG_FEATURE_IPV6
	if (inet6 && flags&NETSTAT_UDP)
		do_info(_PATH_PROCNET_UDP6,"AF INET6 (udp)",udp_do_one);
#endif
	if (inet && flags&NETSTAT_RAW)
		do_info(_PATH_PROCNET_RAW,"AF INET (raw)",raw_do_one);
#ifdef CONFIG_FEATURE_IPV6
	if (inet6 && flags&NETSTAT_RAW)
		do_info(_PATH_PROCNET_RAW6,"AF INET6 (raw)",raw_do_one);
#endif
	if (flags&NETSTAT_UNIX) {
		printf("Active UNIX domain sockets ");
		if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))==(NETSTAT_LISTENING|NETSTAT_CONNECTED))
			printf("(servers and established)");
		else {
			if (flags&NETSTAT_LISTENING)
				printf("(only servers)");
			else
				printf("(w/o servers)");
		}

		printf("\nProto RefCnt Flags       Type       State         I-Node ");
		if (flags & NETSTAT_SELINUX)
			printf("Security Context                  ");
		printf("Path\n");
		do_info(_PATH_PROCNET_UNIX,"AF UNIX",unix_do_one);
	}
	return 0;
}
Example #6
0
static void unix_do_one(int nr, const char *line)
{
	static int has = 0;
	char path[PATH_MAX], ss_flags[32];
	char *ss_proto, *ss_state, *ss_type;
	int num, state, type, inode;
	void *d;
	unsigned long refcnt, proto, unix_flags;
	USE_SELINUX(security_context_t unixcon = NULL);

	if (nr == 0) {
		if (strstr(line, "Inode"))
			has |= HAS_INODE;
		return;
	}
	path[0] = '\0';
	num = sscanf(line, "%p: %lX %lX %lX %X %X %d %s",
				 &d, &refcnt, &proto, &unix_flags, &type, &state, &inode, path);
	if (num < 6) {
		bb_error_msg("warning, got bogus unix line.");
		return;
	}
	if (!(has & HAS_INODE))
		snprintf(path,sizeof(path),"%d",inode);

	if ((flags&(NETSTAT_LISTENING|NETSTAT_CONNECTED))!=(NETSTAT_LISTENING|NETSTAT_CONNECTED)) {
		if ((state == SS_UNCONNECTED) && (unix_flags & SO_ACCEPTCON)) {
			if (!(flags&NETSTAT_LISTENING))
				return;
		} else {
			if (!(flags&NETSTAT_CONNECTED))
				return;
		}
	}

	switch (proto) {
		case 0:
			ss_proto = "unix";
			break;

		default:
			ss_proto = "??";
	}

	switch (type) {
		case SOCK_STREAM:
			ss_type = "STREAM";
			break;

		case SOCK_DGRAM:
			ss_type = "DGRAM";
			break;

		case SOCK_RAW:
			ss_type = "RAW";
			break;

		case SOCK_RDM:
			ss_type = "RDM";
			break;

		case SOCK_SEQPACKET:
			ss_type = "SEQPACKET";
			break;

		default:
			ss_type = "UNKNOWN";
	}

	switch (state) {
		case SS_FREE:
			ss_state = "FREE";
			break;

		case SS_UNCONNECTED:
			/*
			 * Unconnected sockets may be listening
			 * for something.
			 */
			if (unix_flags & SO_ACCEPTCON) {
				ss_state = "LISTENING";
			} else {
				ss_state = "";
			}
			break;

		case SS_CONNECTING:
			ss_state = "CONNECTING";
			break;

		case SS_CONNECTED:
			ss_state = "CONNECTED";
			break;

		case SS_DISCONNECTING:
			ss_state = "DISCONNECTING";
			break;

		default:
			ss_state = "UNKNOWN";
	}

	strcpy(ss_flags, "[ ");
	if (unix_flags & SO_ACCEPTCON)
		strcat(ss_flags, "ACC ");
	if (unix_flags & SO_WAITDATA)
		strcat(ss_flags, "W ");
	if (unix_flags & SO_NOSPACE)
		strcat(ss_flags, "N ");

	strcat(ss_flags, "]");

#ifdef CONFIG_SELINUX
	if ((flags & NETSTAT_SELINUX) && is_selinux_enabled()) {
		if (lgetfilecon(path, &unixcon) < 0)
			unixcon = NULL;
	}
#endif
	printf("%-5s %-6ld %-11s %-10s %-13s ",
		   ss_proto, refcnt, ss_flags, ss_type, ss_state);
	if (has & HAS_INODE)
		printf("%-6d ",inode);
	else
		printf("-      ");
#ifdef CONFIG_SELINUX
	if (flags & NETSTAT_SELINUX) {
		printf("%-32s  ", unixcon ? unixcon : "-");
		if (unixcon)
			freecon(unixcon);
	}
#endif
	puts(path);
}
Example #7
0
int sulogin_main(int argc UNUSED_PARAM, char **argv)
{
	char *cp;
	int timeout = 0;
	struct passwd *pwd;
	const char *shell;
#if ENABLE_FEATURE_SHADOWPASSWDS
	/* Using _r function to avoid pulling in static buffers */
	char buffer[256];
	struct spwd spw;
#endif

	logmode = LOGMODE_BOTH;
	openlog(applet_name, 0, LOG_AUTH);

	opt_complementary = "t+"; /* -t N */
	getopt32(argv, "t:", &timeout);

	if (argv[optind]) {
		close(0);
		close(1);
		dup(xopen(argv[optind], O_RDWR));
		close(2);
		dup(0);
	}

	/* Malicious use like "sulogin /dev/sda"? */
	if (!isatty(0) || !isatty(1) || !isatty(2)) {
		logmode = LOGMODE_SYSLOG;
		bb_error_msg_and_die("not a tty");
	}

	/* Clear dangerous stuff, set PATH */
	sanitize_env_if_suid();

// bb_askpass() already handles this
//	signal(SIGALRM, catchalarm);

	pwd = getpwuid(0);
	if (!pwd) {
		goto auth_error;
	}

#if ENABLE_FEATURE_SHADOWPASSWDS
	{
		/* getspnam_r may return 0 yet set result to NULL.
		 * At least glibc 2.4 does this. Be extra paranoid here. */
		struct spwd *result = NULL;
		int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result);
		if (r || !result) {
			goto auth_error;
		}
		pwd->pw_passwd = result->sp_pwdp;
	}
#endif

	while (1) {
		char *encrypted;
		int r;

		/* cp points to a static buffer that is zeroed every time */
		cp = bb_askpass(timeout,
				"Give root password for system maintenance\n"
				"(or type Control-D for normal startup):");

		if (!cp || !*cp) {
			bb_info_msg("Normal startup");
			return 0;
		}
		encrypted = pw_encrypt(cp, pwd->pw_passwd, 1);
		r = strcmp(encrypted, pwd->pw_passwd);
		free(encrypted);
		if (r == 0) {
			break;
		}
		bb_do_delay(FAIL_DELAY);
		bb_error_msg("login incorrect");
	}
	memset(cp, 0, strlen(cp));
//	signal(SIGALRM, SIG_DFL);

	bb_info_msg("System Maintenance Mode");

	USE_SELINUX(renew_current_security_context());

	shell = getenv("SUSHELL");
	if (!shell)
		shell = getenv("sushell");
	if (!shell) {
		shell = "/bin/sh";
		if (pwd->pw_shell[0])
			shell = pwd->pw_shell;
	}
	/* Exec login shell with no additional parameters. Never returns. */
	run_shell(shell, 1, NULL, NULL);

 auth_error:
	bb_error_msg_and_die("no password entry for root");
}