aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@strace.io>2024-09-01 08:00:00 +0000
committerDmitry V. Levin <ldv@strace.io>2024-09-10 08:00:00 +0000
commit7fb6beed01bc1a59438b8b2a9b34b2dba296e553 (patch)
tree2f6ae951c4d94d331e29e348e6ffd9846687be33
parentaa3e91322cbc651bb130ec8636b28d676979d4fe (diff)
downloadpam-7fb6beed01bc1a59438b8b2a9b34b2dba296e553.tar.gz
pam-7fb6beed01bc1a59438b8b2a9b34b2dba296e553.tar.bz2
pam-7fb6beed01bc1a59438b8b2a9b34b2dba296e553.zip
meson: build Linux-PAM using meson
On my non-representative hardware, the full build using autotools (./autogen.sh && CFLAGS=-O2 ./configure && make -j`nproc` && make -j`nproc` install) takes about 45 seconds. On the same hardware, the full build using meson (meson setup -Doptimization=2 dir && meson compile -C dir && meson install -C dir) takes just about 7.5 seconds.
-rwxr-xr-xaux/chdir_meson_build_subdir.sh6
-rwxr-xr-xaux/redir_exe.sh6
-rw-r--r--conf/pam_conv1/meson.build25
-rw-r--r--doc/.gitignore2
l---------doc/adg/html/meson.build1
l---------doc/adg/meson.build1
-rw-r--r--doc/guide-html-meson.build32
-rw-r--r--doc/guide-meson.build90
-rwxr-xr-xdoc/install-html.sh7
-rw-r--r--doc/man/meson.build67
-rw-r--r--doc/meson.build26
l---------doc/mwg/html/meson.build1
l---------doc/mwg/meson.build1
l---------doc/sag/html/meson.build1
l---------doc/sag/meson.build1
-rw-r--r--doc/specs/meson.build42
-rw-r--r--examples/meson.build14
-rw-r--r--libpam/include/meson.build3
-rw-r--r--libpam/include/security/meson.build10
-rw-r--r--libpam/meson.build73
-rw-r--r--libpam_internal/meson.build19
-rw-r--r--libpam_misc/include/security/meson.build1
-rw-r--r--libpam_misc/meson.build40
-rw-r--r--libpamc/include/security/meson.build1
-rw-r--r--libpamc/meson.build36
-rw-r--r--meson.build627
-rw-r--r--meson_options.txt99
-rw-r--r--modules/meson.build51
-rw-r--r--modules/module-meson.build510
l---------modules/pam_access/meson.build1
l---------modules/pam_canonicalize_user/meson.build1
l---------modules/pam_debug/meson.build1
l---------modules/pam_deny/meson.build1
l---------modules/pam_echo/meson.build1
l---------modules/pam_env/meson.build1
l---------modules/pam_exec/meson.build1
l---------modules/pam_faildelay/meson.build1
l---------modules/pam_faillock/meson.build1
l---------modules/pam_filter/meson.build1
-rw-r--r--modules/pam_filter/upperLOWER/meson.build9
l---------modules/pam_ftp/meson.build1
l---------modules/pam_group/meson.build1
l---------modules/pam_issue/meson.build1
l---------modules/pam_keyinit/meson.build1
l---------modules/pam_lastlog/meson.build1
l---------modules/pam_limits/meson.build1
l---------modules/pam_listfile/meson.build1
l---------modules/pam_localuser/meson.build1
l---------modules/pam_loginuid/meson.build1
l---------modules/pam_mail/meson.build1
l---------modules/pam_mkhomedir/meson.build1
l---------modules/pam_motd/meson.build1
l---------modules/pam_namespace/meson.build1
l---------modules/pam_nologin/meson.build1
l---------modules/pam_permit/meson.build1
l---------modules/pam_pwhistory/meson.build1
l---------modules/pam_rhosts/meson.build1
l---------modules/pam_rootok/meson.build1
l---------modules/pam_securetty/meson.build1
l---------modules/pam_selinux/meson.build1
l---------modules/pam_sepermit/meson.build1
l---------modules/pam_setquota/meson.build1
l---------modules/pam_shells/meson.build1
l---------modules/pam_stress/meson.build1
l---------modules/pam_succeed_if/meson.build1
l---------modules/pam_time/meson.build1
l---------modules/pam_timestamp/meson.build1
l---------modules/pam_tty_audit/meson.build1
l---------modules/pam_umask/meson.build1
l---------modules/pam_unix/meson.build1
l---------modules/pam_userdb/meson.build1
l---------modules/pam_usertype/meson.build1
l---------modules/pam_warn/meson.build1
l---------modules/pam_wheel/meson.build1
l---------modules/pam_xauth/meson.build1
-rw-r--r--po/meson.build10
-rw-r--r--tests/meson.build47
-rw-r--r--xtests/meson.build70
78 files changed, 1973 insertions, 1 deletions
diff --git a/aux/chdir_meson_build_subdir.sh b/aux/chdir_meson_build_subdir.sh
new file mode 100755
index 00000000..69c32fcb
--- /dev/null
+++ b/aux/chdir_meson_build_subdir.sh
@@ -0,0 +1,6 @@
+#!/bin/sh -efu
+
+exe=$1; shift
+exe=$(readlink -ev -- "$exe")
+cd "$MESON_BUILD_SUBDIR"
+exec "$exe" "$@"
diff --git a/aux/redir_exe.sh b/aux/redir_exe.sh
new file mode 100755
index 00000000..3ab78e64
--- /dev/null
+++ b/aux/redir_exe.sh
@@ -0,0 +1,6 @@
+#!/bin/sh -efu
+# stdin stdout ...
+
+exec < "$1"; shift
+exec > "$1"; shift
+exec "$@"
diff --git a/conf/pam_conv1/meson.build b/conf/pam_conv1/meson.build
new file mode 100644
index 00000000..487acd6a
--- /dev/null
+++ b/conf/pam_conv1/meson.build
@@ -0,0 +1,25 @@
+pam_conv_y = custom_target(
+ 'pam_conv_y.[ch]',
+ input: 'pam_conv_y.y',
+ output: ['pam_conv_y.c', 'pam_conv_y.h'],
+ command: yacc_cmd,
+)
+
+pam_conv_l = custom_target(
+ 'pam_conv_l.c',
+ input: 'pam_conv_l.l',
+ output: 'pam_conv_l.c',
+ depends: pam_conv_y,
+ command: [prog_flex, '-o', '@OUTPUT@', '@INPUT@'],
+)
+
+executable(
+ 'pam_conv1',
+ sources: [pam_conv_l, pam_conv_y],
+ include_directories: [libpam_inc],
+ c_args: [
+ '-Wno-unused-function',
+ '-Wno-sign-compare',
+ ],
+ link_args: exe_link_args,
+)
diff --git a/doc/.gitignore b/doc/.gitignore
index 589288a9..cbfabdd7 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,5 +1,5 @@
pam.sgml
MODULES-SGML
/*/*.txt
-/*/html/
+/*/html/*.html
custom-man.xsl
diff --git a/doc/adg/html/meson.build b/doc/adg/html/meson.build
new file mode 120000
index 00000000..d6d90eaa
--- /dev/null
+++ b/doc/adg/html/meson.build
@@ -0,0 +1 @@
+../../guide-html-meson.build \ No newline at end of file
diff --git a/doc/adg/meson.build b/doc/adg/meson.build
new file mode 120000
index 00000000..2e19d830
--- /dev/null
+++ b/doc/adg/meson.build
@@ -0,0 +1 @@
+../guide-meson.build \ No newline at end of file
diff --git a/doc/guide-html-meson.build b/doc/guide-html-meson.build
new file mode 100644
index 00000000..e5c90812
--- /dev/null
+++ b/doc/guide-html-meson.build
@@ -0,0 +1,32 @@
+# -*- mode: meson -*-
+
+html = custom_target(
+ input: xml,
+ output: name + '.html',
+ command: [
+ prog_xsltproc,
+ '--nonet',
+ '--xinclude',
+ '--stringparam', 'base.dir', meson.current_build_dir(),
+ '--stringparam', 'root.filename', name,
+ '--stringparam', 'use.id.as.filename', '1',
+ '--stringparam', 'chunk.first.sections', '1',
+ '--stringparam', 'section.autolabel', '1',
+ '--stringparam', 'section.label.includes.component.label', '1',
+ '--stringparam', 'toc.max.depth', toc_max_depth,
+ '--stringparam', 'chunker.output.encoding', 'UTF-8',
+ html_stylesheet,
+ '@INPUT@',
+ ],
+ install: true,
+ install_dir: htmldir,
+ install_tag: 'doc',
+)
+
+meson.add_install_script(
+ install_html,
+ meson.current_build_dir(),
+ htmldir,
+ html,
+ install_tag: 'doc',
+)
diff --git a/doc/guide-meson.build b/doc/guide-meson.build
new file mode 100644
index 00000000..e29d16e2
--- /dev/null
+++ b/doc/guide-meson.build
@@ -0,0 +1,90 @@
+# -*- mode: meson -*-
+
+guide = fs.name(meson.current_source_dir()).to_upper()
+name = 'Linux-PAM_' + guide
+
+xml = files(name + '.xml')
+
+if guide == 'SAG'
+ toc_max_depth = '2'
+else
+ toc_max_depth = '3'
+endif
+
+
+run_command(
+ [prog_xmllint,
+ '--noent',
+ '--nonet',
+ '--noout',
+ '--xinclude',
+ '--relaxng', docbook_rng,
+ xml],
+ check: true,
+)
+
+
+html = custom_target(
+ input: xml,
+ output: name + '.html',
+ command: [
+ prog_xsltproc,
+ '-o', '@OUTPUT@',
+ '--nonet',
+ '--xinclude',
+ '--stringparam', 'generate.toc', 'book toc',
+ '--stringparam', 'section.autolabel', '1',
+ '--stringparam', 'section.label.includes.component.label', '1',
+ '--stringparam', 'toc.max.depth', toc_max_depth,
+ txt_stylesheet,
+ '@INPUT@',
+ ],
+)
+
+custom_target(
+ input: html,
+ output: name + '.txt',
+ command: [
+ redir_exe,
+ '@INPUT@',
+ '@OUTPUT@',
+ browser,
+ ],
+ install: true,
+ install_dir: docdir,
+ install_tag: 'doc',
+)
+
+
+fop = custom_target(
+ input: xml,
+ output: name + '.fop',
+ command: [
+ prog_xsltproc,
+ '-o', '@OUTPUT@',
+ '--nonet',
+ '--xinclude',
+ '--stringparam', 'generate.toc', 'book toc',
+ '--stringparam', 'section.autolabel', '1',
+ '--stringparam', 'section.label.includes.component.label', '1',
+ '--stringparam', 'toc.max.depth', toc_max_depth,
+ pdf_stylesheet,
+ '@INPUT@',
+ ],
+)
+
+custom_target(
+ input: fop,
+ output: name + '.pdf',
+ command: [
+ prog_fop,
+ '@INPUT@',
+ '@OUTPUT@',
+ ],
+ install: true,
+ install_dir: pdfdir,
+ install_tag: 'doc',
+)
+
+
+subdir('html')
diff --git a/doc/install-html.sh b/doc/install-html.sh
new file mode 100755
index 00000000..884fc27c
--- /dev/null
+++ b/doc/install-html.sh
@@ -0,0 +1,7 @@
+#!/bin/sh -eu
+
+cd "$1"; shift
+MESON_INSTALL_DESTDIR=${MESON_INSTALL_DESTDIR_PREFIX%$MESON_INSTALL_PREFIX}
+dest="$MESON_INSTALL_DESTDIR$1"; shift
+
+install -p -m644 -t "$dest" -- *.html
diff --git a/doc/man/meson.build b/doc/man/meson.build
new file mode 100644
index 00000000..b90b1578
--- /dev/null
+++ b/doc/man/meson.build
@@ -0,0 +1,67 @@
+foreach man: [['misc_conv.3', []],
+ ['pam.3', []],
+ ['pam_acct_mgmt.3', []],
+ ['pam_authenticate.3', []],
+ ['pam_chauthtok.3', []],
+ ['pam_close_session.3', []],
+ ['pam_conv.3', []],
+ ['pam_end.3', []],
+ ['pam_error.3', ['pam_verror.3']],
+ ['pam_fail_delay.3', []],
+ ['pam_get_authtok.3', ['pam_get_authtok_noverify.3', 'pam_get_authtok_verify.3']],
+ ['pam_get_data.3', []],
+ ['pam_get_item.3', []],
+ ['pam_get_user.3', []],
+ ['pam_getenv.3', []],
+ ['pam_getenvlist.3', []],
+ ['pam_info.3', ['pam_vinfo.3']],
+ ['pam_misc_drop_env.3', []],
+ ['pam_misc_paste_env.3', []],
+ ['pam_misc_setenv.3', []],
+ ['pam_open_session.3', []],
+ ['pam_prompt.3', ['pam_vprompt.3']],
+ ['pam_putenv.3', []],
+ ['pam_set_data.3', []],
+ ['pam_set_item.3', []],
+ ['pam_setcred.3', []],
+ ['pam_sm_acct_mgmt.3', []],
+ ['pam_sm_authenticate.3', []],
+ ['pam_sm_chauthtok.3', []],
+ ['pam_sm_close_session.3', []],
+ ['pam_sm_open_session.3', []],
+ ['pam_sm_setcred.3', []],
+ ['pam_start.3', []],
+ ['pam_strerror.3', []],
+ ['pam_syslog.3', ['pam_vsyslog.3']],
+ ['pam_xauth_data.3', []],
+ ['pam.conf.5', ['pam.d.5']],
+ ['pam.8', ['PAM.8']],
+ ]
+ xml = man[0] + '.xml'
+
+ run_command([prog_xmllint,
+ '--nonet',
+ '--noout',
+ '--xinclude',
+ '--relaxng', docbook_rng,
+ xml],
+ check: true)
+
+ custom_target(man[0],
+ input: xml,
+ output: man,
+ depends: custom_man_xsl,
+ command: [prog_xsltproc,
+ '-o', '@OUTPUT0@',
+ '--nonet',
+ '--xinclude',
+ '--path', meson.current_source_dir(),
+ stringparam_vendordir,
+ stringparam_profileconditions,
+ custom_man_xsl,
+ '@INPUT@'],
+ install: true,
+ install_dir: mandir / 'man' + man[0].substring(-1),
+ install_tag: 'man',
+ )
+endforeach
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 00000000..afe15851
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,26 @@
+custom_man_xsl = custom_target(
+ 'custom-man.xsl',
+ input: 'custom-man.xsl.in',
+ output: ['custom-man.xsl'],
+ command: [
+ redir_exe,
+ '@INPUT@',
+ '@OUTPUT@',
+ 'sed',
+ 's+MAN_STYLESHEET+' + man_stylesheet + '+g'
+ ]
+)
+
+install_data(
+ 'index.html',
+ install_dir: htmldir,
+ install_tag: 'doc',
+)
+
+install_html = files('install-html.sh')
+
+subdir('man')
+subdir('specs')
+subdir('sag')
+subdir('adg')
+subdir('mwg')
diff --git a/doc/mwg/html/meson.build b/doc/mwg/html/meson.build
new file mode 120000
index 00000000..d6d90eaa
--- /dev/null
+++ b/doc/mwg/html/meson.build
@@ -0,0 +1 @@
+../../guide-html-meson.build \ No newline at end of file
diff --git a/doc/mwg/meson.build b/doc/mwg/meson.build
new file mode 120000
index 00000000..2e19d830
--- /dev/null
+++ b/doc/mwg/meson.build
@@ -0,0 +1 @@
+../guide-meson.build \ No newline at end of file
diff --git a/doc/sag/html/meson.build b/doc/sag/html/meson.build
new file mode 120000
index 00000000..d6d90eaa
--- /dev/null
+++ b/doc/sag/html/meson.build
@@ -0,0 +1 @@
+../../guide-html-meson.build \ No newline at end of file
diff --git a/doc/sag/meson.build b/doc/sag/meson.build
new file mode 120000
index 00000000..2e19d830
--- /dev/null
+++ b/doc/sag/meson.build
@@ -0,0 +1 @@
+../guide-meson.build \ No newline at end of file
diff --git a/doc/specs/meson.build b/doc/specs/meson.build
new file mode 100644
index 00000000..4ddeef84
--- /dev/null
+++ b/doc/specs/meson.build
@@ -0,0 +1,42 @@
+parse_y = custom_target(
+ 'parse_y.[ch]',
+ input: 'parse_y.y',
+ output: ['parse_y.c', 'parse_y.h'],
+ command: yacc_cmd,
+)
+
+parse_l = custom_target(
+ 'parse_l.c',
+ input: 'parse_l.l',
+ output: 'parse_l.c',
+ depends: parse_y,
+ command: [prog_flex, '-o', '@OUTPUT@', '@INPUT@'],
+)
+
+padout = executable(
+ 'padout',
+ sources: [parse_l, parse_y],
+ include_directories: [libpam_inc],
+ c_args: [
+ '-Wno-unused-function',
+ '-Wno-sign-compare',
+ ],
+ link_args: exe_link_args,
+)
+
+custom_target(
+ 'draft-morgan-pam-current.txt',
+ input: 'draft-morgan-pam.raw',
+ output: 'draft-morgan-pam-current.txt',
+ command: [redir_exe, '@INPUT@', '@OUTPUT@', padout],
+ depends: padout,
+ install: true,
+ install_dir: docdir,
+ install_tag: 'doc',
+)
+
+install_data(
+ 'rfc86.0.txt',
+ install_dir: docdir,
+ install_tag: 'doc',
+)
diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644
index 00000000..4f5e85e0
--- /dev/null
+++ b/examples/meson.build
@@ -0,0 +1,14 @@
+foreach prog: ['xsh',
+ 'vpass',
+ 'blank',
+ 'check_user',
+ 'tty_conv'
+ ]
+ executable(
+ prog,
+ sources: prog + '.c',
+ link_args: exe_link_args,
+ include_directories: [libpamc_inc],
+ dependencies: [libpam_dep, libpam_misc_dep],
+ )
+endforeach
diff --git a/libpam/include/meson.build b/libpam/include/meson.build
new file mode 100644
index 00000000..1bf46f3b
--- /dev/null
+++ b/libpam/include/meson.build
@@ -0,0 +1,3 @@
+configure_file(output: 'config.h', configuration: cdata)
+
+subdir('security')
diff --git a/libpam/include/security/meson.build b/libpam/include/security/meson.build
new file mode 100644
index 00000000..1a712c9f
--- /dev/null
+++ b/libpam/include/security/meson.build
@@ -0,0 +1,10 @@
+install_headers([
+ '_pam_compat.h',
+ '_pam_macros.h',
+ '_pam_types.h',
+ 'pam_appl.h',
+ 'pam_ext.h',
+ 'pam_modules.h',
+ 'pam_modutil.h',
+ ],
+ install_dir: includedir)
diff --git a/libpam/meson.build b/libpam/meson.build
new file mode 100644
index 00000000..3e8a531c
--- /dev/null
+++ b/libpam/meson.build
@@ -0,0 +1,73 @@
+subdir('include')
+
+libpam_src = [
+ 'pam_account.c',
+ 'pam_audit.c',
+ 'pam_auth.c',
+ 'pam_data.c',
+ 'pam_delay.c',
+ 'pam_dispatch.c',
+ 'pam_dynamic.c',
+ 'pam_end.c',
+ 'pam_env.c',
+ 'pam_get_authtok.c',
+ 'pam_handlers.c',
+ 'pam_item.c',
+ 'pam_misc.c',
+ 'pam_modutil_check_user.c',
+ 'pam_modutil_cleanup.c',
+ 'pam_modutil_getgrgid.c',
+ 'pam_modutil_getgrnam.c',
+ 'pam_modutil_getlogin.c',
+ 'pam_modutil_getpwnam.c',
+ 'pam_modutil_getpwuid.c',
+ 'pam_modutil_getspnam.c',
+ 'pam_modutil_ingroup.c',
+ 'pam_modutil_ioloop.c',
+ 'pam_modutil_priv.c',
+ 'pam_modutil_sanitize.c',
+ 'pam_modutil_searchkey.c',
+ 'pam_password.c',
+ 'pam_prelude.c',
+ 'pam_session.c',
+ 'pam_start.c',
+ 'pam_strerror.c',
+ 'pam_syslog.c',
+ 'pam_vprompt.c',
+]
+
+libpam_version = '0.85.1'
+libpam_map = 'libpam.map'
+libpam_map_path = meson.current_source_dir() / libpam_map
+
+libpam_link_deps = [libpam_map]
+libpam_link_args = ['-Wl,--version-script=' + libpam_map_path]
+
+libpam = shared_library(
+ 'pam',
+ sources: libpam_src,
+ include_directories: [libpam_inc],
+ c_args: [
+ '-DDEFAULT_MODULE_PATH="@0@/"'.format(securedir),
+ '-DLIBPAM_COMPILE',
+ ],
+ dependencies: [libpam_internal_dep, libaudit, libeconf, libdl, libintl],
+ link_depends: libpam_link_deps,
+ link_args: libpam_link_args,
+ version: libpam_version,
+ install: true,
+)
+
+libpam_dep = declare_dependency(
+ include_directories: [libpam_inc],
+ link_with: [libpam],
+)
+
+pkgconfig.generate(
+ libpam,
+ description: 'The primary Linux-PAM library. It is used by PAM modules and PAM-aware applications.',
+ name: 'PAM',
+ filebase: 'pam',
+ version: meson.project_version(),
+ url: 'http://www.linux-pam.org/'
+)
diff --git a/libpam_internal/meson.build b/libpam_internal/meson.build
new file mode 100644
index 00000000..5d03877a
--- /dev/null
+++ b/libpam_internal/meson.build
@@ -0,0 +1,19 @@
+libpam_internal_src = [
+ 'pam_debug.c',
+ 'pam_econf.c',
+ 'pam_line.c',
+]
+
+libpam_internal_inc = include_directories('include')
+
+libpam_internal = static_library(
+ 'pam_internal',
+ sources: libpam_internal_src,
+ include_directories: [libpam_internal_inc, libpam_inc],
+ dependencies: libeconf,
+)
+
+libpam_internal_dep = declare_dependency(
+ include_directories: [libpam_internal_inc],
+ link_with: [libpam_internal],
+)
diff --git a/libpam_misc/include/security/meson.build b/libpam_misc/include/security/meson.build
new file mode 100644
index 00000000..4330915e
--- /dev/null
+++ b/libpam_misc/include/security/meson.build
@@ -0,0 +1 @@
+install_headers('pam_misc.h', install_dir: includedir)
diff --git a/libpam_misc/meson.build b/libpam_misc/meson.build
new file mode 100644
index 00000000..e0bb30f5
--- /dev/null
+++ b/libpam_misc/meson.build
@@ -0,0 +1,40 @@
+subdir('include/security')
+
+libpam_misc_src = [
+ 'help_env.c',
+ 'misc_conv.c',
+]
+
+libpam_misc_inc = include_directories('include')
+
+libpam_misc_version = '0.82.1'
+libpam_misc_map = 'libpam_misc.map'
+libpam_misc_map_path = meson.current_source_dir() / libpam_misc_map
+
+libpam_misc_link_deps = [libpam_misc_map]
+libpam_misc_link_args = ['-Wl,--version-script=' + libpam_misc_map_path]
+
+libpam_misc = shared_library(
+ 'pam_misc',
+ sources: libpam_misc_src,
+ include_directories: [libpam_misc_inc, libpamc_inc],
+ dependencies: [libpam_internal_dep, libpam_dep],
+ link_depends: libpam_misc_link_deps,
+ link_args: libpam_misc_link_args,
+ version: libpam_misc_version,
+ install: true,
+)
+
+libpam_misc_dep = declare_dependency(
+ include_directories: [libpam_misc_inc],
+ link_with: [libpam_misc],
+)
+
+pkgconfig.generate(
+ libpam_misc,
+ description: 'Miscellaneous functions that make the job of writing PAM-aware applications easier.',
+ name: 'pam_misc',
+ filebase: 'pam_misc',
+ version: meson.project_version(),
+ url: 'http://www.linux-pam.org/'
+)
diff --git a/libpamc/include/security/meson.build b/libpamc/include/security/meson.build
new file mode 100644
index 00000000..f82fea09
--- /dev/null
+++ b/libpamc/include/security/meson.build
@@ -0,0 +1 @@
+install_headers('pam_client.h', install_dir: includedir)
diff --git a/libpamc/meson.build b/libpamc/meson.build
new file mode 100644
index 00000000..f5da0679
--- /dev/null
+++ b/libpamc/meson.build
@@ -0,0 +1,36 @@
+subdir('include/security')
+
+libpamc_src = [
+ 'pamc_client.c',
+ 'pamc_converse.c',
+ 'pamc_load.c',
+]
+
+libpamc_inc = include_directories('include')
+
+libpamc_version = '0.82.1'
+libpamc_map = 'libpamc.map'
+libpamc_map_path = meson.current_source_dir() / libpamc_map
+
+libpamc_link_deps = [libpamc_map]
+libpamc_link_args = ['-Wl,--version-script=' + libpamc_map_path]
+
+libpamc = shared_library(
+ 'pamc',
+ sources: libpamc_src,
+ include_directories: [libpam_inc, libpamc_inc],
+ dependencies: [libpam_internal_dep],
+ link_depends: libpamc_link_deps,
+ link_args: libpamc_link_args,
+ version: libpamc_version,
+ install: true,
+)
+
+pkgconfig.generate(
+ libpamc,
+ description: 'The PAM client API library and binary prompt support. Rarely used.',
+ name: 'libpamc',
+ filebase: 'pamc',
+ version: meson.project_version(),
+ url: 'http://www.linux-pam.org/'
+)
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..107fe1d1
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,627 @@
+project('Linux-PAM', 'c',
+ version: '1.6.1',
+ license: 'BSD-3-Clause OR GPL-2.0-or-later',
+ default_options: [
+ 'b_pie=true',
+ 'prefix=/usr',
+ 'warning_level=2',
+ ],
+ meson_version: '>= 0.62.0',
+)
+
+fs = import('fs')
+pkgconfig = import('pkgconfig')
+
+
+prefixdir = get_option('prefix')
+if not fs.is_absolute(prefixdir)
+ error('Prefix is not absolute: "@0@"'.format(prefixdir))
+endif
+datadir = prefixdir / get_option('datadir')
+includedir = prefixdir / get_option('includedir') / 'security'
+libdir = prefixdir / get_option('libdir')
+localedir = prefixdir / get_option('localedir')
+localstatedir = '/' / get_option('localstatedir')
+mandir = prefixdir / get_option('mandir')
+sbindir = prefixdir / get_option('sbindir')
+sysconfdir = prefixdir / get_option('sysconfdir')
+securedir = get_option('securedir')
+if securedir == ''
+ securedir = libdir / 'security'
+endif
+
+
+cc = meson.get_compiler('c')
+cdata = configuration_data()
+
+null_dep = dependency('', required: false)
+
+cdata.set('_GNU_SOURCE', 1)
+cdata.set_quoted('PACKAGE', meson.project_name())
+cdata.set_quoted('PAM_VERSION', meson.project_version())
+cdata.set('UNUSED', '__attribute__((__unused__))')
+cdata.set('PAM_NO_HEADER_FUNCTIONS', 1, description: 'Disable function bodies in headers')
+cdata.set_quoted('SYSCONFDIR', sysconfdir)
+cdata.set_quoted('LTDIR', '')
+# used in configure_file() only, so not quoted
+cdata.set('sbindir', sbindir)
+
+cdata.set('PAM_DEBUG', get_option('pam-debug') ? 1 : false)
+cdata.set('PAM_LOCKING', get_option('pamlocking') ? 1 : false)
+cdata.set('PAM_READ_BOTH_CONFS', get_option('read-both-confs') ? 1 : false)
+cdata.set10('DEFAULT_USERGROUPS_SETTING', get_option('usergroups'))
+cdata.set('PAM_USERTYPE_UIDMIN', get_option('uidmin'))
+cdata.set('PAM_USERTYPE_OVERFLOW_UID', get_option('kernel-overflow-uid'))
+cdata.set('PAM_MISC_CONV_BUFSIZE', get_option('misc-conv-bufsize'))
+
+cdata.set_quoted('_PAM_ISA',
+ get_option('isadir') != '' ? get_option('isadir') : '../..' / fs.name(libdir) / 'security')
+
+docdir = get_option('docdir')
+if docdir == ''
+ docdir = datadir / 'doc' / meson.project_name()
+endif
+
+htmldir = get_option('htmldir')
+if htmldir == ''
+ htmldir = docdir
+endif
+
+pdfdir = get_option('pdfdir')
+if pdfdir == ''
+ pdfdir = docdir
+endif
+
+sconfigdir = get_option('sconfigdir')
+if sconfigdir == ''
+ sconfigdir = sysconfdir / 'security'
+endif
+cdata.set_quoted('SCONFIG_DIR', sconfigdir)
+# used in configure_file() only, so not quoted
+cdata.set('SCONFIGDIR', sconfigdir)
+
+vendordir = get_option('vendordir')
+if get_option('vendordir') == ''
+ vendor_sconfigdir = sconfigdir
+ stringparam_vendordir = []
+ stringparam_profileconditions = 'without_vendordir'
+else
+ vendor_sconfigdir = vendordir / 'security'
+ cdata.set_quoted('VENDORDIR', vendordir)
+ cdata.set_quoted('VENDOR_SCONFIG_DIR', vendor_sconfigdir)
+ stringparam_vendordir = ['--stringparam', 'vendordir', vendordir]
+ stringparam_profileconditions = 'with_vendordir'
+endif
+
+randomdev_option = get_option('randomdev')
+if randomdev_option == '' or randomdev_option == 'yes'
+ cdata.set_quoted('PAM_PATH_RANDOMDEV', '/dev/urandom')
+elif randomdev_option != 'no'
+ cdata.set_quoted('PAM_PATH_RANDOMDEV', randomdev_option)
+endif
+
+xauth_option = get_option('xauth')
+if xauth_option != '' and xauth_option != '/usr/X11R6/bin/xauth'
+ cdata.set_quoted('PAM_PATH_XAUTH', xauth_option)
+endif
+
+
+# meson defines -D_STRIP_FILE_OFFSET_BITS=64 even for 64-bit systems, this
+# forces glibc to use function names with the same semantics but with "64"
+# suffix, and that leads to discrepancies in the build artefacts produced
+# by different build systems.
+if cc.sizeof('long') >= 8
+ add_project_arguments(
+ '-U_FILE_OFFSET_BITS',
+ language: 'c')
+endif
+
+
+try_cc_flags = [
+ '-Wbad-function-cast',
+ '-Wcast-align',
+ '-Wcast-align=strict',
+ '-Wcast-qual',
+ '-Wdeprecated',
+ '-Wformat=2',
+ '-Winit-self',
+ '-Wmain',
+ '-Wmissing-declarations',
+ '-Wmissing-format-attribute',
+ '-Wmissing-prototypes',
+ '-Wnull-dereference',
+ '-Wpointer-arith',
+ '-Wreturn-type',
+ '-Wshadow',
+ '-Wstrict-prototypes',
+ '-Wundef',
+ '-Wuninitialized',
+ '-Wunused',
+ '-Wwrite-strings',
+]
+add_project_arguments(
+ cc.get_supported_arguments(try_cc_flags),
+ language: 'c')
+
+add_project_link_arguments(
+ # --as-needed and --no-undefined are enabled by default
+ cc.get_supported_link_arguments([
+ '-Wl,--fatal-warnings',
+ '-Wl,-O1',
+ ]),
+ language: 'c')
+
+exe_link_args = cc.get_supported_link_arguments([
+ '-Wl,-z,relro',
+ '-Wl,-z,now',
+])
+
+
+check_headers = [
+ 'crypt.h',
+ 'paths.h',
+ 'sys/random.h',
+]
+foreach h: check_headers
+ if cc.has_header(h)
+ cdata.set('HAVE_' + h.underscorify().to_upper(), 1)
+ endif
+endforeach
+
+
+check_functions = [
+ ['close_range', '#include <unistd.h>'],
+ ['explicit_bzero', '#include <string.h>'],
+ ['getdomainname', '#include <unistd.h>'],
+ ['getgrgid_r', '#include <grp.h>'],
+ ['getgrnam_r', '#include <grp.h>'],
+ ['getgrouplist', '#include <grp.h>'],
+ ['getmntent_r', '#include <mntent.h>'],
+ ['getpwnam', '#include <pwd.h>'],
+ ['getpwnam_r', '#include <pwd.h>'],
+ ['getpwuid_r', '#include <pwd.h>'],
+ ['getrandom', '#include <sys/random.h>'],
+ ['getspnam_r', '#include <shadow.h>'],
+ ['getutent_r', '#include <utmp.h>'],
+ ['innetgr', '#include <netdb.h>'],
+ ['memset_explicit', '#include <string.h>'],
+ ['quotactl', '#include <sys/quota.h>'],
+ ['ruserok', '#include <netdb.h>'],
+ ['ruserok_af', '#include <netdb.h>'],
+ ['unshare', '#include <sched.h>'],
+]
+foreach ident: check_functions
+ if cc.has_function(ident[0], prefix: ident[1], args: '-D_GNU_SOURCE')
+ cdata.set('HAVE_' + ident[0].to_upper(), 1)
+ endif
+endforeach
+
+enable_pam_keyinit = cc.sizeof('__NR_keyctl', prefix: '#include <sys/syscall.h>') > 0
+
+if get_option('mailspool') != ''
+ cdata.set_quoted('PAM_PATH_MAILDIR', get_option('mailspool'))
+else
+ have = cc.sizeof('_PATH_MAILDIR', prefix: '#include <paths.h>') > 0
+ cdata.set('PAM_PATH_MAILDIR', have ? '_PATH_MAILDIR' : '"/var/spool/mail"')
+endif
+
+
+libdl = dependency('dl')
+
+
+if not get_option('i18n').disabled()
+ libintl = dependency('intl', required: get_option('i18n'))
+ if libintl.found()
+ cdata.set('ENABLE_NLS', 1)
+ cdata.set_quoted('LOCALEDIR', localedir)
+ foreach f: ['bindtextdomain',
+ 'dngettext',
+ ]
+ if cc.has_function(f, prefix: '#include <libintl.h>',
+ args: '-D_GNU_SOURCE',
+ dependencies: libintl)
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ endif
+ endforeach
+ endif
+endif
+
+
+libaudit = dependency('audit', required: get_option('audit'))
+if libaudit.found()
+ cdata.set('HAVE_LIBAUDIT', 1)
+ foreach ident: ['struct audit_tty_status']
+ if cc.sizeof(ident, prefix: '#include <libaudit.h>') > 0
+ cdata.set('HAVE_' + ident.underscorify().to_upper(), 1)
+ endif
+ endforeach
+ foreach ident: [['struct audit_tty_status', 'log_passwd']]
+ if cc.has_member(ident[0], ident[1],
+ prefix: '#include <libaudit.h>',
+ args: '-D_GNU_SOURCE')
+ cdata.set('HAVE_@0@_@1@'.format(ident[0], ident[1]).underscorify().to_upper(), 1)
+ endif
+ endforeach
+endif
+
+
+libcrypt = dependency('libcrypt', 'libxcrypt', required: false)
+if not libcrypt.found()
+ libcrypt = cc.find_library('crypt')
+endif
+crypt_h = cdata.get('HAVE_CRYPT_H') == 1 ? '''#include <crypt.h>''' : '''#include <unistd.h>'''
+foreach f: ['crypt_r']
+ if cc.has_function(f, prefix: crypt_h,
+ args: '-D_GNU_SOURCE',
+ dependencies: libcrypt)
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ endif
+endforeach
+
+
+libeconf = dependency('libeconf', version: '>= 0.5.0', required: get_option('econf'))
+if libeconf.found()
+ cdata.set('USE_ECONF', 1)
+ have_econf_readconfig = true
+ if stringparam_vendordir != []
+ stringparam_profileconditions += ';with_vendordir_and_with_econf'
+ endif
+
+ foreach f: ['econf_newKeyFile_with_options',
+ 'econf_readConfigWithCallback',
+ ]
+ if cc.has_function(f, prefix: '#include <libeconf.h>',
+ args: '-D_GNU_SOURCE',
+ dependencies: libeconf)
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ else
+ have_econf_readconfig = false
+ endif
+ if have_econf_readconfig
+ cdata.set('HAVE_ECONF_READCONFIG', 1)
+ endif
+ endforeach
+else
+ if stringparam_vendordir != []
+ stringparam_profileconditions += ';with_vendordir_and_without_econf'
+ endif
+endif
+
+
+libselinux = dependency('libselinux', required: get_option('selinux'))
+if libselinux.found()
+ cdata.set('WITH_SELINUX', 1)
+ foreach f: ['getseuser', 'setkeycreatecon']
+ if cc.has_function(f, prefix: '#include <selinux/selinux.h>',
+ dependencies: libselinux)
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ endif
+ endforeach
+endif
+
+
+if get_option('openssl').disabled()
+ libcrypto = null_dep
+else
+ libcrypto = dependency('libcrypto', required: false)
+endif
+if libcrypto.found() and cc.has_function('EVP_MAC_CTX_new',
+ prefix: '#include <openssl/hmac.h>',
+ dependencies: libcrypto)
+ cdata.set('WITH_OPENSSL', 1)
+ stringparam_profileconditions += ';openssl_hmac'
+else
+ stringparam_profileconditions += ';no_openssl_hmac'
+endif
+
+
+libsystemd = dependency('libsystemd', version: '>= 254', required: get_option('logind'))
+cdata.set('USE_LOGIND', libsystemd.found() ? 1 : false)
+
+systemdunitdir = get_option('systemdunitdir')
+if systemdunitdir == ''
+ systemdunitdir = prefixdir / 'lib' / 'systemd' / 'system'
+ systemd = dependency('systemd', required: false)
+ if systemd.found()
+ systemdunitdir = systemd.get_variable(
+ pkgconfig: 'systemdsystemunitdir',
+ default_value: systemdunitdir,
+ )
+ endif
+endif
+
+
+feature_pam_userdb = get_option('pam_userdb')
+if feature_pam_userdb.disabled()
+ enable_pam_userdb = false
+else
+ use_db = get_option('db')
+ have = false
+ if use_db == 'db' or use_db == 'auto'
+ db_uniquename = get_option('db-uniquename')
+ name = 'db' + db_uniquename
+ libdb = cc.find_library(name, required: false)
+ if libdb.found()
+ foreach f: ['dbm_open' + db_uniquename, 'dbm_open']
+ have = cc.links('''
+ #define _GNU_SOURCE
+ #define DB_DBM_HSEARCH 1
+ #define HAVE_DBM 1
+ #include <db.h>
+ int main(void) {return !@0@("", 0, 0);}
+ '''.format(f),
+ args: '-l' + name,
+ name: '@0@ in @1@'.format(f, 'lib' + name))
+ if have
+ break
+ endif
+ endforeach
+ if have
+ use_db = 'db'
+ cdata.set('HAVE_DB_H', 1)
+ endif
+ endif
+ endif
+ if use_db == 'gdbm' or use_db == 'auto'
+ libdb = cc.find_library('gdbm', required: false)
+ if libdb.found()
+ have = cc.has_function('gdbm_store', prefix: '#include <gdbm.h>',
+ args: '-D_GNU_SOURCE', dependencies: libdb)
+ if have
+ use_db = 'gdbm'
+ cdata.set('HAVE_GDBM_H', 1)
+ endif
+ endif
+ endif
+ if use_db == 'ndbm' or use_db == 'auto'
+ libdb = cc.find_library('ndbm', required: false)
+ if libdb.found()
+ have = cc.has_function('dbm_store', prefix: '#include <ndbm.h>',
+ args: '-D_GNU_SOURCE', dependencies: libdb)
+ if have
+ use_db = 'ndbm'
+ cdata.set('HAVE_NDBM_H', 1)
+ endif
+ endif
+ endif
+ if not have and feature_pam_userdb.enabled()
+ error('pam_userdb module is enabled but the db library is not available')
+ endif
+ enable_pam_userdb = have
+endif
+
+
+feature_pam_lastlog = get_option('pam_lastlog')
+if feature_pam_lastlog.disabled()
+ enable_pam_lastlog = false
+else
+ libutil = cc.find_library('util', required: false)
+ have = cc.has_function('logwtmp', prefix: '#include <utmp.h>',
+ dependencies: libutil)
+ if not have and feature_pam_lastlog.enabled()
+ error('pam_lastlog module is enabled but logwtmp() is not available')
+ endif
+ enable_pam_lastlog = have
+endif
+
+
+enable_pam_unix = not get_option('pam_unix').disabled()
+if enable_pam_unix
+ if get_option('lckpwdf')
+ cdata.set('USE_LCKPWDF', 1)
+ foreach f: ['lckpwdf']
+ if cc.has_function(f, prefix: '#include <shadow.h>')
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ endif
+ endforeach
+ endif
+
+ feature_nis = get_option('nis')
+ if feature_nis.disabled()
+ enable_nis = false
+ libtirpc = null_dep
+ libnsl = null_dep
+ else
+ # If libtirpc is available, prefer that over the system implementation.
+ libtirpc = dependency('libtirpc', required: false)
+ enable_nis = true
+ foreach f: ['getrpcport',
+ 'rpcb_getaddr',
+ ]
+ if cc.has_function(f, prefix: '#include <rpc/rpc.h>',
+ dependencies: libtirpc)
+ cdata.set('HAVE_' + f.to_upper(), 1)
+ cdata.set('HAVE_DECL_' + f.to_upper(), 1)
+ endif
+ endforeach
+
+ libnsl = dependency('libnsl', required: feature_nis)
+ enable_nis = libnsl.found()
+
+ if enable_nis
+ foreach f: ['yp_bind',
+ 'yp_get_default_domain',
+ 'yp_match',
+ 'yp_unbind',
+ ]
+ if not cc.has_function(f, prefix: '''#include <rpcsvc/ypclnt.h>
+ #include <rpcsvc/yp_prot.h>''',
+ dependencies: [libnsl, libtirpc])
+ enable_nis = false
+ libnsl = null_dep
+ break
+ endif
+ endforeach
+ endif
+
+ if enable_nis
+ cdata.set('HAVE_NIS', 1)
+ elif feature_nis.enabled()
+ error('NIS is enabled but required interfaces are not available')
+ endif
+ endif
+endif
+
+
+feature_docs = get_option('docs')
+enable_docs = not feature_docs.disabled()
+if enable_docs
+ prog_xsltproc = find_program(
+ 'xsltproc',
+ required: feature_docs,
+ disabler: true,
+ )
+ prog_xmllint = find_program(
+ 'xmllint',
+ required: feature_docs,
+ disabler: true,
+ )
+ prog_w3m = find_program(
+ 'w3m',
+ required: false,
+ )
+ if prog_w3m.found()
+ browser = [prog_w3m, '-T', 'text/html', '-dump']
+ else
+ prog_elinks = find_program(
+ 'elinks',
+ required: feature_docs,
+ disabler: true,
+ )
+ browser = [prog_elinks, '-no-numbering', '-no-references', '-dump']
+ endif
+ prog_fop = find_program(
+ 'fop',
+ required: feature_docs,
+ disabler: true,
+ )
+
+ prog_xmlcatalog = find_program(
+ 'xmlcatalog',
+ required: feature_docs,
+ disabler: true,
+ )
+ xml_catalog = get_option('xml-catalog')
+ if xml_catalog == ''
+ xml_catalog = '/etc/xml/catalog'
+ endif
+
+ have = prog_xmlcatalog.found() and run_command(
+ ['test', '-f', xml_catalog],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ xml_catalog = disabler()
+ endif
+
+ docbook_rng = get_option('docbook-rng')
+ have = run_command(
+ [prog_xmlcatalog, '--noout', xml_catalog, docbook_rng],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ docbook_rng = disabler()
+ endif
+
+ html_stylesheet = get_option('html-stylesheet')
+ have = run_command(
+ [prog_xmlcatalog, '--noout', xml_catalog, html_stylesheet],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ html_stylesheet = disabler()
+ endif
+
+ txt_stylesheet = get_option('txt-stylesheet')
+ have = run_command(
+ [prog_xmlcatalog, '--noout', xml_catalog, txt_stylesheet],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ txt_stylesheet = disabler()
+ endif
+
+ man_stylesheet = get_option('man-stylesheet')
+ have = run_command(
+ [prog_xmlcatalog, '--noout', xml_catalog, man_stylesheet],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ man_stylesheet = disabler()
+ endif
+
+ pdf_stylesheet = get_option('pdf-stylesheet')
+ have = run_command(
+ [prog_xmlcatalog, '--noout', xml_catalog, pdf_stylesheet],
+ check: feature_docs.enabled()
+ ).returncode() == 0
+ if not have
+ pdf_stylesheet = disabler()
+ endif
+
+ stringparam_profileconditions = [
+ '--stringparam',
+ 'profile.condition',
+ stringparam_profileconditions
+ ]
+else
+ prog_xsltproc = disabler()
+ prog_xmllint = disabler()
+ prog_fop = disabler()
+ browser = disabler()
+ custom_man_xsl = disabler()
+ docbook_rng = disabler()
+ html_stylesheet = disabler()
+ man_stylesheet = disabler()
+ txt_stylesheet = disabler()
+endif
+
+
+prog_flex = find_program(
+ 'flex',
+ required: false,
+ disabler: true,
+)
+
+yacc_cmd = []
+prog_yacc = find_program(
+ 'bison',
+ required: false,
+)
+if prog_yacc.found()
+ yacc_cmd = [prog_yacc, '-o', '@OUTPUT0@', '--defines=@OUTPUT1@', '@INPUT@']
+else
+ prog_yacc = find_program(
+ 'byacc',
+ required: false,
+ disabler: true,
+ )
+ yacc_cmd = [prog_yacc, '-o', '@OUTPUT0@', '-H', '@OUTPUT1@', '@INPUT@']
+endif
+
+
+redir_exe = files('aux' / 'redir_exe.sh')
+chdir_meson_build_subdir = files('aux' / 'chdir_meson_build_subdir.sh')
+
+
+libpam_private_inc = include_directories('libpam')
+libpam_inc = include_directories('libpam' / 'include')
+
+
+subdir('po')
+subdir('libpam_internal')
+subdir('libpam')
+subdir('libpamc')
+subdir('libpam_misc')
+if enable_docs
+ subdir('doc')
+endif
+subdir('tests')
+subdir('modules')
+subdir('conf' / 'pam_conv1')
+if get_option('examples')
+ subdir('examples')
+endif
+if get_option('xtests')
+ subdir('xtests')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..914ab462
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,99 @@
+# -*- mode: meson -*-
+
+option('i18n', type: 'feature', value: 'auto',
+ description: 'i18n support')
+option('docs', type: 'feature', value: 'auto',
+ description: 'Generate and install documentation')
+option('audit', type: 'feature', value: 'auto',
+ description: 'audit support')
+option('econf', type: 'feature', value: 'auto',
+ description: 'libeconf support')
+option('logind', type: 'feature', value: 'auto',
+ description: 'logind support in pam_issue and pam_timestamp')
+option('openssl', type: 'feature', value: 'disabled',
+ description: 'Use OpenSSL crypto libraries in pam_timestamp')
+option('selinux', type: 'feature', value: 'auto',
+ description: 'SELinux support')
+option('nis', type: 'feature', value: 'auto',
+ description: 'NIS/YP support in pam_unix')
+
+option('examples', type: 'boolean', value: true,
+ description: 'Build examples')
+option('lckpwdf', type: 'boolean', value: true,
+ description: 'Use lckpwdf function in pam_unix')
+option('pam-debug', type: 'boolean', value: false,
+ description: 'Save debugging information into pam-debug.log')
+option('pamlocking', type: 'boolean', value: false,
+ description: 'Observe a global authentication lock')
+option('read-both-confs', type: 'boolean', value: false,
+ description: 'Read both /etc/pam.d and /etc/pam.conf files')
+option('usergroups', type: 'boolean', value: false,
+ description: 'usergroups option default in pam_umask')
+option('xtests', type: 'boolean', value: false,
+ description: 'Build xtests')
+
+option('misc-conv-bufsize', type: 'integer', value: 4096,
+ description: 'Size of input buffer for misc_conv() conversation function')
+option('kernel-overflow-uid', type: 'integer', value: 65534,
+ description: 'Linux kernel overflow uid')
+option('uidmin', type: 'integer', value: 1000,
+ description: 'Default value for regular user min uid')
+
+option('docbook-rng',
+ type: 'string',
+ value: 'http://docbook.org/xml/5.0/rng/docbookxi.rng',
+ description: 'RNG file for checking XML files')
+option('html-stylesheet',
+ type: 'string',
+ value: 'http://docbook.sourceforge.net/release/xsl-ns/current/html/chunk.xsl',
+ description: 'html stylesheet path')
+option('man-stylesheet',
+ type: 'string',
+ value: 'http://docbook.sourceforge.net/release/xsl-ns/current/manpages/profile-docbook.xsl',
+ description: 'man stylesheet path')
+option('pdf-stylesheet',
+ type: 'string',
+ value: 'http://docbook.sourceforge.net/release/xsl-ns/current/fo/docbook.xsl',
+ description: 'pdf stylesheet path')
+option('txt-stylesheet',
+ type: 'string',
+ value: 'http://docbook.sourceforge.net/release/xsl-ns/current/html/docbook.xsl',
+ description: 'txt stylesheet path')
+option('xml-catalog', type: 'string',
+ description: 'xml catalog path')
+
+option('docdir', type: 'string',
+ description: 'documentation directory')
+option('htmldir', type: 'string',
+ description: 'HTML documentation directory')
+option('pdfdir', type: 'string',
+ description: 'PDF documentation directory')
+
+option('isadir', type: 'string',
+ description: 'Arch-specific PAM modules directory, relative to SECUREDIR')
+option('securedir', type: 'string',
+ description: 'PAM modules directory')
+option('sconfigdir', type: 'string',
+ description: 'PAM module configuration files directory')
+option('systemdunitdir', type: 'string',
+ description: 'systemd service directory')
+option('mailspool', type: 'string',
+ description: 'Mail spool directory')
+option('xauth', type: 'string',
+ description: 'Additional path to check for xauth when it is called from pam_xauth')
+option('randomdev', type: 'string',
+ description: 'Random device to use instead of /dev/urandom')
+option('vendordir', type: 'string',
+ description: 'Distribution provided configuration files directory')
+
+option('pam_userdb', type: 'feature', value: 'auto',
+ description: 'pam_userdb module')
+option('db', type: 'combo', choices: ['db', 'gdbm', 'ndbm', 'auto'],
+ value: 'auto')
+option('db-uniquename', type: 'string',
+ description: 'Unique name for db libraries and functions')
+
+option('pam_lastlog', type: 'feature', value: 'disabled',
+ description: 'pam_lastlog module')
+option('pam_unix', type: 'feature', value: 'auto',
+ description: 'pam_unix module')
diff --git a/modules/meson.build b/modules/meson.build
new file mode 100644
index 00000000..20cebdbb
--- /dev/null
+++ b/modules/meson.build
@@ -0,0 +1,51 @@
+pam_module_map = 'modules.map'
+pam_module_map_path = meson.current_source_dir() / pam_module_map
+
+pam_module_link_deps = ['..' / pam_module_map]
+pam_module_link_args = ['-Wl,--version-script=' + pam_module_map_path]
+
+subdir('pam_access')
+subdir('pam_canonicalize_user')
+subdir('pam_debug')
+subdir('pam_deny')
+subdir('pam_echo')
+subdir('pam_env')
+subdir('pam_exec')
+subdir('pam_faildelay')
+subdir('pam_faillock')
+subdir('pam_filter')
+subdir('pam_ftp')
+subdir('pam_group')
+subdir('pam_issue')
+subdir('pam_keyinit')
+subdir('pam_lastlog')
+subdir('pam_limits')
+subdir('pam_listfile')
+subdir('pam_localuser')
+subdir('pam_loginuid')
+subdir('pam_mail')
+subdir('pam_mkhomedir')
+subdir('pam_motd')
+subdir('pam_namespace')
+subdir('pam_nologin')
+subdir('pam_permit')
+subdir('pam_pwhistory')
+subdir('pam_rhosts')
+subdir('pam_rootok')
+subdir('pam_securetty')
+subdir('pam_selinux')
+subdir('pam_sepermit')
+subdir('pam_setquota')
+subdir('pam_shells')
+subdir('pam_stress')
+subdir('pam_succeed_if')
+subdir('pam_time')
+subdir('pam_timestamp')
+subdir('pam_tty_audit')
+subdir('pam_umask')
+subdir('pam_unix')
+subdir('pam_userdb')
+subdir('pam_usertype')
+subdir('pam_warn')
+subdir('pam_wheel')
+subdir('pam_xauth')
diff --git a/modules/module-meson.build b/modules/module-meson.build
new file mode 100644
index 00000000..3804221e
--- /dev/null
+++ b/modules/module-meson.build
@@ -0,0 +1,510 @@
+# -*- mode: meson -*-
+
+module = fs.name(meson.current_source_dir())
+
+# pam_module.so
+
+pam_module_src = [module + '.c']
+pam_module_c_args = []
+pam_module_deps = [libpam_internal_dep, libpam_dep]
+
+if module == 'pam_env'
+ pam_module_deps += [libeconf]
+endif
+if module == 'pam_faillock'
+ pam_module_src += ['faillock.c', 'faillock_config.c']
+ pam_module_deps += [libaudit]
+endif
+if module == 'pam_issue'
+ pam_module_deps += [libsystemd]
+endif
+if module == 'pam_keyinit'
+ if not enable_pam_keyinit
+ subdir_done()
+ endif
+endif
+if module == 'pam_lastlog'
+ if not enable_pam_lastlog
+ subdir_done()
+ endif
+ pam_module_deps += [libutil]
+endif
+if module == 'pam_limits'
+ limits_conf_dir = sconfigdir / 'limits.d'
+ pam_module_c_args += ['-DLIMITS_FILE_DIR="@0@"'.format(limits_conf_dir)]
+ pam_module_deps += [libsystemd]
+endif
+if module == 'pam_loginuid'
+ pam_module_deps += [libaudit]
+endif
+if module == 'pam_mkhomedir'
+ pam_module_c_args += ['-DMKHOMEDIR_HELPER="@0@"'.format(sbindir / 'mkhomedir_helper')]
+endif
+if module == 'pam_namespace'
+ if cdata.get('HAVE_UNSHARE', 0) == 0
+ subdir_done()
+ endif
+ pam_module_src += ['md5.c', 'argv_parse.c']
+ pam_module_deps += [libselinux]
+endif
+if module == 'pam_pwhistory'
+ pam_module_src += ['opasswd.c', 'pwhistory_config.c']
+ if libselinux.found()
+ pam_module_c_args += ['-DPWHISTORY_HELPER="@0@"'.format(sbindir / 'pwhistory_helper')]
+ endif
+ pam_module_deps += [libcrypt, libselinux]
+endif
+if module == 'pam_rhosts'
+ if cdata.get('HAVE_RUSEROK', 0) == 0 or cdata.get('HAVE_RUSEROK_AF', 0) == 0
+ subdir_done()
+ endif
+endif
+if module == 'pam_rootok'
+ pam_module_deps += [libselinux, libaudit]
+endif
+if module == 'pam_selinux'
+ if not libselinux.found()
+ subdir_done()
+ endif
+ pam_module_deps += [libselinux, libaudit]
+endif
+if module == 'pam_sepermit'
+ if not libselinux.found()
+ subdir_done()
+ endif
+ pam_module_deps += [libselinux]
+ sepermit_lockdir = localstatedir / 'run' / 'sepermit'
+ pam_module_c_args += ['-DSEPERMIT_LOCKDIR="@0@"'.format(sepermit_lockdir)]
+endif
+if module == 'pam_setquota'
+ if cdata.get('HAVE_QUOTACTL', 0) == 0
+ subdir_done()
+ endif
+endif
+if module == 'pam_shells'
+ pam_module_deps += [libeconf]
+endif
+if module == 'pam_timestamp'
+ if cdata.get('WITH_OPENSSL', 0) == 1
+ pam_module_src += ['hmac_openssl_wrapper.c']
+ else
+ pam_module_src += ['hmacsha1.c', 'sha1.c']
+ endif
+ pam_module_deps += [libcrypto, libsystemd]
+endif
+if module == 'pam_tty_audit'
+ if cdata.get('HAVE_STRUCT_AUDIT_TTY_STATUS', 0) == 0
+ subdir_done()
+ endif
+endif
+if module == 'pam_unix'
+ if not enable_pam_unix
+ subdir_done()
+ endif
+ pam_module_src = ['bigcrypt.c',
+ 'pam_unix_acct.c',
+ 'pam_unix_auth.c',
+ 'pam_unix_passwd.c',
+ 'pam_unix_sess.c',
+ 'support.c',
+ 'passverify.c',
+ 'md5_good.c',
+ 'md5_broken.c',
+ ]
+ if enable_nis
+ pam_module_src += ['yppasswd_xdr.c']
+ endif
+ pam_module_c_args += ['-DCHKPWD_HELPER="@0@"'.format(sbindir / 'unix_chkpwd'),
+ '-DUPDATE_HELPER="@0@"'.format(sbindir / 'unix_update')]
+ pam_module_deps += [libcrypt, libselinux, libtirpc, libnsl]
+endif
+if module == 'pam_userdb'
+ if not enable_pam_userdb
+ subdir_done()
+ endif
+ pam_module_deps += [libdb, libcrypt]
+endif
+if module == 'pam_xauth'
+ pam_module_deps += [libselinux]
+endif
+
+pam_module = shared_module(
+ module,
+ name_prefix: '',
+ sources: pam_module_src,
+ dependencies: pam_module_deps,
+ c_args: pam_module_c_args,
+ link_depends: pam_module_link_deps,
+ link_args: pam_module_link_args,
+ install: true,
+ install_dir: securedir,
+)
+
+
+# pam_module.8
+
+pam_module_mans = [[module + '.8', []]]
+if module == 'pam_access'
+ pam_module_mans += [['access.conf.5', []]]
+endif
+if module == 'pam_env'
+ pam_module_mans += [['pam_env.conf.5', ['environment.5']]]
+endif
+if module == 'pam_group'
+ pam_module_mans += [['group.conf.5', []]]
+endif
+if module == 'pam_faillock'
+ pam_module_mans += [['faillock.8', []],
+ ['faillock.conf.5', []]]
+endif
+if module == 'pam_limits'
+ pam_module_mans += [['limits.conf.5', []]]
+endif
+if module == 'pam_mkhomedir'
+ pam_module_mans += [['mkhomedir_helper.8', []]]
+endif
+if module == 'pam_namespace'
+ pam_module_mans += [['namespace.conf.5', []],
+ [module + '_helper.8', []]]
+endif
+if module == 'pam_pwhistory'
+ pam_module_mans += [['pwhistory.conf.5', []]]
+ if libselinux.found()
+ pam_module_mans += [['pwhistory_helper.8', []]]
+ endif
+endif
+if module == 'pam_sepermit'
+ pam_module_mans += [['sepermit.conf.5', []]]
+endif
+if module == 'pam_time'
+ pam_module_mans += [['time.conf.5', []]]
+endif
+if module == 'pam_timestamp'
+ pam_module_mans += [['pam_timestamp_check.8', []]]
+endif
+if module == 'pam_unix'
+ pam_module_mans += [['unix_chkpwd.8', []]]
+ if libselinux.found()
+ pam_module_mans += [['unix_update.8', []]]
+ endif
+endif
+
+foreach man: pam_module_mans
+ xml = man[0] + '.xml'
+
+ run_command([prog_xmllint,
+ '--nonet',
+ '--noout',
+ '--xinclude',
+ '--relaxng', docbook_rng,
+ xml],
+ check: true)
+
+ custom_target(man[0],
+ input: xml,
+ output: man,
+ depends: [custom_man_xsl, pam_module],
+ command: [prog_xsltproc,
+ '-o', '@OUTPUT0@',
+ '--nonet',
+ '--xinclude',
+ '--path', meson.current_source_dir(),
+ stringparam_vendordir,
+ stringparam_profileconditions,
+ custom_man_xsl,
+ '@INPUT@'],
+ install: true,
+ install_dir: mandir / 'man' + man[0].substring(-1),
+ install_tag: 'man',
+ )
+endforeach
+
+
+# README
+
+readme_html = custom_target(
+ input: 'README.xml',
+ output: 'README.html',
+ depends: pam_module,
+ command: [prog_xsltproc,
+ '-o', '@OUTPUT@',
+ '--nonet',
+ '--xinclude',
+ '--path', meson.current_source_dir(),
+ '--stringparam', 'generate.toc', 'none',
+ stringparam_vendordir,
+ stringparam_profileconditions,
+ txt_stylesheet,
+ '@INPUT@'],
+)
+
+custom_target(
+ input: readme_html,
+ output: module + '.txt',
+ command: [redir_exe,
+ '@INPUT@',
+ '@OUTPUT@',
+ browser],
+ install: true,
+ install_dir: docdir / 'modules',
+ install_tag: 'doc',
+)
+
+
+# module-specific configuration files and helpers
+
+if module == 'pam_access'
+ install_data(
+ 'access.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_env'
+ install_data(
+ 'pam_env.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+ install_data(
+ 'environment',
+ install_dir: sysconfdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_group'
+ install_data(
+ 'group.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_faillock'
+ executable(
+ 'faillock',
+ sources: ['main.c', 'faillock.c', 'faillock_config.c'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libaudit],
+ install: true,
+ install_dir: sbindir,
+ )
+ install_data(
+ 'faillock.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_filter'
+ install_data(
+ 'pam_filter.h',
+ install_dir: includedir,
+ install_tag: 'devel',
+ )
+endif
+if module == 'pam_limits'
+ install_data(
+ 'limits.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+ install_emptydir(
+ limits_conf_dir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_mkhomedir'
+ executable(
+ 'mkhomedir_helper',
+ sources: ['mkhomedir_helper.c'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep],
+ install: true,
+ install_dir: sbindir,
+ )
+endif
+if module == 'pam_namespace'
+ pam_namespace_helper = configure_file(
+ input: 'pam_namespace_helper.in',
+ output: 'pam_namespace_helper',
+ configuration: cdata
+ )
+ install_data(
+ pam_namespace_helper,
+ install_mode: 'rwxr-xr-x',
+ install_dir: sbindir,
+ install_tag: 'bin',
+ )
+ pam_namespace_service = configure_file(
+ input: 'pam_namespace.service.in',
+ output: 'pam_namespace.service',
+ configuration: cdata
+ )
+ install_data(
+ pam_namespace_service,
+ install_dir: systemdunitdir,
+ install_tag: 'config',
+ )
+ install_data(
+ 'namespace.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+ install_data(
+ 'namespace.init',
+ install_mode: 'rwxr-xr-x',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+ install_emptydir(
+ sconfigdir / 'namespace.d',
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_pwhistory'
+ executable(
+ 'pwhistory_helper',
+ sources: ['pwhistory_helper.c', 'opasswd.c'],
+ c_args: ['-DHELPER_COMPILE="pwhistory_helper"'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libcrypt],
+ install: true,
+ install_dir: sbindir,
+ )
+ install_data(
+ 'pwhistory.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_selinux'
+ executable(
+ 'pam_selinux_check',
+ sources: ['pam_selinux_check.c'],
+ include_directories: [libpamc_inc],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libpam_misc_dep],
+ )
+endif
+if module == 'pam_sepermit'
+ install_data(
+ 'sepermit.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+ install_emptydir(
+ sepermit_lockdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_time'
+ install_data(
+ 'time.conf',
+ install_dir: vendor_sconfigdir,
+ install_tag: 'config',
+ )
+endif
+if module == 'pam_timestamp'
+ executable(
+ 'pam_timestamp_check',
+ sources: ['pam_timestamp_check.c'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libsystemd],
+ install: true,
+ install_dir: sbindir,
+ )
+endif
+if module == 'pam_unix'
+ executable(
+ 'unix_chkpwd',
+ sources: ['unix_chkpwd.c',
+ 'audit.c',
+ 'bigcrypt.c',
+ 'md5_good.c',
+ 'md5_broken.c',
+ 'passverify.c',
+ ],
+ c_args: ['-DHELPER_COMPILE="unix_chkpwd"'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libcrypt, libselinux, libaudit],
+ install: true,
+ install_dir: sbindir,
+ )
+ if libselinux.found()
+ executable(
+ 'unix_update',
+ sources: ['unix_update.c',
+ 'audit.c',
+ 'bigcrypt.c',
+ 'md5_good.c',
+ 'md5_broken.c',
+ 'passverify.c',
+ ],
+ c_args: ['-DHELPER_COMPILE="unix_update"'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep, libcrypt, libselinux, libaudit],
+ install: true,
+ install_dir: sbindir,
+ )
+ endif
+ executable(
+ 'bigcrypt',
+ sources: ['bigcrypt.c', 'bigcrypt_main.c'],
+ dependencies: [libpam_internal_dep, libpam_dep, libcrypt],
+ )
+endif
+
+
+# tests
+
+test(
+ 'dlopen ' + module,
+ tst_dlopen,
+ args: [pam_module],
+)
+
+tst_module_retval_name = 'tst-' + module + '-retval'
+tst_module_retval_src = tst_module_retval_name + '.c'
+
+if fs.exists(tst_module_retval_src)
+ tst_module_retval_link_args = ''
+ if module == 'pam_canonicalize_user'
+ tst_module_retval_link_args = '-Wl,--export-dynamic'
+ endif
+
+ tst_module_retval_deps = [libpam_internal_dep, libpam_dep]
+ if module == 'pam_rootok'
+ tst_module_retval_deps += [libselinux, libaudit]
+ endif
+
+ tst_module_retval = executable(
+ tst_module_retval_name,
+ sources: tst_module_retval_src,
+ dependencies: tst_module_retval_deps,
+ link_args: tst_module_retval_link_args,
+ )
+
+ test(
+ tst_module_retval_name,
+ chdir_meson_build_subdir,
+ args: [tst_module_retval],
+ env: ['MESON_BUILD_SUBDIR=' + meson.current_build_dir()],
+ )
+endif
+
+
+if module == 'pam_timestamp' and cdata.get('WITH_OPENSSL', 0) != 1
+ hmacfile_exe = executable(
+ 'hmacfile',
+ sources: ['hmacfile.c', 'hmacsha1.c', 'sha1.c'],
+ dependencies: [libpam_internal_dep, libpam_dep],
+ )
+ test(
+ 'pam_timestamp hmacfile',
+ hmacfile_exe,
+ )
+endif
+
+
+if module == 'pam_filter'
+ subdir('upperLOWER')
+endif
diff --git a/modules/pam_access/meson.build b/modules/pam_access/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_access/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_canonicalize_user/meson.build b/modules/pam_canonicalize_user/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_canonicalize_user/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_debug/meson.build b/modules/pam_debug/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_debug/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_deny/meson.build b/modules/pam_deny/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_deny/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_echo/meson.build b/modules/pam_echo/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_echo/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_env/meson.build b/modules/pam_env/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_env/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_exec/meson.build b/modules/pam_exec/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_exec/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_faildelay/meson.build b/modules/pam_faildelay/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_faildelay/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_faillock/meson.build b/modules/pam_faillock/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_faillock/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_filter/meson.build b/modules/pam_filter/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_filter/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_filter/upperLOWER/meson.build b/modules/pam_filter/upperLOWER/meson.build
new file mode 100644
index 00000000..8992fff1
--- /dev/null
+++ b/modules/pam_filter/upperLOWER/meson.build
@@ -0,0 +1,9 @@
+executable(
+ 'upperLOWER',
+ sources: ['upperLOWER.c'],
+ include_directories: ['..'],
+ link_args: exe_link_args,
+ dependencies: [libpam_internal_dep, libpam_dep],
+ install: true,
+ install_dir: securedir / 'pam_filter',
+)
diff --git a/modules/pam_ftp/meson.build b/modules/pam_ftp/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_ftp/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_group/meson.build b/modules/pam_group/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_group/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_issue/meson.build b/modules/pam_issue/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_issue/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_keyinit/meson.build b/modules/pam_keyinit/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_keyinit/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_lastlog/meson.build b/modules/pam_lastlog/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_lastlog/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_limits/meson.build b/modules/pam_limits/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_limits/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_listfile/meson.build b/modules/pam_listfile/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_listfile/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_localuser/meson.build b/modules/pam_localuser/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_localuser/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_loginuid/meson.build b/modules/pam_loginuid/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_loginuid/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_mail/meson.build b/modules/pam_mail/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_mail/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_mkhomedir/meson.build b/modules/pam_mkhomedir/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_mkhomedir/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_motd/meson.build b/modules/pam_motd/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_motd/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_namespace/meson.build b/modules/pam_namespace/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_namespace/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_nologin/meson.build b/modules/pam_nologin/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_nologin/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_permit/meson.build b/modules/pam_permit/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_permit/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_pwhistory/meson.build b/modules/pam_pwhistory/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_pwhistory/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_rhosts/meson.build b/modules/pam_rhosts/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_rhosts/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_rootok/meson.build b/modules/pam_rootok/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_rootok/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_securetty/meson.build b/modules/pam_securetty/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_securetty/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_selinux/meson.build b/modules/pam_selinux/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_selinux/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_sepermit/meson.build b/modules/pam_sepermit/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_sepermit/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_setquota/meson.build b/modules/pam_setquota/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_setquota/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_shells/meson.build b/modules/pam_shells/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_shells/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_stress/meson.build b/modules/pam_stress/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_stress/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_succeed_if/meson.build b/modules/pam_succeed_if/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_succeed_if/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_time/meson.build b/modules/pam_time/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_time/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_timestamp/meson.build b/modules/pam_timestamp/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_timestamp/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_tty_audit/meson.build b/modules/pam_tty_audit/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_tty_audit/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_umask/meson.build b/modules/pam_umask/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_umask/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_unix/meson.build b/modules/pam_unix/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_unix/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_userdb/meson.build b/modules/pam_userdb/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_userdb/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_usertype/meson.build b/modules/pam_usertype/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_usertype/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_warn/meson.build b/modules/pam_warn/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_warn/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_wheel/meson.build b/modules/pam_wheel/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_wheel/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/modules/pam_xauth/meson.build b/modules/pam_xauth/meson.build
new file mode 120000
index 00000000..ba2e9b52
--- /dev/null
+++ b/modules/pam_xauth/meson.build
@@ -0,0 +1 @@
+../module-meson.build \ No newline at end of file
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 00000000..8f075704
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,10 @@
+if not find_program('gettext', required: get_option('i18n')).found()
+ subdir_done()
+endif
+
+i18n = import('i18n')
+i18n.gettext(
+ meson.project_name(),
+ preset: 'glib',
+ data_dirs: '.'
+)
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 00000000..4d37e450
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,47 @@
+foreach name: ['dlopen',
+ 'pam_start',
+ 'pam_end',
+ 'pam_fail_delay',
+ 'pam_open_session',
+ 'pam_close_session',
+ 'pam_acct_mgmt',
+ 'pam_authenticate',
+ 'pam_chauthtok',
+ 'pam_setcred',
+ 'pam_get_item',
+ 'pam_set_item',
+ 'pam_getenvlist',
+ 'pam_get_user',
+ 'pam_get_data',
+ 'pam_set_data',
+ 'pam_mkargv',
+ 'pam_start_confdir',
+ ]
+ tst_deps = [libpam_internal_dep, libpam_dep]
+ if name == 'dlopen'
+ tst_deps += libdl
+ endif
+ tst_name = 'tst-' + name
+
+ tst_exe = executable(
+ tst_name,
+ sources: tst_name + '.c',
+ dependencies: tst_deps,
+ include_directories: [libpam_private_inc],
+ c_args: ['-DLIBPAM_COMPILE'],
+ link_args: exe_link_args,
+ )
+
+ if name == 'dlopen'
+ tst_dlopen = tst_exe
+ endif
+
+ test(
+ tst_name,
+ chdir_meson_build_subdir,
+ args: [tst_exe],
+ env: ['MESON_BUILD_SUBDIR=' + meson.current_build_dir(),
+ 'srcdir=' + meson.current_source_dir()
+ ],
+ )
+endforeach
diff --git a/xtests/meson.build b/xtests/meson.build
new file mode 100644
index 00000000..96b2612f
--- /dev/null
+++ b/xtests/meson.build
@@ -0,0 +1,70 @@
+xtest_progs = [
+ 'tst-pam_access1',
+ 'tst-pam_access2',
+ 'tst-pam_access3',
+ 'tst-pam_access4',
+ 'tst-pam_authfail',
+ 'tst-pam_authsucceed',
+ 'tst-pam_dispatch1',
+ 'tst-pam_dispatch2',
+ 'tst-pam_dispatch3',
+ 'tst-pam_dispatch4',
+ 'tst-pam_dispatch5',
+ 'tst-pam_group1',
+ 'tst-pam_limits1',
+ 'tst-pam_motd',
+ 'tst-pam_pwhistory1',
+ 'tst-pam_shells',
+ 'tst-pam_succeed_if1',
+ 'tst-pam_time1',
+ 'tst-pam_unix1',
+ 'tst-pam_unix2',
+ 'tst-pam_unix3',
+ 'tst-pam_unix4',
+]
+
+foreach prog: xtest_progs
+ tst_exe = executable(
+ prog,
+ sources: prog + '.c',
+ c_args: ['-DLIBPAM_COMPILE'],
+ link_args: exe_link_args,
+ include_directories: [libpamc_inc],
+ dependencies: [libpam_dep, libpam_misc_dep],
+ )
+
+ test(
+ 'xtests ' + prog,
+ chdir_meson_build_subdir,
+ args: [
+ files('run-xtests.sh'),
+ meson.current_source_dir(),
+ fs.name(tst_exe),
+ ],
+ env: ['MESON_BUILD_SUBDIR=' + meson.current_build_dir()],
+ is_parallel: false,
+ )
+endforeach
+
+xtest_scripts = [
+ 'tst-pam_assemble_line1',
+ 'tst-pam_substack1',
+ 'tst-pam_substack2',
+ 'tst-pam_substack3',
+ 'tst-pam_substack4',
+ 'tst-pam_substack5',
+]
+
+foreach name: xtest_scripts
+ test(
+ 'xtests ' + name,
+ chdir_meson_build_subdir,
+ args: [
+ files('run-xtests.sh'),
+ meson.current_source_dir(),
+ name,
+ ],
+ env: ['MESON_BUILD_SUBDIR=' + meson.current_build_dir()],
+ is_parallel: false,
+ )
+endforeach