コード例 #1
0
ファイル: mgt_jail.c プロジェクト: biddyweb/Varnish-Cache
void
VJ_Init(const char *j_arg)
{
	char **av;
	int i;

	if (j_arg != NULL) {
		av = VAV_Parse(j_arg, NULL, ARGV_COMMA);
		AN(av);
		if (av[0] != NULL)
			ARGV_ERR("-j argument: %s\n", av[0]);
		if (av[1] == NULL)
			ARGV_ERR("-j argument is emtpy\n");
		vjt = pick(vj_choice, av[1], "jail");
		CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
		(void)vjt->init(av + 2);
		VAV_Free(av);
	} else {
		/*
		 * Go through list of jail technologies until one
		 * succeeds, falling back to "none".
		 */
		for (i = 0; vj_choice[i].name != NULL; i++) {
			vjt = vj_choice[i].ptr;
			CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
			if (!vjt->init(NULL))
				break;
		}
	}
	VSB_printf(vident, ",-j%s", vjt->name);
}
コード例 #2
0
ファイル: mgt_jail.c プロジェクト: biddyweb/Varnish-Cache
void
VJ_make_workdir(const char *dname)
{
	int fd;

	AN(dname);
	CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
	if (vjt->make_workdir != NULL) {
		vjt->make_workdir(dname);
		return;
	}

	if (mkdir(dname, 0755) < 0 && errno != EEXIST)
		ARGV_ERR("Cannot create working directory '%s': %s\n",
		    dname, strerror(errno));

	if (chdir(dname) < 0)
		ARGV_ERR("Cannot change to working directory '%s': %s\n",
		    dname, strerror(errno));

	fd = open("_.testfile", O_RDWR|O_CREAT|O_EXCL, 0600);
	if (fd < 0)
		ARGV_ERR("Error: Cannot create test-file in %s (%s)\n"
		    "Check permissions (or delete old directory)\n",
		    dname, strerror(errno));
	AZ(close(fd));
	AZ(unlink("_.testfile"));
}
コード例 #3
0
static void
sma_init(struct stevedore *parent, int ac, char * const *av)
{
	const char *e;
	uintmax_t u;
	struct sma_sc *sc;

	ASSERT_MGT();
	ALLOC_OBJ(sc, SMA_SC_MAGIC);
	AN(sc);
	sc->sma_max = SIZE_MAX;
	assert(sc->sma_max == SIZE_MAX);
	parent->priv = sc;

	AZ(av[ac]);
	if (ac > 1)
		ARGV_ERR("(-smalloc) too many arguments\n");

	if (ac == 0 || *av[0] == '\0')
		 return;

	e = str2bytes(av[0], &u, 0);
	if (e != NULL)
		ARGV_ERR("(-smalloc) size \"%s\": %s\n", av[0], e);
	if ((u != (uintmax_t)(size_t)u))
		ARGV_ERR("(-smalloc) size \"%s\": too big\n", av[0]);
	if (u < 1024*1024)
		ARGV_ERR("(-smalloc) size \"%s\": too small, "
			 "did you forget to specify M or G?\n", av[0]);

	sc->sma_max = u;
}
コード例 #4
0
void
mgt_sandbox_init(void)
{
	struct passwd *pwd;
	struct group *grp;
	struct vsb *sb;
	unsigned subs;

	/* Pick a sandbox */

#ifdef HAVE_SETPPRIV
	mgt_sandbox = mgt_sandbox_solaris;
#else
	mgt_sandbox = mgt_sandbox_unix;
#endif

	/* Test it */

	sb = VSB_new_auto();
	subs = VSUB_run(sb, run_sandbox_test, NULL, "SANDBOX-test", 10);
	VSB_delete(sb);
	if (subs) {
		MGT_complain(C_SECURITY,
		    "Platform-specific sandbox failed - sandboxing disabled");
		MGT_complain(C_SECURITY,
		    "Varnish runs with elevated privileges");
		mgt_sandbox = mgt_sandbox_null;
	}

	MCF_AddParams(mgt_parspec_sandbox);

	/*
	 * If we have nobody/nogroup, use them as defaults for sandboxes,
	 * else fall back to whoever we run as.
	 */
	if (getpwnam("nobody") != NULL) {
		MCF_SetDefault("user", "nobody");
	} else {
		pwd = getpwuid(getuid());
		if (pwd == NULL)
			ARGV_ERR("Neither user 'nobody' or my uid (%jd)"
			    " found in password database.\n",
			    (intmax_t)getuid());
		MCF_SetDefault("user", pwd->pw_name);
	}
	endpwent();

	if (getgrnam("nogroup") != NULL) {
		MCF_SetDefault("group", "nogroup");
	} else {
		grp = getgrgid(getgid());
		if (grp == NULL)
			ARGV_ERR("Neither group 'nogroup' or my gid (%jd)"
			    " found in password database.\n",
			    (intmax_t)getgid());
		MCF_SetDefault("group", grp->gr_name);
	}
	endgrent();
}
コード例 #5
0
ファイル: mgt_stevedore.c プロジェクト: ehocdet/varnish-cache
void
STV_Config(const char *spec)
{
	char **av, buf[8];
	const char *name;
	struct stevedore *stv;
	const struct stevedore *stv2;
	int ac;
	static unsigned seq = 0;

	av = MGT_NamedArg(spec, &name, "-s");
	AN(av);

	if (av[1] == NULL)
		ARGV_ERR("-s argument lacks strategy {malloc, file, ...}\n");

	for (ac = 0; av[ac + 2] != NULL; ac++)
		continue;

	stv2 = MGT_Pick(STV_choice, av[1], "storage");
	AN(stv2);

	/* Append strategy to ident string */
	VSB_printf(vident, ",-s%s", av[1]);

	av += 2;

	CHECK_OBJ_NOTNULL(stv2, STEVEDORE_MAGIC);
	ALLOC_OBJ(stv, STEVEDORE_MAGIC);
	AN(stv);

	*stv = *stv2;
	AN(stv->name);

	if (name == NULL) {
		bprintf(buf, "s%u", seq++);
		name = buf;
	}

	stv->ident = strdup(name);
	AN(stv->ident);
	stv_check_ident(spec, stv->ident);

	if (stv->init != NULL)
		stv->init(stv, ac, av);
	else if (ac != 0)
		ARGV_ERR("(-s %s) too many arguments\n", stv->name);

	AN(stv->allocobj);
	AN(stv->methods);

	if (!strcmp(stv->ident, TRANSIENT_STORAGE)) {
		AZ(stv_transient);
		stv_transient = stv;
	} else
		VTAILQ_INSERT_TAIL(&stevedores, stv, list);
	/* NB: Do not free av, stevedore gets to keep it */
}
コード例 #6
0
int
STV_GetFile(const char *fn, int *fdp, const char **fnp, const char *ctx)
{
	int fd;
	struct stat st;
	int retval = 1;
	char buf[FILENAME_MAX];

	AN(fn);
	AN(fnp);
	AN(fdp);
	*fnp = NULL;
	*fdp = -1;

	/* try to create a new file of this name */
	fd = open(fn, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, 0600);
	if (fd >= 0) {
		*fdp = fd;
		*fnp = fn;
		return (retval);
	}

	if (stat(fn, &st))
		ARGV_ERR(
		    "(%s) \"%s\" does not exist and could not be created\n",
		    ctx, fn);

	if (S_ISDIR(st.st_mode)) {
		bprintf(buf, "%s/varnish.XXXXXX", fn);
		fd = mkstemp(buf);
		if (fd < 0)
			ARGV_ERR("(%s) \"%s\" mkstemp(%s) failed (%s)\n",
			    ctx, fn, buf, strerror(errno));
		AZ(unlink(buf));
		*fnp = strdup(buf);
		AN(*fnp);
		retval = 2;
	} else if (S_ISREG(st.st_mode)) {
		fd = open(fn, O_RDWR | O_LARGEFILE);
		if (fd < 0)
			ARGV_ERR("(%s) \"%s\" could not open (%s)\n",
			    ctx, fn, strerror(errno));
		*fnp = fn;
		retval = 0;
	} else
		ARGV_ERR(
		    "(%s) \"%s\" is neither file nor directory\n", ctx, fn);

	AZ(fstat(fd, &st));
	if (!S_ISREG(st.st_mode))
		ARGV_ERR("(%s) \"%s\" was not a file after opening\n",
		    ctx, fn);

	*fdp = fd;
	return (retval);
}
コード例 #7
0
vju_init(char **args)
{
	if (args == NULL) {
		/* Autoconfig */
		if (geteuid() != 0)
			return (1);
		if (vju_getuid(VARNISH_USER))
			return (1);
	} else {

		if (geteuid() != 0)
			ARGV_ERR("Unix Jail: Must be root.\n");

		for (;*args != NULL; args++) {
			if (!strncmp(*args, "user="******"Unix jail: %s user not found.\n",
					    (*args) + 5);
				continue;
			}
			if (!strncmp(*args, "workuser="******"Unix jail: %s user not found.\n",
					    (*args) + 9);
				continue;
			}
			if (!strncmp(*args, "ccgroup=", 8)) {
				if (vju_getccgid((*args) + 8))
					ARGV_ERR(
					    "Unix jail: %s group not found.\n",
					    (*args) + 8);
				continue;
			}
			ARGV_ERR("Unix jail: unknown sub-argument '%s'\n",
			    *args);
		}

		if (vju_user == NULL && vju_getuid(VARNISH_USER))
			ARGV_ERR("Unix jail: %s user not found.\n",
			    VARNISH_USER);
	}

	AN(vju_user);

	vju_mgr_gid = getgid();

	if (vju_wrkuser == NULL)
		(void)vju_getwrkuid(VCACHE_USER);

	if (vju_wrkuser != NULL && vju_wrkgid != vju_gid)
		ARGV_ERR("Unix jail: user %s and %s have "
		    "different login groups\n", vju_user, vju_wrkuser);

	/* Do an explicit JAIL_MASTER_LOW */
	AZ(setegid(vju_gid));
	AZ(seteuid(vju_uid));
	return (0);
}
コード例 #8
0
ファイル: mgt_stevedore.c プロジェクト: ehocdet/varnish-cache
smp_fake_init(struct stevedore *parent, int ac, char * const *av)
{

	(void)parent;
	(void)ac;
	(void)av;
	ARGV_ERR(
	    "-spersistent has been deprecated, please see:\n"
	    "  https://www.varnish-cache.org/docs/trunk/phk/persistent.html\n"
	    "for details.\n"
	);
}
コード例 #9
0
ファイル: mgt_cli.c プロジェクト: ElijahLynn/Varnish-Cache
void
mgt_cli_telnet(const char *T_arg)
{
	int error;
	const char *err;
	struct vsb *vsb;

	AN(T_arg);
	vsb = VSB_new_auto();
	AN(vsb);
	error = VSS_resolver(T_arg, NULL, mct_callback, vsb, &err);
	if (err != NULL)
		ARGV_ERR("Could resolve -T argument to address\n\t%s\n", err);
	AZ(error);
	AZ(VSB_finish(vsb));
	if (VSB_len(vsb) == 0)
		ARGV_ERR("-T %s could not be listened on.", T_arg);
	/* Save in shmem */
	mgt_SHM_static_alloc(VSB_data(vsb), VSB_len(vsb) + 1, "Arg", "-T", "");
	VSB_destroy(&vsb);
}
コード例 #10
0
ファイル: mgt_cli.c プロジェクト: ElijahLynn/Varnish-Cache
void
mgt_cli_master(const char *M_arg)
{
	const char *err;
	int error;

	AN(M_arg);

	error = VSS_resolver(M_arg, NULL, marg_cb, NULL, &err);
	if (err != NULL)
		ARGV_ERR("Could resolve -M argument to address\n\t%s\n", err);
	AZ(error);
	if (VTAILQ_EMPTY(&m_addr_list))
		ARGV_ERR("Could not resolve -M argument to address\n");
	AZ(M_poker);
	M_poker = vev_new();
	AN(M_poker);
	M_poker->timeout = M_poll;
	M_poker->callback = Marg_poker;
	M_poker->name = "-M poker";
	AZ(vev_add(mgt_evb, M_poker));
}
コード例 #11
0
ファイル: storage_umem.c プロジェクト: Gavin-v/varnish-cache
static void
smu_init(struct stevedore *parent, int ac, char * const *av)
{
	const char *e;
	uintmax_t u;

	(void)parent;

	AZ(av[ac]);
	if (ac > 1)
		ARGV_ERR("(-sumem) too many arguments\n");

	if (ac == 0 || *av[0] == '\0')
		 return;

	e = VNUM_2bytes(av[0], &u, 0);
	if (e != NULL)
		ARGV_ERR("(-sumem) size \"%s\": %s\n", av[0], e);
	if ((u != (uintmax_t)(size_t)u))
		ARGV_ERR("(-sumem) size \"%s\": too big\n", av[0]);
	smu_max = u;
}
コード例 #12
0
ファイル: mgt_param_tcp.c プロジェクト: kangkot/Varnish-Cache
static void
tcp_keep_probes(void)
{
	const char *err;
	int s;

	s = VTCP_listen_on(":0", NULL, 10, &err);
	if (err != NULL)
		ARGV_ERR("Could not probe TCP keepalives: %s", err);
	assert(s > 0);
	tcp_probe(s, TCP_KEEPIDLE, "tcp_keepalive_time",	600);
	tcp_probe(s, TCP_KEEPCNT, "tcp_keepalive_probes",	5);
	tcp_probe(s, TCP_KEEPINTVL, "tcp_keepalive_intvl",	5);
	AZ(close(s));
}
コード例 #13
0
ファイル: mgt_stevedore.c プロジェクト: ehocdet/varnish-cache
static void
stv_check_ident(const char *spec, const char *ident)
{
	struct stevedore *stv;
	unsigned found = 0;

	if (!strcmp(ident, TRANSIENT_STORAGE))
		found = (stv_transient != NULL);
	else {
		STV_Foreach(stv)
			if (!strcmp(stv->ident, ident)) {
				found = 1;
				break;
			}
	}

	if (found)
		ARGV_ERR("(-s %s) '%s' is already defined\n", spec, ident);
}
コード例 #14
0
ファイル: stevedore_utils.c プロジェクト: BMDan/Varnish-Cache
uintmax_t
STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx)
{
	uintmax_t l, fssize;
	unsigned bs;
	const char *q;
	int i;
	off_t o;
	struct stat st;

	AN(granularity);
	AN(ctx);

	AZ(fstat(fd, &st));
	xxxassert(S_ISREG(st.st_mode));

	AZ(VFIL_fsinfo(fd, &bs, &fssize, NULL));
	/* Increase granularity if it is lower than the filesystem block size */
	if (*granularity < bs)
		*granularity = bs;

	if ((size == NULL || *size == '\0') && st.st_size != 0) {
		/*
		 * We have no size specification, but an existing file,
		 * use its existing size.
		 */
		l = st.st_size;
	} else if (size == NULL || *size == '\0') {
		ARGV_ERR("(%s) no size specified\n",
		    ctx);
	} else {
		AN(size);
		q = VNUM_2bytes(size, &l, 0);

		if (q != NULL)
			ARGV_ERR("(%s) size \"%s\": %s\n", ctx, size, q);

		if (l < 1024*1024)
			ARGV_ERR("(%s) size \"%s\": too small, "
			    "did you forget to specify M or G?\n", ctx, size);

		if (l > fssize)
			ARGV_ERR("(%s) size \"%s\": larger than file system\n",
			    ctx, size);
	}

	/*
	 * This trickery wouldn't be necessary if X/Open would
	 * just add OFF_MAX to <limits.h>...
	 */
	i = 0;
	while(1) {
		o = l;
		if (o == l && o > 0)
			break;
		l >>= 1;
		i++;
	}
	if (i)
		fprintf(stderr, "WARNING: (%s) file size reduced"
		    " to %ju due to system \"off_t\" limitations\n", ctx, l);

	if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */
		fprintf(stderr,
		    "NB: Storage size limited to 2GB on 32 bit architecture,\n"
		    "NB: otherwise we could run out of address space.\n"
		);
		l = INT32_MAX;
	}

	/* Round down */
	l -= (l % *granularity);

	return(l);
}
コード例 #15
0
ファイル: mgt_jail.c プロジェクト: biddyweb/Varnish-Cache
vjn_init(char **args)
{
	if (args != NULL && *args != NULL)
		ARGV_ERR("-jnone takes no arguments.\n");
	return (0);
}
コード例 #16
0
void
smp_mgt_init(struct stevedore *parent, int ac, char * const *av)
{
	struct smp_sc		*sc;
	struct smp_sign		sgn;
	void *target;
	int i;

	ASSERT_MGT();

	AZ(av[ac]);

	/* Necessary alignment. See also smp_object::__filler__ */
	assert(sizeof(struct smp_object) % 8 == 0);

#define SIZOF(foo)       fprintf(stderr, \
    "sizeof(%s) = %zu = 0x%zx\n", #foo, sizeof(foo), sizeof(foo));
	SIZOF(struct smp_ident);
	SIZOF(struct smp_sign);
	SIZOF(struct smp_segptr);
	SIZOF(struct smp_object);
#undef SIZOF

	/* See comments in storage_persistent.h */
	assert(sizeof(struct smp_ident) == SMP_IDENT_SIZE);

	/* Allocate softc */
	ALLOC_OBJ(sc, SMP_SC_MAGIC);
	XXXAN(sc);
	sc->parent = parent;
	sc->fd = -1;
	VTAILQ_INIT(&sc->segments);

	/* Argument processing */
	if (ac != 2)
		ARGV_ERR("(-spersistent) wrong number of arguments\n");

	i = STV_GetFile(av[0], &sc->fd, &sc->filename, "-spersistent");
	if (i == 2)
		ARGV_ERR("(-spersistent) need filename (not directory)\n");

	sc->align = sizeof(void*) * 2;
	sc->granularity = getpagesize();
	sc->mediasize = STV_FileSize(sc->fd, av[1], &sc->granularity,
	    "-spersistent");

	AZ(ftruncate(sc->fd, sc->mediasize));

	/* Try to determine correct mmap address */
	i = read(sc->fd, &sgn, sizeof sgn);
	assert(i == sizeof sgn);
	if (!strcmp(sgn.ident, "SILO"))
		target = (void*)(uintptr_t)sgn.mapped;
	else
		target = NULL;

	sc->base = (void*)mmap(target, sc->mediasize, PROT_READ|PROT_WRITE,
	    MAP_NOCORE | MAP_NOSYNC | MAP_SHARED, sc->fd, 0);

	if (sc->base == MAP_FAILED)
		ARGV_ERR("(-spersistent) failed to mmap (%s)\n",
		    strerror(errno));

	smp_def_sign(sc, &sc->idn, 0, "SILO");
	sc->ident = SIGN_DATA(&sc->idn);

	i = smp_valid_silo(sc);
	if (i) {
		printf("Warning SILO (%s) not reloaded (reason=%d)\n",
		    sc->filename, i);
		smp_newsilo(sc);
	}
	AZ(smp_valid_silo(sc));

	smp_metrics(sc);

	parent->priv = sc;

	/* XXX: only for sendfile I guess... */
	mgt_child_inherit(sc->fd, "storage_persistent");
}
コード例 #17
0
uintmax_t
STV_FileSize(int fd, const char *size, unsigned *granularity, const char *ctx)
{
	uintmax_t l, fssize;
	unsigned bs;
	const char *q;
	int i;
	off_t o;
	struct stat st;

	AZ(fstat(fd, &st));
	xxxassert(S_ISREG(st.st_mode));

	bs = *granularity;
	fssize = stv_fsspace(fd, &bs);
	xxxassert(bs % *granularity == 0);

	if ((size == NULL || *size == '\0') && st.st_size != 0) {
		/*
		 * We have no size specification, but an existing file,
		 * use its existing size.
		 */
		l = st.st_size;
	} else {
		AN(size);
		q = str2bytes(size, &l, fssize);

		if (q != NULL)
			ARGV_ERR("(%s) size \"%s\": %s\n", size, ctx, q);

		if (l < 1024*1024)
			ARGV_ERR("(-spersistent) size \"%s\": too small, "
				 "did you forget to specify M or G?\n", size);
	}

	/*
	 * This trickery wouldn't be necessary if X/Open would
	 * just add OFF_MAX to <limits.h>...
	 */
	i = 0;
	while(1) {
		o = l;
		if (o == l && o > 0)
			break;
		l >>= 1;
		i++;
	}
	if (i)
		fprintf(stderr, "WARNING: (%s) file size reduced"
		    " to %ju due to system \"off_t\" limitations\n", ctx, l);
	else if (l - st.st_size > fssize) {
		l = fssize * 80 / 100;
		fprintf(stderr, "WARNING: (%s) file size reduced"
		    " to %ju (80%% of available disk space)\n", ctx, l);
	}

	if (sizeof(void *) == 4 && l > INT32_MAX) { /*lint !e506 !e774 !e845 */
		fprintf(stderr,
		    "NB: Storage size limited to 2GB on 32 bit architecture,\n"
		    "NB: otherwise we could run out of address space.\n"
		);
		l = INT32_MAX;
	}

	/* round down to multiple of filesystem blocksize or pagesize */
	l -= (l % bs);

	*granularity = bs;
	return(l);
}