mirror of https://github.com/pekman/netns-exec
Initial commit
commit
9f2939b482
@ -0,0 +1,2 @@
|
||||
/*.o
|
||||
/netns-exec
|
@ -0,0 +1,3 @@
|
||||
[submodule "iproute2"]
|
||||
path = iproute2
|
||||
url = git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
|
@ -0,0 +1,48 @@
|
||||
PREFIX = /usr/local
|
||||
EXEC_PREFIX = $(PREFIX)
|
||||
BINDIR = $(EXEC_PREFIX)/bin
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -Wall
|
||||
PROG = netns-exec
|
||||
|
||||
IPROUTE2_DIR = iproute2
|
||||
IPROUTE2_OBJS = namespace.o
|
||||
IPROUTE2_OBJS_FULL = $(addprefix $(IPROUTE2_DIR)/lib/, $(IPROUTE2_OBJS))
|
||||
IPROUTE2_INCLUDES = -iquote $(IPROUTE2_DIR)/include
|
||||
IPROUTE2_CFLAGS = $(CFLAGS)
|
||||
|
||||
CPPFLAGS += $(IPROUTE2_INCLUDES)
|
||||
|
||||
OBJS = $(PROG).o $(IPROUTE2_OBJS_FULL)
|
||||
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
|
||||
install: $(PROG)
|
||||
install -D -m4755 -t$(BINDIR) $(PROG)
|
||||
|
||||
uninstall:
|
||||
rm -fv $(BINDIR)/$(PROG)
|
||||
|
||||
localclean:
|
||||
rm -fv $(PROG) $(PROG).o
|
||||
|
||||
clean: localclean
|
||||
$(MAKE) clean -C $(IPROUTE2_DIR)
|
||||
|
||||
distclean: localclean
|
||||
$(MAKE) distclean -C $(IPROUTE2_DIR)
|
||||
|
||||
|
||||
# rule for building files in iproute2 subdirectory:
|
||||
# (This is a bit of a hack. Set some variables to make iproute2's
|
||||
# Makefile only build what we need and set all needed options.)
|
||||
$(IPROUTE2_OBJS_FULL):
|
||||
$(MAKE) -C $(IPROUTE2_DIR) \
|
||||
SUBDIRS='lib' MFLAGS='$(IPROUTE2_OBJS)' \
|
||||
EXTRA_CFLAGS='$(IPROUTE2_CFLAGS)'
|
||||
|
||||
MAKEOVERRIDES := $(filter-out CFLAGS=% CPPFLAGS=%,$(MAKEOVERRIDES))
|
@ -0,0 +1 @@
|
||||
Subproject commit ead954cbd40a2a9e3756d2010c6bfb1d80c340ed
|
@ -0,0 +1,102 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "namespace.h"
|
||||
|
||||
|
||||
#define EXIT_INVALID_ARGS 2
|
||||
#define EXIT_NOT_FOUND 127
|
||||
#define EXIT_CANNOT_EXEC 126
|
||||
#define EXIT_OTHER_ERROR 125
|
||||
|
||||
|
||||
static void usage(const char *argv0, bool is_error)
|
||||
{
|
||||
fprintf(
|
||||
stderr,
|
||||
"\n"
|
||||
"usage:\n"
|
||||
"\n"
|
||||
"run command in netns:\n"
|
||||
" %1$s [-h | --help] [--] <netns> <command> [<args> ...]\n"
|
||||
"\n"
|
||||
"run shell in netns:\n"
|
||||
" %1$s [-h | --help] [--] <netns>\n"
|
||||
"\n",
|
||||
argv0);
|
||||
|
||||
exit(is_error ? EXIT_INVALID_ARGS : 0);
|
||||
}
|
||||
|
||||
|
||||
static void drop_root_privileges(void)
|
||||
{
|
||||
if (setuid(getuid()) < 0) {
|
||||
perror("error setting user id");
|
||||
exit(EXIT_OTHER_ERROR);
|
||||
}
|
||||
if (setgid(getgid()) < 0) {
|
||||
perror("error setting group id");
|
||||
exit(EXIT_OTHER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// parse arguments
|
||||
if (argc < 2 || (argc == 2 && strcmp(argv[1], "--") == 0))
|
||||
// no netns given
|
||||
usage(argv[0], true);
|
||||
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)
|
||||
usage(argv[0], false);
|
||||
|
||||
if (strcmp(argv[1], "--") == 0) {
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
else if (argv[1][0] == '-') {
|
||||
// invalid command line option
|
||||
fprintf(stderr, "Unknown option: %s\n", argv[1]);
|
||||
usage(argv[0], true);
|
||||
}
|
||||
|
||||
|
||||
// switch network namespace using iproute2's function
|
||||
if (netns_switch(argv[1]) < 0)
|
||||
return EXIT_OTHER_ERROR;
|
||||
|
||||
|
||||
drop_root_privileges();
|
||||
|
||||
|
||||
char **command_argv;
|
||||
|
||||
// if no command given, start shell
|
||||
if (argc == 2) {
|
||||
static char *shell_argv[] = { "/bin/sh", NULL };
|
||||
char *shell = getenv("SHELL");
|
||||
if (shell != NULL)
|
||||
shell_argv[0] = shell;
|
||||
command_argv = shell_argv;
|
||||
}
|
||||
else {
|
||||
command_argv = &argv[2];
|
||||
}
|
||||
|
||||
|
||||
// execute the command
|
||||
execvp(command_argv[0], command_argv);
|
||||
|
||||
fprintf(stderr, "error executing \"%s\": %s",
|
||||
command_argv[0], strerror(errno));
|
||||
if (errno == ENOENT)
|
||||
return EXIT_NOT_FOUND;
|
||||
else
|
||||
return EXIT_CANNOT_EXEC;
|
||||
}
|
Loading…
Reference in New Issue