varnish-cache/bin/varnishd/mgt/mgt_jail.c
1
/*-
2
 * Copyright (c) 2015 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 *
28
 * Jailing
29
 *
30
 */
31
32
#include "config.h"
33
34
#include <errno.h>
35
#include <fcntl.h>
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <string.h>
39
#include <unistd.h>
40
#include <sys/stat.h>
41
42
#include "mgt/mgt.h"
43
#include "common/heritage.h"
44
#include "vav.h"
45
46
/**********************************************************************
47
 * A "none" jail implementation which doesn't do anything.
48
 */
49
50
static int v_matchproto_(jail_init_f)
51 637
vjn_init(char **args)
52
{
53 637
        if (args != NULL && *args != NULL)
54 0
                ARGV_ERR("-jnone takes no arguments.\n");
55 637
        return (0);
56
}
57
58
static void v_matchproto_(jail_master_f)
59 17498
vjn_master(enum jail_master_e jme)
60
{
61
        (void)jme;
62 17498
}
63
64
static void v_matchproto_(jail_subproc_f)
65 2975
vjn_subproc(enum jail_subproc_e jse)
66
{
67
        (void)jse;
68 2975
}
69
70
static const struct jail_tech jail_tech_none = {
71
        .magic =        JAIL_TECH_MAGIC,
72
        .name =         "none",
73
        .init =         vjn_init,
74
        .master =       vjn_master,
75
        .subproc =      vjn_subproc,
76
};
77
78
/**********************************************************************/
79
80
static const struct jail_tech *vjt;
81
82
static const struct choice vj_choice[] = {
83
#ifdef HAVE_SETPPRIV
84
        { "solaris",    &jail_tech_solaris },
85
#endif
86
        { "unix",       &jail_tech_unix },
87
        { "none",       &jail_tech_none },
88
        { NULL,         NULL },
89
};
90
91
void
92 662
VJ_Init(const char *j_arg)
93
{
94
        char **av;
95
        int i;
96
97 662
        if (j_arg != NULL) {
98 9
                av = VAV_Parse(j_arg, NULL, ARGV_COMMA);
99 9
                AN(av);
100 9
                if (av[0] != NULL)
101 0
                        ARGV_ERR("-j argument: %s\n", av[0]);
102 9
                if (av[1] == NULL)
103 0
                        ARGV_ERR("-j argument is emtpy\n");
104 9
                vjt = MGT_Pick(vj_choice, av[1], "jail");
105 7
                CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
106 7
                (void)vjt->init(av + 2);
107 2
                VAV_Free(av);
108
        } else {
109
                /*
110
                 * Go through list of jail technologies until one
111
                 * succeeds, falling back to "none".
112
                 */
113 1290
                for (i = 0; vj_choice[i].name != NULL; i++) {
114 1290
                        vjt = vj_choice[i].ptr;
115 1290
                        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
116 1290
                        if (!vjt->init(NULL))
117 653
                                break;
118
                }
119
        }
120 655
        VSB_printf(vident, ",-j%s", vjt->name);
121 655
}
122
123
void
124 17857
VJ_master(enum jail_master_e jme)
125
{
126 17857
        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
127 17857
        vjt->master(jme);
128 17857
}
129
130
void
131 3030
VJ_subproc(enum jail_subproc_e jse)
132
{
133 3030
        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
134 3030
        vjt->subproc(jse);
135 3030
}
136
137
int
138 631
VJ_make_workdir(const char *dname)
139
{
140
        int fd;
141
142 631
        AN(dname);
143 631
        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
144 631
        if (vjt->make_workdir != NULL)
145 0
                return (vjt->make_workdir(dname));
146
147 631
        VJ_master(JAIL_MASTER_FILE);
148 631
        if (mkdir(dname, 0755) < 0 && errno != EEXIST)
149 0
                ARGV_ERR("Cannot create working directory '%s': %s\n",
150
                    dname, strerror(errno));
151
152 631
        if (chdir(dname) < 0)
153 0
                ARGV_ERR("Cannot change to working directory '%s': %s\n",
154
                    dname, strerror(errno));
155
156 631
        fd = open("_.testfile", O_RDWR|O_CREAT|O_EXCL, 0600);
157 631
        if (fd < 0)
158 0
                ARGV_ERR("Cannot create test-file in %s (%s)\n"
159
                    "Check permissions (or delete old directory)\n",
160
                    dname, strerror(errno));
161 631
        closefd(&fd);
162 631
        AZ(unlink("_.testfile"));
163 631
        VJ_master(JAIL_MASTER_LOW);
164 631
        return (0);
165
}
166
167
int
168 1537
VJ_make_vcldir(const char *dname)
169
{
170
171 1537
        AN(dname);
172 1537
        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
173 1537
        if (vjt->make_vcldir != NULL)
174 28
                return (vjt->make_vcldir(dname));
175
176 1509
        if (mkdir(dname, 0755) < 0 && errno != EEXIST) {
177 0
                MGT_Complain(C_ERR, "Cannot create VCL directory '%s': %s",
178 0
                    dname, strerror(errno));
179 0
                return (1);
180
        }
181 1509
        return (0);
182
}
183
184
void
185 1266
VJ_fix_fd(int fd, enum jail_fixfd_e what)
186
{
187
188 1266
        CHECK_OBJ_NOTNULL(vjt, JAIL_TECH_MAGIC);
189 1266
        if (vjt->fixfd != NULL)
190 28
                vjt->fixfd(fd, what);
191 1266
}