static int
lua_set_acllist(lua_State *L, void *wl, lua_cmd_t *cmd, char *buf)
{
	struct maclist *maclist = (struct maclist *) buf;
	struct ether_addr *ea;
	uint max = (WLC_IOCTL_MAXLEN - sizeof(int)) / ETHER_ADDR_LEN;
	char *nargv[128];
	char **argv;
	uint len;

	cmd_split(buf, (char **)nargv, 128);
	argv = (char **)nargv;

	/* Clear list */
	maclist->count = htod32(0);
	ea = maclist->ea;
	while (*argv && maclist->count < max)
	{
		if (!wl_ether_atoe(*argv, ea))
		{
			return -1;
		}
		maclist->count++;
		ea++;
		argv++;
	}

	/* Set new list */
	len = sizeof(maclist->count) + maclist->count * sizeof(maclist->ea);
	maclist->count = htod32(maclist->count);
	return wlu_set(wl, WLC_SET_MACLIST, maclist, len);
}
Exemplo n.º 2
0
static int start_child_process(const char* cmd) {
	int pid, in[2], out[2], err[2];
	char** params = cmd_split(cmd);

	pipe(in);
	pipe(out);
	pipe(err);

	signal(SIGCHLD, SIG_DFL);

	pid = fork();
	switch(pid) {
		case 0:
			/* child process */
			close(0);
			dup(in[0]);
			close(in[0]);
			close(in[1]);

			close(1);
			dup(out[1]);
			close(out[0]);
			close(out[1]);

			close(2);
			dup(err[1]);
			close(err[0]);
			close(err[1]);

			errno = 0;

			/* start it */
			execvp(params[0], params);

			/* some programs use value 2 (tar) */
			if(errno == 2)
				_exit(199);
			else
				_exit(errno);
			break;
		case -1:
			E_WARNING(E_STRLOC ": fork() failed\n");
			/* close the pipes */
			close(in[0]);
			close(in[1]);

			close(out[0]);
			close(out[1]);

			close(err[0]);
			close(err[1]);
			break;
		default:
			/* parent */
			close(in[0]);
			close(out[1]);
			close(err[1]);
			break;
	}

	/* cleanup when returns from the child */
	for(int i = 0; params[i]; i++)
		free(params[i]);
	free(params);

	int status = 0, ret = 1;
	errno = 0;
	if(waitpid(pid, &status, 0) < 0) {
		E_WARNING(E_STRLOC ": waitpid() failed with '%s'\n", strerror(errno));
		return 1;
	}

	if(WIFEXITED(status)) {
		ret = WEXITSTATUS(status);
	} else if(WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
		start_crasher(cmd, SIGSEGV);
	} else {
		E_WARNING(E_STRLOC ": child '%s' killed\n", cmd);
	}

	return ret;
}
Exemplo n.º 3
0
static void exec_cmd(const char* cmd, int child_err_report_fd) {
	/* let it be closed on exec */
	if(child_err_report_fd != -1)
		fcntl(child_err_report_fd, F_SETFD, FD_CLOEXEC); 

	int errnosv, count = 0;
	char** args = cmd_split(cmd, &count);

	if(!args) {
		errnosv = ENOMEM;

		if(child_err_report_fd != -1) {
			/* report it to the pipe if it was used*/
			write_int(child_err_report_fd, RUN_EXECVE_FAILED);
			write_int(child_err_report_fd, errnosv);
			_exit(1);
		} else {
			/* or directly if wasn't */
			_exit(errnosv);
		}
	}

	/* see if it has a path component in itself */
	if(strchr(args[0], '/') != NULL) {
		execv(args[0], args);

		/* execute it then via shell if failed */
		if(errno == ENOEXEC)
			exec_cmd_via_shell(args[0], args, count);
	} else {
		/*
		 * search PATH then; here will not be used file_path() or similar checker
		 * but execve() will be directly called on each path component and if failed,
		 * it will go to the next available
		 */
		char name[PATH_MAX], *path, *path_copy;
		
		path = getenv("PATH");
		if(!path) {
			/* in glib was stated that '.' is put last for security so I'm using that here too */
			path = (char*)"/bin:/usr/bin:.";
		}

		path_copy = strdup(path);

		if(path_copy) {
			for(char* t = strtok(path_copy, ":"); t; t = strtok(NULL, ":")) {
				snprintf(name, sizeof(name), "%s/%s", t, args[0]);

				/* execute it */
				execv(name, args);

				/* or try with shell instead */
				if(errno == ENOEXEC)
					exec_cmd_via_shell(name, args, count);

				/* these indicates that current entry wasn't found; go to the next */
				if(errno == EACCES || errno == ENOENT || errno == ENOTDIR)
					continue;

				/* if we got here, it means it is bad; break it and let errno be reported via pipe */
				errnosv = errno;
				break;
			}

			free(path_copy);
		}
	}

	/* quickly save it before any further stdlib calls */
	errnosv = errno;

	/* got here; everything failed so report it then */
	for(int i = 0; args[i]; i++)
		free(args[i]);
	free(args);

	if(child_err_report_fd != -1) {
		/* report for async code */
		write_int(child_err_report_fd, RUN_EXECVE_FAILED);
		write_int(child_err_report_fd, errnosv);
		_exit(1);
	} else {
		/* report for sync code */
		_exit(errnosv);
	}
}