2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2020, Ryan Moeller <freqlabs@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
44 int luaopen_jail(lua_State *);
52 name = luaL_checkstring(L, 1);
53 jid = jail_getid(name);
56 lua_pushstring(L, jail_errmsg);
59 lua_pushinteger(L, jid);
64 l_getname(lua_State *L)
69 jid = luaL_checkinteger(L, 1);
70 name = jail_getname(jid);
73 lua_pushstring(L, jail_errmsg);
76 lua_pushstring(L, name);
82 l_allparams(lua_State *L)
84 struct jailparam *params;
87 params_count = jailparam_all(¶ms);
88 if (params_count == -1) {
90 lua_pushstring(L, jail_errmsg);
94 for (int i = 0; i < params_count; ++i) {
95 lua_pushstring(L, params[i].jp_name);
96 lua_rawseti(L, -2, i + 1);
98 jailparam_free(params, params_count);
104 l_getparams(lua_State *L)
107 struct jailparam *params;
108 size_t params_count, skipped;
109 int flags, jid, type;
111 type = lua_type(L, 1);
112 luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1,
113 "expected a jail name (string) or id (integer)");
114 luaL_checktype(L, 2, LUA_TTABLE);
115 params_count = 1 + lua_rawlen(L, 2);
116 luaL_argcheck(L, params_count > 1, 2, "expected #params > 0");
117 flags = luaL_optinteger(L, 3, 0);
119 params = malloc(params_count * sizeof(struct jailparam));
121 return (luaL_error(L, "malloc: %s", strerror(errno)));
124 * Set the jail name or id param as determined by the first arg.
127 if (type == LUA_TSTRING) {
128 if (jailparam_init(¶ms[0], "name") == -1) {
130 return (luaL_error(L, "jailparam_init: %s",
133 name = lua_tostring(L, 1);
134 if (jailparam_import(¶ms[0], name) == -1) {
135 jailparam_free(params, 1);
137 return (luaL_error(L, "jailparam_import: %s",
140 } else /* type == LUA_TNUMBER */ {
141 if (jailparam_init(¶ms[0], "jid") == -1) {
143 return (luaL_error(L, "jailparam_init: %s",
146 jid = lua_tointeger(L, 1);
147 if (jailparam_import_raw(¶ms[0], &jid, sizeof(jid)) == -1) {
148 jailparam_free(params, 1);
150 return (luaL_error(L, "jailparam_import_raw: %s",
156 * Set the remaining param names being requested.
160 for (size_t i = 1; i < params_count; ++i) {
161 const char *param_name;
163 lua_rawgeti(L, -1, i);
164 param_name = lua_tostring(L, -1);
165 if (param_name == NULL) {
166 jailparam_free(params, i - skipped);
168 return (luaL_argerror(L, 2,
169 "param names must be strings"));
172 /* Skip name or jid, whichever was given. */
173 if (type == LUA_TSTRING) {
174 if (strcmp(param_name, "name") == 0) {
178 } else /* type == LUA_TNUMBER */ {
179 if (strcmp(param_name, "jid") == 0) {
184 if (jailparam_init(¶ms[i - skipped], param_name) == -1) {
185 jailparam_free(params, i - skipped);
187 return (luaL_error(L, "jailparam_init: %s",
191 params_count -= skipped;
194 * Get the values and convert to a table.
197 jid = jailparam_get(params, params_count, flags);
199 jailparam_free(params, params_count);
202 lua_pushstring(L, jail_errmsg);
205 lua_pushinteger(L, jid);
208 for (size_t i = 0; i < params_count; ++i) {
211 value = jailparam_export(¶ms[i]);
212 lua_pushstring(L, value);
214 lua_setfield(L, -2, params[i].jp_name);
217 jailparam_free(params, params_count);
224 l_setparams(lua_State *L)
227 struct jailparam *params;
229 int flags, jid, type;
231 type = lua_type(L, 1);
232 luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1,
233 "expected a jail name (string) or id (integer)");
234 luaL_checktype(L, 2, LUA_TTABLE);
237 for (params_count = 1; lua_next(L, 2) != 0; ++params_count)
239 luaL_argcheck(L, params_count > 1, 2, "expected #params > 0");
241 flags = luaL_optinteger(L, 3, 0);
243 params = malloc(params_count * sizeof(struct jailparam));
245 return (luaL_error(L, "malloc: %s", strerror(errno)));
248 * Set the jail name or id param as determined by the first arg.
251 if (type == LUA_TSTRING) {
252 if (jailparam_init(¶ms[0], "name") == -1) {
254 return (luaL_error(L, "jailparam_init: %s",
257 name = lua_tostring(L, 1);
258 if (jailparam_import(¶ms[0], name) == -1) {
259 jailparam_free(params, 1);
261 return (luaL_error(L, "jailparam_import: %s",
264 } else /* type == LUA_TNUMBER */ {
265 if (jailparam_init(¶ms[0], "jid") == -1) {
267 return (luaL_error(L, "jailparam_init: %s",
270 jid = lua_tointeger(L, 1);
271 if (jailparam_import_raw(¶ms[0], &jid, sizeof(jid)) == -1) {
272 jailparam_free(params, 1);
274 return (luaL_error(L, "jailparam_import_raw: %s",
280 * Set the rest of the provided params.
284 for (size_t i = 1; i < params_count && lua_next(L, 2) != 0; ++i) {
287 name = lua_tostring(L, -2);
289 jailparam_free(params, i);
291 return (luaL_argerror(L, 2,
292 "param names must be strings"));
294 if (jailparam_init(¶ms[i], name) == -1) {
295 jailparam_free(params, i);
297 return (luaL_error(L, "jailparam_init: %s",
301 value = lua_tostring(L, -1);
303 jailparam_free(params, i + 1);
305 return (luaL_argerror(L, 2,
306 "param values must be strings"));
308 if (jailparam_import(¶ms[i], value) == -1) {
309 jailparam_free(params, i + 1);
311 return (luaL_error(L, "jailparam_import: %s",
319 * Attempt to set the params.
322 jid = jailparam_set(params, params_count, flags);
324 jailparam_free(params, params_count);
327 lua_pushstring(L, jail_errmsg);
330 lua_pushinteger(L, jid);
332 jailparam_free(params, params_count);
337 static const struct luaL_Reg l_jail[] = {
338 /** Get id of a jail by name.
339 * @param name jail name (string)
340 * @return jail id (integer)
341 * or nil, error (string) on error
344 /** Get name of a jail by id.
345 * @param jid jail id (integer)
346 * @return jail name (string)
347 * or nil, error (string) on error
349 {"getname", l_getname},
350 /** Get a list of all known jail parameters.
351 * @return list of jail parameter names (table of strings)
352 * or nil, error (string) on error
354 {"allparams", l_allparams},
355 /** Get the listed params for a given jail.
356 * @param jail jail name (string) or id (integer)
357 * @param params list of parameter names (table of strings)
358 * @param flags optional flags (integer)
359 * @return jid (integer), params (table of [string] = string)
360 * or nil, error (string) on error
362 {"getparams", l_getparams},
363 /** Set params for a given jail.
364 * @param jail jail name (string) or id (integer)
365 * @param params params and values (table of [string] = string)
366 * @param flags optional flags (integer)
367 * @return jid (integer)
368 * or nil, error (string) on error
370 {"setparams", l_setparams},
375 luaopen_jail(lua_State *L)
379 luaL_setfuncs(L, l_jail, 0);
381 lua_pushinteger(L, JAIL_CREATE);
382 lua_setfield(L, -2, "CREATE");
383 lua_pushinteger(L, JAIL_UPDATE);
384 lua_setfield(L, -2, "UPDATE");
385 lua_pushinteger(L, JAIL_ATTACH);
386 lua_setfield(L, -2, "ATTACH");
387 lua_pushinteger(L, JAIL_DYING);
388 lua_setfield(L, -2, "DYING");