diff options
| author | Baptiste Daroussin <bapt@FreeBSD.org> | 2024-09-09 15:17:27 +0000 |
|---|---|---|
| committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2024-09-12 07:03:44 +0000 |
| commit | 7899f917b1c0ea178f1d2be0cfb452086d079d23 (patch) | |
| tree | 82f36a60bad849ea06999c0eeb006f920ede71a9 /libexec | |
| parent | d82cb5c608ae9aaced4cb459ca511e62c64dbf74 (diff) | |
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/flua/Makefile | 5 | ||||
| -rw-r--r-- | libexec/flua/Makefile.inc | 5 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/Makefile | 3 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/Makefile.inc | 1 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/sys/Makefile | 4 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/sys/Makefile.inc | 1 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/sys/linker/Makefile | 7 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua | 67 | ||||
| -rw-r--r-- | libexec/flua/libfreebsd/sys/linker/linker.c | 104 | ||||
| -rw-r--r-- | libexec/flua/libhash/Makefile | 9 | ||||
| -rw-r--r-- | libexec/flua/libhash/hash.3lua | 54 | ||||
| -rw-r--r-- | libexec/flua/libhash/lhash.c | 177 | ||||
| -rw-r--r-- | libexec/flua/libhash/lhash.h | 11 | ||||
| -rw-r--r-- | libexec/flua/libjail/Makefile | 9 | ||||
| -rw-r--r-- | libexec/flua/libjail/jail.3lua | 277 | ||||
| -rw-r--r-- | libexec/flua/libjail/lua_jail.c | 710 | ||||
| -rw-r--r-- | libexec/flua/libucl/Makefile | 14 |
17 files changed, 1458 insertions, 0 deletions
diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index c8206b94769d..08ea9c002d61 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -1,5 +1,10 @@ .include <src.lua.mk> +SUBDIR+= libfreebsd +SUBDIR+= libhash +SUBDIR+= libjail +SUBDIR+= libucl + LUASRC?= ${SRCTOP}/contrib/lua/src .PATH: ${LUASRC} diff --git a/libexec/flua/Makefile.inc b/libexec/flua/Makefile.inc new file mode 100644 index 000000000000..34505d54d7df --- /dev/null +++ b/libexec/flua/Makefile.inc @@ -0,0 +1,5 @@ +SHLIBDIR?= ${LIBDIR}/flua + +CFLAGS+= \ + -I${SRCTOP}/contrib/lua/src \ + -I${SRCTOP}/lib/liblua diff --git a/libexec/flua/libfreebsd/Makefile b/libexec/flua/libfreebsd/Makefile new file mode 100644 index 000000000000..6ed0451055ff --- /dev/null +++ b/libexec/flua/libfreebsd/Makefile @@ -0,0 +1,3 @@ +SUBDIR+= sys + +.include <bsd.subdir.mk> diff --git a/libexec/flua/libfreebsd/Makefile.inc b/libexec/flua/libfreebsd/Makefile.inc new file mode 100644 index 000000000000..01b5f23410c8 --- /dev/null +++ b/libexec/flua/libfreebsd/Makefile.inc @@ -0,0 +1 @@ +.include "../Makefile.inc" diff --git a/libexec/flua/libfreebsd/sys/Makefile b/libexec/flua/libfreebsd/sys/Makefile new file mode 100644 index 000000000000..9f38294536f2 --- /dev/null +++ b/libexec/flua/libfreebsd/sys/Makefile @@ -0,0 +1,4 @@ +SUBDIR+= linker + +.include <bsd.subdir.mk> + diff --git a/libexec/flua/libfreebsd/sys/Makefile.inc b/libexec/flua/libfreebsd/sys/Makefile.inc new file mode 100644 index 000000000000..01b5f23410c8 --- /dev/null +++ b/libexec/flua/libfreebsd/sys/Makefile.inc @@ -0,0 +1 @@ +.include "../Makefile.inc" diff --git a/libexec/flua/libfreebsd/sys/linker/Makefile b/libexec/flua/libfreebsd/sys/linker/Makefile new file mode 100644 index 000000000000..1adf547b503c --- /dev/null +++ b/libexec/flua/libfreebsd/sys/linker/Makefile @@ -0,0 +1,7 @@ +SHLIB_NAME= linker.so + +SRCS+= linker.c + +MAN= freebsd.sys.linker.3lua + +.include <bsd.lib.mk> diff --git a/libexec/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua b/libexec/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua new file mode 100644 index 000000000000..0ab8f185388a --- /dev/null +++ b/libexec/flua/libfreebsd/sys/linker/freebsd.sys.linker.3lua @@ -0,0 +1,67 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2024, Baptiste Daroussin <bapt@FreeBSD.org> +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd September 6, 2024 +.Dt FREEBSD.SYS.LINKER 3lua +.Os +.Sh NAME +.Nm freebsd.sys.linker +.Nd Lua binding to +.Fx 's +Linker functions +.Sh SYNOPSIS +.Bd -literal +local linker = require('freebsd.sys.linker') +.Ed +.Pp +.Bl -tag -width XXXX -compact +.It Dv fileid, err, errno = linker.kldload(name) +.It Dv ok, err, errno = linker.kldunload(fileid|name) +.El +.Sh DESCRIPTION +The +.Nm +module is a binding to the +.Fx 's +linker functions. +List of functions: +.Bl -tag -width XXXX +.It Dv fileid, err = freebsd.sys.linker.kldload(name) +Load the kernel module named +.Fa name +and return the identifier +.Pq fileid +as an interger. +.It Dv ok, err, errno = freebsd.sys.linker.kldunload(fileid|name) +Unload the kernel module identifier either by +.Fa name +as a string, or +.Fa fileid +as an integer. +.El +.Sh SEE ALSO +.Xr kldload 2 , +.Xr kldunload 2 diff --git a/libexec/flua/libfreebsd/sys/linker/linker.c b/libexec/flua/libfreebsd/sys/linker/linker.c new file mode 100644 index 000000000000..a2dc3b487525 --- /dev/null +++ b/libexec/flua/libfreebsd/sys/linker/linker.c @@ -0,0 +1,104 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024, Baptiste Daroussin <bapt@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <sys/param.h> +#include <sys/linker.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> + +int luaopen_freebsd_sys_linker(lua_State *L); + +static int +lua_kldload(lua_State *L) +{ + const char *name; + int ret; + + name = luaL_checkstring(L, 1); + ret = kldload(name); + if (ret == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + lua_pushinteger(L, ret); + return (1); +} + +static int +lua_kldunload(lua_State *L) +{ + const char *name; + int ret, fileid; + + if (lua_isinteger(L, 1)) { + fileid = lua_tointeger(L, 1); + } else { + name = luaL_checkstring(L, 1); + fileid = kldfind(name); + } + if (fileid == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + ret = kldunload(fileid); + lua_pushinteger(L, ret); + if (ret == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + lua_pushinteger(L, errno); + return (3); + } + lua_pushinteger(L, 0); + return (1); +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg freebsd_sys_linker[] = { + REG_SIMPLE(kldload), + REG_SIMPLE(kldunload), + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_freebsd_sys_linker(lua_State *L) +{ + luaL_newlib(L, freebsd_sys_linker); + + return (1); +} diff --git a/libexec/flua/libhash/Makefile b/libexec/flua/libhash/Makefile new file mode 100644 index 000000000000..b7c8d7ee9948 --- /dev/null +++ b/libexec/flua/libhash/Makefile @@ -0,0 +1,9 @@ +SHLIB_NAME= hash.so + +SRCS+= lhash.c + +LIBADD+= md + +MAN= hash.3lua + +.include <bsd.lib.mk> diff --git a/libexec/flua/libhash/hash.3lua b/libexec/flua/libhash/hash.3lua new file mode 100644 index 000000000000..1662e87f7c68 --- /dev/null +++ b/libexec/flua/libhash/hash.3lua @@ -0,0 +1,54 @@ +.\" +.\" Copyright (c) 2024 Netflix, Inc. +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd February 6, 2024 +.Dt HASH 3lua +.Os +.Sh NAME +.Nm new , +.Nm update , +.Nm digest , +.Nm hexdigest +.Nd Lua Cryptographic hash module. +.Sh DESCRIPTION +The built-in cryptographic hashing Lua bindings for the are available via the +.Ic hash +table. +.Ss Supported Hashing Schemes +The following hashing schemes are supported by the hash module. +.Bl -bullet -compact +.It +sha256 +.El +.Ss APIs Supported +.Bl -tag -width asdf -compact +.It Fn new data +Compute a digest based on the +.Va data . +.It Fn update Va data +Using the current digest, process +.Va data +to compute a new digest as if all prior data had been concatenated together. +.It Fn digest +Return the hashed digest as a binary array. +This resets the context. +.It Fn hexdigest +Take +.Fn digest +and convert it to an upper case hex string. +This resets the context. +.It Va digest_size +Return the size of the digest, in bytes. +.It Va block_size +Return the block size used in bytes. +.El +.Sh EXAMPLES +.Sh SEE ALSO +.Xr sha256 3 +.Sh AUTHORS +The +.Nm +man page was written by +.An Warner Losh Aq Mt imp@FreeBSD.org . diff --git a/libexec/flua/libhash/lhash.c b/libexec/flua/libhash/lhash.c new file mode 100644 index 000000000000..4587961fe8a0 --- /dev/null +++ b/libexec/flua/libhash/lhash.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <lua.h> +#include "lauxlib.h" +#include "lhash.h" + +#include <sha256.h> +#include <string.h> + +#define SHA256_META "SHA256 meta table" +#define SHA256_DIGEST_LEN 32 + +/* + * Note C++ comments indicate the before -- after state of the stack, in with a + * similar convention to forth's ( ) comments. Lua indexes are from 1 and can be + * read left to right (leftmost is 1). Negative are relative to the end (-1 is + * rightmost). A '.' indicates a return value left on the stack (all values to + * its right). Trivial functions don't do this. + */ + +/* + * Updates the digest with the new data passed in. Takes 1 argument, which + * is converted to a string. + */ +static int +lua_sha256_update(lua_State *L) +{ + size_t len; + const unsigned char *data; + SHA256_CTX *ctx; + + ctx = luaL_checkudata(L, 1, SHA256_META); + data = luaL_checklstring(L, 2, &len); + SHA256_Update(ctx, data, len); + + lua_settop(L, 1); + + return (1); +} + +/* + * Finalizes the digest value and returns it as a 32-byte binary string. The ctx + * is zeroed. + */ +static int +lua_sha256_digest(lua_State *L) +{ + SHA256_CTX *ctx; + unsigned char digest[SHA256_DIGEST_LEN]; + + ctx = luaL_checkudata(L, 1, SHA256_META); + SHA256_Final(digest, ctx); + lua_pushlstring(L, digest, sizeof(digest)); + + return (1); +} + +/* + * Finalizes the digest value and returns it as a 64-byte ascii string of hex + * numbers. The ctx is zeroed. + */ +static int +lua_sha256_hexdigest(lua_State *L) +{ + SHA256_CTX *ctx; + char buf[SHA256_DIGEST_LEN * 2 + 1]; + unsigned char digest[SHA256_DIGEST_LEN]; + static const char hex[]="0123456789abcdef"; + int i; + + ctx = luaL_checkudata(L, 1, SHA256_META); + SHA256_Final(digest, ctx); + for (i = 0; i < SHA256_DIGEST_LEN; i++) { + buf[i+i] = hex[digest[i] >> 4]; + buf[i+i+1] = hex[digest[i] & 0x0f]; + } + buf[i+i] = '\0'; + + lua_pushstring(L, buf); + + return (1); +} + +/* + * Zeros out the ctx before garbage collection. Normally this is done in + * obj:digest or obj:hexdigest, but if not, it will be wiped here. Lua + * manages freeing the ctx memory. + */ +static int +lua_sha256_done(lua_State *L) +{ + SHA256_CTX *ctx; + + ctx = luaL_checkudata(L, 1, SHA256_META); + memset(ctx, 0, sizeof(*ctx)); + + return (0); +} + +/* + * Create object obj which accumulates the state of the sha256 digest + * for its contents and any subsequent obj:update call. It takes zero + * or 1 arguments. + */ +static int +lua_sha256(lua_State *L) +{ + SHA256_CTX *ctx; + int top; + + /* We take 0 or 1 args */ + top = lua_gettop(L); // data -- data + if (top > 1) { + lua_pushnil(L); + return (1); + } + + ctx = lua_newuserdata(L, sizeof(*ctx)); // data -- data ctx + SHA256_Init(ctx); + if (top == 1) { + size_t len; + const unsigned char *data; + + data = luaL_checklstring(L, 1, &len); + SHA256_Update(ctx, data, len); + } + luaL_setmetatable(L, SHA256_META); // data ctx -- data ctx + + return (1); // data . ctx +} + +/* + * Setup the metatable to manage our userdata that we create in lua_sha256. We + * request a finalization call with __gc so we can zero out the ctx buffer so + * that we don't leak secrets if obj:digest or obj:hexdigest aren't called. + */ +static void +register_metatable_sha256(lua_State *L) +{ + luaL_newmetatable(L, SHA256_META); // -- meta + + lua_newtable(L); // meta -- meta tbl + lua_pushcfunction(L, lua_sha256_update); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "update"); // meta tbl fn -- meta tbl + lua_pushcfunction(L, lua_sha256_digest); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "digest"); // meta tbl fn -- meta tbl + lua_pushcfunction(L, lua_sha256_hexdigest); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "hexdigest"); // meta tbl fn -- meta tbl + + /* Associate tbl with metatable */ + lua_setfield(L, -2, "__index"); // meta tbl -- meta + lua_pushcfunction(L, lua_sha256_done); // meta -- meta fn + lua_setfield(L, -2, "__gc"); // meta fn -- meta + + lua_pop(L, 1); // meta -- +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg hashlib[] = { + REG_SIMPLE(sha256), + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_hash(lua_State *L) +{ + register_metatable_sha256(L); + + luaL_newlib(L, hashlib); + + return 1; +} diff --git a/libexec/flua/libhash/lhash.h b/libexec/flua/libhash/lhash.h new file mode 100644 index 000000000000..c1e9788a55a3 --- /dev/null +++ b/libexec/flua/libhash/lhash.h @@ -0,0 +1,11 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <lua.h> + +int luaopen_hash(lua_State *L); diff --git a/libexec/flua/libjail/Makefile b/libexec/flua/libjail/Makefile new file mode 100644 index 000000000000..20cd9f5f1429 --- /dev/null +++ b/libexec/flua/libjail/Makefile @@ -0,0 +1,9 @@ +SHLIB_NAME= jail.so + +SRCS+= lua_jail.c + +LIBADD+= jail + +MAN= jail.3lua + +.include <bsd.lib.mk> diff --git a/libexec/flua/libjail/jail.3lua b/libexec/flua/libjail/jail.3lua new file mode 100644 index 000000000000..59cbd2dc228c --- /dev/null +++ b/libexec/flua/libjail/jail.3lua @@ -0,0 +1,277 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2020, Ryan Moeller <freqlabs@FreeBSD.org> +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd October 24, 2020 +.Dt JAIL 3lua +.Os +.Sh NAME +.Nm attach , +.Nm getid , +.Nm getname , +.Nm list , +.Nm allparams , +.Nm getparams , +.Nm remove , +.Nm setparams , +.Nm CREATE , +.Nm UPDATE , +.Nm ATTACH , +.Nm DYING +.Nd Lua binding to +.Xr jail 3 +.Sh SYNOPSIS +.Bd -literal +local jail = require('jail') +.Ed +.Pp +.Bl -tag -width XXXX -compact +.It Dv ok, err = jail.attach(jid|name) +.It Dv jid, err = jail.getid(name) +.It Dv name, err = jail.getname(jid) +.It Dv params, err = jail.allparams() +.It Dv iter, jail_obj = jail.list([params]) +.It Dv jid, res = jail.getparams(jid|name, params [, flags ] ) +.It Dv ok, err = jail.remove(jid|name) +.It Dv jid, err = jail.setparams(jid|name, params, flags ) +.It Dv jail.CREATE +.It Dv jail.UPDATE +.It Dv jail.ATTACH +.It Dv jail.DYING +.El +.Sh DESCRIPTION +The +.Nm jail +module is a binding to the +.Xr jail 3 +library. +It provides a string-oriented interface for the +.Xr jail_get 2 +and +.Xr jail_set 2 +system calls. +.Bl -tag -width XXXX +.It Dv ok, err = jail.attach(jid|name) +Attach to the given jail, identified by an integer +.Fa jid +or the +.Fa name . +.It Dv jid, err = jail.getid(name) +Get the jail identifier +.Pq jid +as an integer. +.Fa name +is the name of a jail or a jid in the form of a string. +.It Dv name, err = jail.getname(jid) +Get the name of a jail as a string for the given +.Fa jid +.Pq an integer . +.It Dv iter, jail_obj = jail.list([params]) +Returns an iterator over running jails on the system. +.Dv params +is a list of parameters to fetch for each jail as we iterate. +.Dv jid +and +.Dv name +will always be returned, and may be omitted from +.Dv params . +Additionally, +.Dv params +may be omitted or an empty table, but not nil. +.Pp +See +.Sx EXAMPLES . +.It Dv params, err = jail.allparams() +Get a list of all supported parameter names +.Pq as strings . +See +.Xr jail 8 +for descriptions of the core jail parameters. +.It Dv jid, res = jail.getparams(jid|name, params [, flags ] ) +Get a table of the requested parameters for the given jail. +.Nm jid|name +can either be the jid as an integer or the jid or name as a string. +.Nm params +is a list of parameter names. +.Nm flags +is an optional integer representing the flag bits to apply for the operation. +See the list of flags below. +Only the +.Dv DYING +flag is valid to set. +.It Dv ok, err = jail.remove(jid|name) +Remove the given jail, identified by an integer +.Fa jid +or the +.Fa name . +.It Dv jid, err = jail.setparams(jid|name, params [, flags ] ) +Set parameters for a given jail. +This is used to create, update, attach to, or destroy a jail. +.Nm jid|name +can either be the jid as an integer or the jid or name as a string. +.Nm params +is a table of parameters to apply to the jail, where each key in the table +is a parameter name as a string and each value is a string that will be +converted to the internal value type by +.Xr jailparam_import 3 . +.Nm flags +is an optional integer representing the flag bits to apply for the operation. +See the list of flags below. +.El +.Pp +The +.Nm flags +arguments are an integer bitwise-or combination of one or more of the following +flags: +.Bl -tag -width XXXX +.It Dv jail.CREATE +Used with +.Fn setparams +to create a new jail. +The jail must not already exist, unless combined with +.Dv UPDATE . +.It Dv jail.UPDATE +Used with +.Fn setparams +to modify an existing jail. +The jail must already exist, unless combined with +.Dv CREATE . +.It Dv jail.ATTACH +Used with +.Fn setparams +in combination with +.Dv CREATE +or +.Dv UPDATE +to attach the current process to a jail. +.It Dv jail.DYING +Allow operating on a jail that is in the process of being removed. +.El +.Sh RETURN VALUES +The +.Fn getid +and +.Fn setparams +functions return a jail identifier integer on success, or +.Dv nil +and an error message string if an error occurred. +.Pp +The +.Fn getname +function returns a jail name string on success, or +.Dv nil +and an error message string if an error occurred. +.Pp +The +.Fn allparams +function returns a list of parameter name strings on success, or +.Dv nil +and an error message string if an error occurred. +.Pp +The +.Fn getparams +function returns a jail identifier integer and a table of jail parameters +with parameter name strings as keys and strings for values on success, or +.Dv nil +and an error message string if an error occurred. +.Pp +The +.Fn list +function returns an iterator over the list of running jails. +.Pp +The +.Fn attach +and +.Fn remove +functions return true on success, or +.Dv nil +and an error message string if an error occurred. +.Sh EXAMPLES +Set the hostname of jail +.Dq foo +to +.Dq foo.bar : +.Bd -literal -offset indent +local jail = require('jail') + +jid, err = jail.setparams("foo", {["host.hostname"]="foo.bar"}, + jail.UPDATE) +if not jid then + error(err) +end +.Ed +.Pp +Retrieve the hostname of jail +.Dq foo : +.Bd -literal -offset indent +local jail = require('jail') + +jid, res = jail.getparams("foo", {"host.hostname"}) +if not jid then + error(res) +end +print(res["host.hostname"]) +.Ed +.Pp +Iterate over jails on the system: +.Bd -literal -offset indent +local jail = require('jail') + +-- Recommended: just loop over it +for jparams in jail.list() do + print(jparams["jid"] .. " = " .. jparams["name"]) +end + +-- Request path and hostname, too +for jparams in jail.list({"path", "host.hostname"}) do + print(jparams["host.hostname"] .. " mounted at " .. jparams["path"]) +end + +-- Raw iteration protocol +local iter, jail_obj = jail.list() + +-- Request the first params +local jparams = jail_obj:next() +while jparams do + print(jparams["jid"] .. " = " .. jparams["name"]) + -- Subsequent calls may return nil + jparams = jail_obj:next() +end +.Ed +.Sh SEE ALSO +.Xr jail 2 , +.Xr jail 3 , +.Xr jail 8 +.Sh HISTORY +The +.Nm jail +Lua module for flua first appeared in +.Fx 13.0 . +.Sh AUTHORS +.An Ryan Moeller , +with inspiration from +.Nx +gpio(3lua), by +.An Mark Balmer . diff --git a/libexec/flua/libjail/lua_jail.c b/libexec/flua/libjail/lua_jail.c new file mode 100644 index 000000000000..f364b090b3f9 --- /dev/null +++ b/libexec/flua/libjail/lua_jail.c @@ -0,0 +1,710 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020, Ryan Moeller <freqlabs@FreeBSD.org> + * Copyright (c) 2020, Kyle Evans <kevans@FreeBSD.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/jail.h> +#include <errno.h> +#include <jail.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> + +#define JAIL_METATABLE "jail iterator metatable" + +/* + * Taken from RhodiumToad's lspawn implementation, let static analyzers make + * better decisions about the behavior after we raise an error. + */ +#if defined(LUA_VERSION_NUM) && defined(LUA_API) +LUA_API int (lua_error) (lua_State *L) __dead2; +#endif +#if defined(LUA_ERRFILE) && defined(LUALIB_API) +LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg) __dead2; +LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname) __dead2; +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...) __dead2; +#endif + +int luaopen_jail(lua_State *); + +typedef bool (*getparam_filter)(const char *, void *); + +static void getparam_table(lua_State *L, int paramindex, + struct jailparam *params, size_t paramoff, size_t *params_countp, + getparam_filter keyfilt, void *udata); + +struct l_jail_iter { + struct jailparam *params; + size_t params_count; + int jid; +}; + +static bool +l_jail_filter(const char *param_name, void *data __unused) +{ + + /* + * Allowing lastjid will mess up our iteration over all jails on the + * system, as this is a special parameter that indicates where the search + * starts from. We'll always add jid and name, so just silently remove + * these. + */ + return (strcmp(param_name, "lastjid") != 0 && + strcmp(param_name, "jid") != 0 && + strcmp(param_name, "name") != 0); +} + +static int +l_jail_iter_next(lua_State *L) +{ + struct l_jail_iter *iter, **iterp; + struct jailparam *jp; + int serrno; + + iterp = (struct l_jail_iter **)luaL_checkudata(L, 1, JAIL_METATABLE); + iter = *iterp; + luaL_argcheck(L, iter != NULL, 1, "closed jail iterator"); + + jp = iter->params; + /* Populate lastjid; we must keep it in params[0] for our sake. */ + if (jailparam_import_raw(&jp[0], &iter->jid, sizeof(iter->jid))) { + jailparam_free(jp, iter->params_count); + free(jp); + free(iter); + *iterp = NULL; + return (luaL_error(L, "jailparam_import_raw: %s", jail_errmsg)); + } + + /* The list of requested params was populated back in l_list(). */ + iter->jid = jailparam_get(jp, iter->params_count, 0); + if (iter->jid == -1) { + /* + * We probably got an ENOENT to signify the end of the jail + * listing, but just in case we didn't; stash it off and start + * cleaning up. We'll handle non-ENOENT errors later. + */ + serrno = errno; + jailparam_free(jp, iter->params_count); + free(iter->params); + free(iter); + *iterp = NULL; + if (serrno != ENOENT) + return (luaL_error(L, "jailparam_get: %s", + strerror(serrno))); + return (0); + } + + /* + * Finally, we'll fill in the return table with whatever parameters the + * user requested, in addition to the ones we forced with exception to + * lastjid. + */ + lua_newtable(L); + for (size_t i = 0; i < iter->params_count; ++i) { + char *value; + + jp = &iter->params[i]; + if (strcmp(jp->jp_name, "lastjid") == 0) + continue; + value = jailparam_export(jp); + lua_pushstring(L, value); + lua_setfield(L, -2, jp->jp_name); + free(value); + } + + return (1); +} + +static int +l_jail_iter_close(lua_State *L) +{ + struct l_jail_iter *iter, **iterp; + + /* + * Since we're using this as the __gc method as well, there's a good + * chance that it's already been cleaned up by iterating to the end of + * the list. + */ + iterp = (struct l_jail_iter **)lua_touserdata(L, 1); + iter = *iterp; + if (iter == NULL) + return (0); + + jailparam_free(iter->params, iter->params_count); + free(iter->params); + free(iter); + *iterp = NULL; + return (0); +} + +static int +l_list(lua_State *L) +{ + struct l_jail_iter *iter; + int nargs; + + nargs = lua_gettop(L); + if (nargs >= 1) + luaL_checktype(L, 1, LUA_TTABLE); + + iter = malloc(sizeof(*iter)); + if (iter == NULL) + return (luaL_error(L, "malloc: %s", strerror(errno))); + + /* + * lastjid, jid, name + length of the table. This may be too much if + * we have duplicated one of those fixed parameters. + */ + iter->params_count = 3 + (nargs != 0 ? lua_rawlen(L, 1) : 0); + iter->params = malloc(iter->params_count * sizeof(*iter->params)); + if (iter->params == NULL) { + free(iter); + return (luaL_error(L, "malloc params: %s", strerror(errno))); + } + + /* The :next() method will populate lastjid before jail_getparam(). */ + if (jailparam_init(&iter->params[0], "lastjid") == -1) { + free(iter->params); + free(iter); + return (luaL_error(L, "jailparam_init: %s", jail_errmsg)); + } + /* These two will get populated by jail_getparam(). */ + if (jailparam_init(&iter->params[1], "jid") == -1) { + jailparam_free(iter->params, 1); + free(iter->params); + free(iter); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + if (jailparam_init(&iter->params[2], "name") == -1) { + jailparam_free(iter->params, 2); + free(iter->params); + free(iter); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + + /* + * We only need to process additional arguments if we were given any. + * That is, we don't descend into getparam_table if we're passed nothing + * or an empty table. + */ + iter->jid = 0; + if (iter->params_count != 3) + getparam_table(L, 1, iter->params, 2, &iter->params_count, + l_jail_filter, NULL); + + /* + * Part of the iterator magic. We give it an iterator function with a + * metatable defining next() and close() that can be used for manual + * iteration. iter->jid is how we track which jail we last iterated, to + * be supplied as "lastjid". + */ + lua_pushcfunction(L, l_jail_iter_next); + *(struct l_jail_iter **)lua_newuserdata(L, + sizeof(struct l_jail_iter **)) = iter; + luaL_getmetatable(L, JAIL_METATABLE); + lua_setmetatable(L, -2); + return (2); +} + +static void +register_jail_metatable(lua_State *L) +{ + luaL_newmetatable(L, JAIL_METATABLE); + lua_newtable(L); + lua_pushcfunction(L, l_jail_iter_next); + lua_setfield(L, -2, "next"); + lua_pushcfunction(L, l_jail_iter_close); + lua_setfield(L, -2, "close"); + + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, l_jail_iter_close); + lua_setfield(L, -2, "__gc"); + + lua_pop(L, 1); +} + +static int +l_getid(lua_State *L) +{ + const char *name; + int jid; + + name = luaL_checkstring(L, 1); + jid = jail_getid(name); + if (jid == -1) { + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + lua_pushinteger(L, jid); + return (1); +} + +static int +l_getname(lua_State *L) +{ + char *name; + int jid; + + jid = luaL_checkinteger(L, 1); + name = jail_getname(jid); + if (name == NULL) { + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + lua_pushstring(L, name); + free(name); + return (1); +} + +static int +l_allparams(lua_State *L) +{ + struct jailparam *params; + int params_count; + + params_count = jailparam_all(¶ms); + if (params_count == -1) { + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + lua_newtable(L); + for (int i = 0; i < params_count; ++i) { + lua_pushstring(L, params[i].jp_name); + lua_rawseti(L, -2, i + 1); + } + jailparam_free(params, params_count); + free(params); + return (1); +} + +static void +getparam_table(lua_State *L, int paramindex, struct jailparam *params, + size_t params_off, size_t *params_countp, getparam_filter keyfilt, + void *udata) +{ + size_t params_count; + int skipped; + + params_count = *params_countp; + skipped = 0; + for (size_t i = 1 + params_off; i < params_count; ++i) { + const char *param_name; + + lua_rawgeti(L, -1, i - params_off); + param_name = lua_tostring(L, -1); + if (param_name == NULL) { + jailparam_free(params, i - skipped); + free(params); + luaL_argerror(L, paramindex, + "param names must be strings"); + } + lua_pop(L, 1); + if (keyfilt != NULL && !keyfilt(param_name, udata)) { + ++skipped; + continue; + } + if (jailparam_init(¶ms[i - skipped], param_name) == -1) { + jailparam_free(params, i - skipped); + free(params); + luaL_error(L, "jailparam_init: %s", jail_errmsg); + } + } + *params_countp -= skipped; +} + +struct getparams_filter_args { + int filter_type; +}; + +static bool +l_getparams_filter(const char *param_name, void *udata) +{ + struct getparams_filter_args *gpa; + + gpa = udata; + + /* Skip name or jid, whichever was given. */ + if (gpa->filter_type == LUA_TSTRING) { + if (strcmp(param_name, "name") == 0) + return (false); + } else /* type == LUA_TNUMBER */ { + if (strcmp(param_name, "jid") == 0) + return (false); + } + + return (true); +} + +static int +l_getparams(lua_State *L) +{ + const char *name; + struct jailparam *params; + size_t params_count; + struct getparams_filter_args gpa; + int flags, jid, type; + + type = lua_type(L, 1); + luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1, + "expected a jail name (string) or id (integer)"); + luaL_checktype(L, 2, LUA_TTABLE); + params_count = 1 + lua_rawlen(L, 2); + flags = luaL_optinteger(L, 3, 0); + + params = malloc(params_count * sizeof(struct jailparam)); + if (params == NULL) + return (luaL_error(L, "malloc: %s", strerror(errno))); + + /* + * Set the jail name or id param as determined by the first arg. + */ + + if (type == LUA_TSTRING) { + if (jailparam_init(¶ms[0], "name") == -1) { + free(params); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + name = lua_tostring(L, 1); + if (jailparam_import(¶ms[0], name) == -1) { + jailparam_free(params, 1); + free(params); + return (luaL_error(L, "jailparam_import: %s", + jail_errmsg)); + } + } else /* type == LUA_TNUMBER */ { + if (jailparam_init(¶ms[0], "jid") == -1) { + free(params); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + jid = lua_tointeger(L, 1); + if (jailparam_import_raw(¶ms[0], &jid, sizeof(jid)) == -1) { + jailparam_free(params, 1); + free(params); + return (luaL_error(L, "jailparam_import_raw: %s", + jail_errmsg)); + } + } + + /* + * Set the remaining param names being requested. + */ + gpa.filter_type = type; + getparam_table(L, 2, params, 0, ¶ms_count, l_getparams_filter, &gpa); + + /* + * Get the values and convert to a table. + */ + + jid = jailparam_get(params, params_count, flags); + if (jid == -1) { + jailparam_free(params, params_count); + free(params); + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + lua_pushinteger(L, jid); + + lua_newtable(L); + for (size_t i = 0; i < params_count; ++i) { + char *value; + + value = jailparam_export(¶ms[i]); + lua_pushstring(L, value); + free(value); + lua_setfield(L, -2, params[i].jp_name); + } + + jailparam_free(params, params_count); + free(params); + + return (2); +} + +static int +l_setparams(lua_State *L) +{ + const char *name; + struct jailparam *params; + size_t params_count; + int flags, jid, type; + + type = lua_type(L, 1); + luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1, + "expected a jail name (string) or id (integer)"); + luaL_checktype(L, 2, LUA_TTABLE); + + lua_pushnil(L); + for (params_count = 1; lua_next(L, 2) != 0; ++params_count) + lua_pop(L, 1); + + flags = luaL_optinteger(L, 3, 0); + + params = malloc(params_count * sizeof(struct jailparam)); + if (params == NULL) + return (luaL_error(L, "malloc: %s", strerror(errno))); + + /* + * Set the jail name or id param as determined by the first arg. + */ + + if (type == LUA_TSTRING) { + if (jailparam_init(¶ms[0], "name") == -1) { + free(params); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + name = lua_tostring(L, 1); + if (jailparam_import(¶ms[0], name) == -1) { + jailparam_free(params, 1); + free(params); + return (luaL_error(L, "jailparam_import: %s", + jail_errmsg)); + } + } else /* type == LUA_TNUMBER */ { + if (jailparam_init(¶ms[0], "jid") == -1) { + free(params); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + jid = lua_tointeger(L, 1); + if (jailparam_import_raw(¶ms[0], &jid, sizeof(jid)) == -1) { + jailparam_free(params, 1); + free(params); + return (luaL_error(L, "jailparam_import_raw: %s", + jail_errmsg)); + } + } + + /* + * Set the rest of the provided params. + */ + + lua_pushnil(L); + for (size_t i = 1; i < params_count && lua_next(L, 2) != 0; ++i) { + const char *value; + + name = lua_tostring(L, -2); + if (name == NULL) { + jailparam_free(params, i); + free(params); + return (luaL_argerror(L, 2, + "param names must be strings")); + } + if (jailparam_init(¶ms[i], name) == -1) { + jailparam_free(params, i); + free(params); + return (luaL_error(L, "jailparam_init: %s", + jail_errmsg)); + } + + value = lua_tostring(L, -1); + if (value == NULL) { + jailparam_free(params, i + 1); + free(params); + return (luaL_argerror(L, 2, + "param values must be strings")); + } + if (jailparam_import(¶ms[i], value) == -1) { + jailparam_free(params, i + 1); + free(params); + return (luaL_error(L, "jailparam_import: %s", + jail_errmsg)); + } + + lua_pop(L, 1); + } + + /* + * Attempt to set the params. + */ + + jid = jailparam_set(params, params_count, flags); + if (jid == -1) { + jailparam_free(params, params_count); + free(params); + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + lua_pushinteger(L, jid); + + jailparam_free(params, params_count); + free(params); + return (1); +} + +static int +l_attach(lua_State *L) +{ + int jid, type; + + type = lua_type(L, 1); + luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1, + "expected a jail name (string) or id (integer)"); + + if (lua_isstring(L, 1)) { + /* Resolve it to a jid. */ + jid = jail_getid(lua_tostring(L, 1)); + if (jid == -1) { + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + } else { + jid = lua_tointeger(L, 1); + } + + if (jail_attach(jid) == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + return (2); + } + + lua_pushboolean(L, 1); + return (1); +} + +static int +l_remove(lua_State *L) +{ + int jid, type; + + type = lua_type(L, 1); + luaL_argcheck(L, type == LUA_TSTRING || type == LUA_TNUMBER, 1, + "expected a jail name (string) or id (integer)"); + + if (lua_isstring(L, 1)) { + /* Resolve it to a jid. */ + jid = jail_getid(lua_tostring(L, 1)); + if (jid == -1) { + lua_pushnil(L); + lua_pushstring(L, jail_errmsg); + return (2); + } + } else { + jid = lua_tointeger(L, 1); + } + + if (jail_remove(jid) == -1) { + lua_pushnil(L); + lua_pushstring(L, strerror(errno)); + return (2); + } + + lua_pushboolean(L, 1); + return (1); +} + +static const struct luaL_Reg l_jail[] = { + /** Get id of a jail by name. + * @param name jail name (string) + * @return jail id (integer) + * or nil, error (string) on error + */ + {"getid", l_getid}, + /** Get name of a jail by id. + * @param jid jail id (integer) + * @return jail name (string) + * or nil, error (string) on error + */ + {"getname", l_getname}, + /** Get a list of all known jail parameters. + * @return list of jail parameter names (table of strings) + * or nil, error (string) on error + */ + {"allparams", l_allparams}, + /** Get the listed params for a given jail. + * @param jail jail name (string) or id (integer) + * @param params list of parameter names (table of strings) + * @param flags optional flags (integer) + * @return jid (integer), params (table of [string] = string) + * or nil, error (string) on error + */ + {"getparams", l_getparams}, + /** Set params for a given jail. + * @param jail jail name (string) or id (integer) + * @param params params and values (table of [string] = string) + * @param flags optional flags (integer) + * @return jid (integer) + * or nil, error (string) on error + */ + {"setparams", l_setparams}, + /** Get a list of jail parameters for running jails on the system. + * @param params optional list of parameter names (table of + * strings) + * @return iterator (function), jail_obj (object) with next and + * close methods + */ + {"list", l_list}, + /** Attach to a running jail. + * @param jail jail name (string) or id (integer) + * @return true (boolean) + * or nil, error (string) on error + */ + {"attach", l_attach}, + /** Remove a running jail. + * @param jail jail name (string) or id (integer) + * @return true (boolean) + * or nil, error (string) on error + */ + {"remove", l_remove}, + {NULL, NULL} +}; + +int +luaopen_jail(lua_State *L) +{ + lua_newtable(L); + + luaL_setfuncs(L, l_jail, 0); + + lua_pushinteger(L, JAIL_CREATE); + lua_setfield(L, -2, "CREATE"); + lua_pushinteger(L, JAIL_UPDATE); + lua_setfield(L, -2, "UPDATE"); + lua_pushinteger(L, JAIL_ATTACH); + lua_setfield(L, -2, "ATTACH"); + lua_pushinteger(L, JAIL_DYING); + lua_setfield(L, -2, "DYING"); + + register_jail_metatable(L); + + return (1); +} diff --git a/libexec/flua/libucl/Makefile b/libexec/flua/libucl/Makefile new file mode 100644 index 000000000000..a88c8bda6bfc --- /dev/null +++ b/libexec/flua/libucl/Makefile @@ -0,0 +1,14 @@ +SHLIB_NAME= ucl.so + +WARNS= 2 + +UCLSRC?= ${SRCTOP}/contrib/libucl +.PATH: ${UCLSRC}/lua +SRCS+= lua_ucl.c +CFLAGS+= \ + -I${UCLSRC}/include \ + -I${UCLSRC}/src \ + -I${UCLSRC}/uthash +LIBADD+= ucl + +.include <bsd.lib.mk> |
