diff --git a/README.md b/README.md index 78eea4d..1dbf163 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,27 @@ SMArT is the web-based configuration interface for **MARS_NWE**, a Novell NetWare 3.x emulator for Linux and FreeBSD. -In the current setup, this repository is no longer treated as a standalone component only. It is integrated into the main `mars_nwe` project as a **Git submodule** and is therefore included in the normal **mars_nwe release** process. +In the current setup, this repository is integrated into the main `mars_nwe` project as a **Git submodule**. It is built, installed, and released as part of the normal **MARS_NWE** release process rather than as a separate end-user component. + +## Screenshots + +The screenshots below use anonymized demo data. Exact paths, usernames, printer names, and build placeholders may differ on a real installation. + +| Login | Service runtime page | +| --- | --- | +| ![SMArT login screen](doc/screenshots/login.png) | ![SMArT service runtime page](doc/screenshots/service-runtime.png) | + +| Main menu and advanced section | Volume import from local mount points | +| --- | --- | +| ![SMArT main menu with an advanced section opened](doc/screenshots/main-menu-advanced.png) | ![SMArT volume page with local mount point import](doc/screenshots/volumes-import.png) | + +| User editor | Print queue editor with CUPS helper | +| --- | --- | +| ![SMArT user editor](doc/screenshots/user-editor.png) | ![SMArT print queue editor with CUPS helper](doc/screenshots/print-queue-cups.png) | + +| Validation error page | +| --- | +| ![SMArT validation error page](doc/screenshots/validation-error.png) | ## Project status and integration @@ -10,40 +30,211 @@ This repository is intended to be embedded into the main `mars_nwe` Git reposito - Main project: `mars_nwe` - Submodule role: provides the SMArT web UI and helper tools -- Release model: shipped as part of the integrated **MARS_NWE** release, not as a separate end-user release artifact +- Release model: shipped as part of the integrated **MARS_NWE** release -The build and install rules show that the web UI binaries, Perl helpers, configuration, static assets, and PAM file are installed as part of the overall build and installation flow. +The build and install rules install the web UI binary, Perl helpers, configuration template, static assets, systemd unit, and PAM file as part of the integrated installation target. ## Architecture overview -SMArT consists of two main parts: +SMArT consists of three main pieces: -1. **Perl-based application logic** for configuration pages and helper scripts -2. **`nwwebui` service** as the web frontend that exposes the application over HTTP and HTTPS +1. **`nwwebui`** – a dedicated HTTP/HTTPS frontend service +2. **Perl helper scripts** – request routing, configuration pages, bindery operations, validation, and service control +3. **Small native helpers** – PAM login checking and optional user enumeration helpers -The current implementation adds a dedicated `nwwebui` service that can serve the application directly over: +The `nwwebui` service can expose the UI over: - **HTTP on port 9080** - **HTTPS on port 9443** -The service supports TLS via OpenSSL and can run both listeners in parallel. HTTPS is the preferred mode because authentication happens more securely over an encrypted connection, while plain HTTP may still be useful for testing or trusted internal environments. +Both listeners can run in parallel. HTTPS is recommended for real deployments because the login form transmits credentials. Plain HTTP is still useful for local testing or trusted internal environments. -## Security model +## Major features -SMArT uses PAM-based authentication through the `check_login` helper. The supplied PAM policy is a standard `pam_unix` stack for authentication, account, password, and session handling. During installation with **MARS_NWE**, this file is installed automatically as: +### HTML login, sessions, and logout -- `/etc/pam.d/smart` +SMArT provides a form-based login page, session cookies, and a logout action. Static assets such as the SMArT logo are served before authentication so the login page can render correctly. -That means no manual PAM file deployment is normally required when SMArT is installed through the integrated `mars_nwe` package or release. +Runtime session files are stored under the WebUI runtime directory, typically: + +```text +/run/mars-nwe-webui +``` + +### PAM authentication with administrator group restriction + +Authentication is performed through the PAM service `smart` using the `check_login` helper. In addition to a successful PAM login, the user must be a member of the configured Unix administrator group. + +The administrator group is configured at build time through the main `mars_nwe` CMake project: + +```bash +cmake -DMARS_NWE_SMART_ADMIN_GROUP=root ... +``` + +The default is `root` to preserve the traditional behavior on existing systems. On normal Unix systems the `root` user has primary group `root`, so root can still log in. For delegated administration, build with a dedicated group instead: + +```bash +cmake -DMARS_NWE_SMART_ADMIN_GROUP=nwadmin ... +groupadd nwadmin +usermod -aG nwadmin mario +``` + +After installation the effective setting appears in `smart.conf` as: + +```perl +$smart_admin_group = 'root'; +``` + +or, for a delegated build: + +```perl +$smart_admin_group = 'nwadmin'; +``` + +### Service control page + +The start page includes controls for the configured MARS_NWE service: + +- start +- stop +- restart +- status + +The service name is supplied by the build configuration and can be overridden in `smart.conf`: + +```perl +$mars_nwe_service = 'mars-nwe-serv.service'; +$smart_systemctl_path = '/usr/bin/systemctl'; +``` + +### Runtime information page + +The start page shows the important runtime paths generated by CMake, including: + +- main MARS_NWE configuration file +- SMArT configuration file +- WebUI helper/script directory +- MARS_NWE service unit name +- `systemctl` executable + +This helps diagnose packaging or installation path issues without searching through generated files. + +### Configuration editors and advanced sections + +The main menu contains the commonly used configuration areas and advanced sections. Advanced pages are shown only when the selected section is opened, which keeps the menu usable while still exposing low-level MARS_NWE options. + +Current sections include, among others: + +- setup first +- MARS_NWE service +- general settings +- directories +- precompiled/path settings +- security +- user configuration +- volumes +- devices +- logging +- stations/access control +- users +- groups +- print queues + +### Import helpers + +SMArT can prefill or discover host-side data for common configuration tasks: + +- local mount points for volume creation +- Unix users for MARS_NWE user mapping +- CUPS printers for print queue command generation +- IPX interfaces for device configuration + +These helpers are meant to reduce manual typing while still leaving the final configuration under administrator control. + +### Validation and error pages + +The apply path validates common input before writing configuration or changing bindery data. Invalid values are shown on a dedicated validation page instead of failing silently or returning an empty HTTP response. + +Validation currently covers areas such as: + +- volume names and Unix paths +- device/network parameters +- print queue names, print commands, and spool directories +- user names and group names +- invalid bindery characters + +### Bindery command handling + +Bindery operations are executed through checked helper functions instead of silent `system()` calls. The WebUI logs command start, command success, command failure, and relevant output. + +Commands such as `nwbocreate`, `nwbprm`, and `nwborm` are handled through `run_bindery_cmd()`. Pipe-style `nwbpset` operations are handled through `run_bindery_pipe()` using a temporary input file and checked return code. + +This improves diagnostics for user, group, and print queue operations. The browser receives a structured error page when a bindery command fails. + +### Bindery success pages + +After successful user, group, or print queue changes, SMArT can show a result page with the number of successful bindery commands. This makes bindery changes visible to the administrator and avoids silent redirects after complex operations. + +### Optional Unix user mapping updates + +Existing MARS_NWE users no longer have their `UNIX_USER` mapping removed unless the administrator explicitly requests a mapping change. This prevents accidental loss of Unix user assignments when only editing full name, password, or group membership. + +## Logging + +SMArT has two relevant log streams: + +- the `nwwebui` service log +- the Perl frontend log, normally `smart.log` + +Typical paths: + +```text +/var/log/mars_nwe/nwwebui.log +/var/log/mars_nwe/smart.log +``` + +### Perl frontend log level + +The Perl frontend log level is configured in `smart.conf`: + +```perl +# SMArT Perl logging verbosity. +# Values: error, warning, info, debug, trace +# Default: info +$smart_debug_level = 'info'; +``` + +Supported values, from quiet to verbose: + +- `error` – only real errors that abort or fail an operation +- `warning` – errors and warnings about unusual but non-fatal situations +- `info` – normal operational messages, command start/finish, default +- `debug` – additional diagnostic information for troubleshooting +- `trace` – very verbose step-by-step traces, including bindery pipe payloads + +Use `trace` only while debugging a concrete problem. It may include submitted bindery payload data and can produce a lot of log output. After debugging, switch back to `info`. + +### `nwwebui` service log level + +The `nwwebui` service has its own numeric log level: + +```perl +$nw_log_level = 1; +``` + +Typical meanings: + +- `0` = errors only +- `1` = informational messages +- `2` = debug output ## Installed components -The install rules include the following relevant components. - ### Binaries - `nwwebui` – dedicated web service frontend -- `check_login` – PAM authentication helper +- `check_login` – PAM authentication and administrator-group helper +- optional host discovery helpers, depending on build options ### Perl helpers @@ -52,19 +243,18 @@ The install rules include the following relevant components. - `readconfig.pl` - `settings.pl` - `static.pl` +- `control` ### Configuration and assets - `smart.conf` -- static HTML and image assets for the web UI +- static HTML/image assets for the WebUI - optional `mars-nwe-webui.service` systemd unit - PAM file installed as `/etc/pam.d/smart` -These components are all installed by the build system as part of the same integrated installation target. - ## Typical runtime paths -The original templates use CMake placeholders. For documentation, the following standard example paths can be used in a typical Linux installation: +The templates use CMake placeholders. In a typical Linux installation, the effective paths are similar to: - Main MARS_NWE config directory: `/etc/mars_nwe` - SMArT config file: `/etc/mars_nwe/smart.conf` @@ -72,55 +262,45 @@ The original templates use CMake placeholders. For documentation, the following - Helper binaries and scripts: `/usr/libexec/mars_nwe` - Static SMArT assets: `/usr/libexec/mars_nwe/static` - Log directory: `/var/log/mars_nwe` +- Runtime/session directory: `/run/mars-nwe-webui` - PID directory: `/run/mars_nwe` - TLS certificate: `/etc/mars_nwe/server.crt` - TLS private key: `/etc/mars_nwe/server.key` - PAM file: `/etc/pam.d/smart` -These values are sensible standard defaults for documentation. Packaging may still adjust them depending on the target distribution. +Packaging may adjust these paths depending on the target distribution. -## The `smart.conf` file +## `smart.conf` example -The `smart.conf` file controls both the SMArT frontend behavior and the `nwwebui` listener settings. - -A documented example with standard installation paths is shown below: +A documented example with standard installation paths: ```perl -# SMArT / nwwebui configuration file - -# ------------------------------------------------------------ -# UI colors -# ------------------------------------------------------------ -$COLOR_BACK = "#F0F0FF"; -$COLOR_HEAD_BACK = "#C0C0FF"; -$COLOR_HEAD_FORE = "#000000"; -$COLOR_SUBH_BACK = "#D0D0FF"; -$COLOR_SUBH_FORE = "#000000"; -$COLOR_TEXT_BACK = "#E0E0FF"; -$COLOR_TEXT_FORE = "#000000"; - -# ------------------------------------------------------------ # Main MARS_NWE configuration -# ------------------------------------------------------------ $mars_config = '/etc/mars_nwe/nwserv.conf'; $nonroot_user = 'nobody'; $smart_compact_nwservconf = 0; -# ------------------------------------------------------------ # SMArT internal file layout -# ------------------------------------------------------------ $smart_conf_path = '/etc/mars_nwe/smart.conf'; $smart_nwclient_path = '/etc/mars_nwe/.nwclient'; $smart_static_dir = '/usr/libexec/mars_nwe/static'; $smart_log_path = '/var/log/mars_nwe/smart.log'; $smart_check_login = '/usr/libexec/mars_nwe/check_login'; +$smart_admin_group = 'root'; -# Optional override, usually not needed -# $smart_perl_path = '/usr/libexec/mars_nwe/smart'; +# Perl frontend logging +$smart_debug_level = 'info'; + +# Service control +$mars_nwe_service = 'mars-nwe-serv.service'; +$smart_systemctl_path = '/usr/bin/systemctl'; + +# CUPS helper integration +$smart_cups_enable = '1'; +$smart_cups_lpstat_path = '/usr/bin/lpstat'; +$smart_cups_print_command_template = '/usr/bin/lp -d %p -'; -# ------------------------------------------------------------ # nwwebui listener settings -# ------------------------------------------------------------ $nw_bind_ip = '0.0.0.0'; $nw_log_level = 1; $nw_daemonize = 0; @@ -135,68 +315,32 @@ $nw_cert_file = '/etc/mars_nwe/server.crt'; $nw_key_file = '/etc/mars_nwe/server.key'; ``` -## `smart.conf` settings explained +## Build and installation notes -### UI colors +This repository is built as part of the main `mars_nwe` build. The build system: -These variables define the default SMArT page colors: +- generates `smart.conf` from the template +- generates the main `smart` Perl launcher script +- builds `nwwebui` +- builds `check_login` +- installs the PAM file and static UI assets +- installs helper scripts and optional systemd units -- `$COLOR_BACK` – page background -- `$COLOR_HEAD_BACK` / `$COLOR_HEAD_FORE` – main section header colors -- `$COLOR_SUBH_BACK` / `$COLOR_SUBH_FORE` – subsection header colors -- `$COLOR_TEXT_BACK` / `$COLOR_TEXT_FORE` – regular content row colors +Useful build-time settings include: -### Main MARS_NWE configuration +```bash +cmake -DMARS_NWE_SMART_ADMIN_GROUP=root ... +cmake -DMARS_NWE_SMART_ADMIN_GROUP=nwadmin ... +cmake -DMARS_NWE_SYSTEMD_SERVICE=mars-nwe-serv.service ... +``` -- `$mars_config` – path to the main `nwserv.conf` file that SMArT reads and updates -- `$nonroot_user` – unprivileged user account used when SMArT drops privileges -- `$smart_compact_nwservconf` – controls how `nwserv.conf` is written back: - - `0` keeps comments, spacing, and the original structure as much as possible - - `1` writes a more compact version without the original long comment layout - -### SMArT internal file layout - -- `$smart_conf_path` – absolute path to `smart.conf` -- `$smart_nwclient_path` – file used to store bindery login information for SMArT helper tools -- `$smart_static_dir` – directory containing HTML, icons, and other static assets -- `$smart_log_path` – log file used by the Perl-based SMArT frontend -- `$smart_check_login` – PAM-based authentication helper path -- `$smart_perl_path` – optional override for the main SMArT Perl executable; usually not needed - -### `nwwebui` listener settings - -- `$nw_bind_ip` – bind address for HTTP and HTTPS listeners, for example `0.0.0.0` for all IPv4 interfaces or `127.0.0.1` for localhost-only access -- `$nw_log_level` – service log verbosity: - - `0` = errors only - - `1` = informational messages - - `2` = debug output -- `$nw_daemonize` – whether `nwwebui` detaches into the background -- `$nw_pid_file` – location of the PID file -- `$nw_log_file` – log file written by `nwwebui` -- `$nw_ssl_enable` – enables or disables HTTPS support -- `$nw_http_port` – HTTP listener port; set to `0` to disable plain HTTP -- `$nw_https_port` – HTTPS listener port; set to `0` to disable HTTPS -- `$nw_cert_file` – PEM certificate path for TLS -- `$nw_key_file` – PEM private key path for TLS - -The current code and template show that: - -- `nwwebui` listens on `9080` for HTTP by default -- `9443` is used for HTTPS -- the log file can be configured with `$nw_log_file` -- the log path can also be overridden at runtime with `-l` - -Because passwords may be transmitted during login, HTTPS is the recommended way to access the interface. +The administrator group defaults to `root` for compatibility. Use a dedicated group such as `nwadmin` when non-root administrators should be allowed to access the WebUI. ## Starting the service -Depending on the installation method, `nwwebui` can be started either via **systemd** or directly from the **command line**. The build system installs a `mars-nwe-webui.service` unit when systemd support is enabled. - ### Starting with systemd -A typical installed system uses the `mars-nwe-webui.service` unit. The unit starts `nwwebui`, prepares the needed runtime directories, and loads the standard `smart.conf` file. - -Typical commands: +A typical installed system uses the `mars-nwe-webui.service` unit: ```bash systemctl enable --now mars-nwe-webui.service @@ -206,7 +350,7 @@ systemctl restart mars-nwe-webui.service systemctl status mars-nwe-webui.service ``` -The service unit starts `nwwebui` with the equivalent of: +The service starts `nwwebui` with the equivalent of: ```bash /usr/sbin/nwwebui -c /etc/mars_nwe/smart.conf @@ -214,8 +358,6 @@ The service unit starts `nwwebui` with the equivalent of: ### Starting from the command line -`nwwebui` can also be launched manually. The built-in usage text documents the supported options: - ```text Usage: nwwebui [-h] [-d] [-s] [-c ] [-p ] [-l ] @@ -228,30 +370,15 @@ Options: -l, --logfile Override log file path ``` -Typical examples: +Examples: ```bash -# start in foreground with the standard configuration /usr/sbin/nwwebui -c /etc/mars_nwe/smart.conf - -# start in daemon mode /usr/sbin/nwwebui -d -c /etc/mars_nwe/smart.conf - -# stop a running instance /usr/sbin/nwwebui -s -c /etc/mars_nwe/smart.conf - -# use a custom PID file -/usr/sbin/nwwebui -d -c /etc/mars_nwe/smart.conf -p /run/mars_nwe/nwwebui.pid - -# use a custom log file /usr/sbin/nwwebui -c /etc/mars_nwe/smart.conf -l /var/log/mars_nwe/custom-nwwebui.log - -# override both PID and log file -/usr/sbin/nwwebui -d -c /etc/mars_nwe/smart.conf -p /run/mars_nwe/nwwebui.pid -l /var/log/mars_nwe/nwwebui.log ``` -The `-l` option overrides `$nw_log_file` from `smart.conf` at runtime. - Typical access URLs: - `http://:9080/` @@ -259,18 +386,6 @@ Typical access URLs: For production use, HTTPS should be preferred. -## Build and installation notes - -This repository is built as part of the main `mars_nwe` build. The build system: - -- generates `smart.conf` from the template -- generates the `smart` launcher script -- builds `nwwebui` -- builds `check_login` -- installs the PAM file and static UI assets - -Because this repository is integrated as a Git submodule in `mars_nwe`, end users normally consume it through the main `mars_nwe` source tree and release packages rather than using it as a standalone project. - ## Summary -SMArT is now an integrated part of the `mars_nwe` release and includes a dedicated `nwwebui` service that can expose the interface over both HTTP and HTTPS. The standard listener ports are **9080** for HTTP and **9443** for HTTPS. Authentication is handled through PAM, and the required `/etc/pam.d/smart` file is installed automatically together with the integrated MARS_NWE installation. +SMArT is now an integrated part of the `mars_nwe` release. It includes a dedicated `nwwebui` service, form-based sessions, PAM authentication with configurable administrator group restriction, service control, validation pages, import helpers, improved bindery command handling, and configurable logging. diff --git a/check_login.c b/check_login.c index 3b4e8d6..4df728c 100644 --- a/check_login.c +++ b/check_login.c @@ -1,32 +1,30 @@ /* SMArT - Check username/password combination using PAM + Check username/password combination using PAM and require membership in + the configured SMArT administrator Unix group. Copyright 2001 Wilmer van der Gaast + Updated for MARS_NWE SMArT group-restricted login. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +#include +#include +#include #include #include #include #include +#include +#include int my_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); +static int user_in_group(const char *username, const char *groupname); static struct pam_conv conv = { my_conv, @@ -38,35 +36,140 @@ char *pass; int main( int argc, char **argv ) { - pam_handle_t *pamh; + pam_handle_t *pamh = NULL; int retval, st = 1; + const char *admin_group; + + if( argc < 4 ) + { + fprintf( stderr, "Usage: %s \n", argv[0] ); + return( 3 ); + } user = argv[1]; pass = argv[2]; + admin_group = argv[3]; + + if( user == NULL || user[0] == '\0' || + pass == NULL || + admin_group == NULL || admin_group[0] == '\0' ) + { + return( 3 ); + } retval = pam_start( "smart", user, &conv, &pamh ); - if ( retval == PAM_SUCCESS ) + if( retval == PAM_SUCCESS ) retval = pam_authenticate( pamh, PAM_SILENT ); - if ( retval == PAM_SUCCESS ) + if( retval == PAM_SUCCESS ) st = retval = pam_acct_mgmt( pamh, PAM_SILENT ); - if ( pam_end( pamh, retval ) != PAM_SUCCESS ) + + if( pamh != NULL && pam_end( pamh, retval ) != PAM_SUCCESS ) return( 1 ); - return( st != PAM_SUCCESS ); + if( st != PAM_SUCCESS ) + return( 1 ); + + if( ! user_in_group( user, admin_group ) ) + return( 2 ); + + return( 0 ); +} + +static int user_in_group(const char *username, const char *groupname) +{ + struct passwd *pw; + struct group *gr; + int ngroups = 0; + gid_t *groups; + int i; + + if( username == NULL || username[0] == '\0' || + groupname == NULL || groupname[0] == '\0' ) + { + return( 0 ); + } + + pw = getpwnam( username ); + gr = getgrnam( groupname ); + + if( pw == NULL || gr == NULL ) + { + return( 0 ); + } + + if( pw->pw_gid == gr->gr_gid ) + { + return( 1 ); + } + +#if defined(__linux__) || defined(__GLIBC__) + /* + getgrouplist() asks NSS for supplementary groups, so files, LDAP, SSSD, + NIS, etc. follow the local nsswitch.conf configuration. + */ + getgrouplist( username, pw->pw_gid, NULL, &ngroups ); + + if( ngroups > 0 ) + { + groups = calloc( (size_t) ngroups, sizeof( gid_t ) ); + + if( groups != NULL ) + { + if( getgrouplist( username, pw->pw_gid, groups, &ngroups ) >= 0 ) + { + for( i = 0; i < ngroups; i++ ) + { + if( groups[i] == gr->gr_gid ) + { + free( groups ); + return( 1 ); + } + } + } + + free( groups ); + } + } +#endif + + /* + Portable fallback: check the group's explicit member list. + */ + if( gr->gr_mem != NULL ) + { + for( i = 0; gr->gr_mem[i] != NULL; i++ ) + { + if( strcmp( gr->gr_mem[i], username ) == 0 ) + { + return( 1 ); + } + } + } + + return( 0 ); } int my_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { struct pam_response *reply; int i; - - reply = (struct pam_response *) calloc( num_msg, sizeof( struct pam_response ) ); + + (void) msg; + (void) appdata_ptr; + + reply = (struct pam_response *) calloc( (size_t) num_msg, sizeof( struct pam_response ) ); + if( reply == NULL ) + { + return( PAM_BUF_ERR ); + } + for( i = 0; i < num_msg; i ++ ) { reply[i].resp = (char *) strdup( pass ); /* Just give the password... It's all we know */ reply[i].resp_retcode = 0; } + *resp = reply; - + return( PAM_SUCCESS ); } diff --git a/smart.cmake b/smart.cmake index a894d77..8e21f5e 100644 --- a/smart.cmake +++ b/smart.cmake @@ -55,6 +55,8 @@ $smart_libexec_dir =~ s#/*$##; $smart_control_path = $smart_libexec_dir . '/control' unless defined $smart_control_path; $mars_nwe_service = '@MARS_NWE_SYSTEMD_SERVICE@' unless defined $mars_nwe_service; $smart_systemctl_path = '@SYSTEMCTL_EXECUTABLE@' unless defined $smart_systemctl_path; +$smart_admin_group = '@MARS_NWE_SMART_ADMIN_GROUP@' unless defined $smart_admin_group; +$smart_admin_group = 'root' if ! defined( $smart_admin_group ) || $smart_admin_group eq '' || $smart_admin_group =~ /^\@MARS_NWE_SMART_ADMIN_GROUP\@$/; $l = ; $l =~ s/[\n\r]//g; @@ -437,14 +439,27 @@ sub check_login_password( $$ ) my( $user, $pass ) = @_; return 0 if ! defined( $user ) || ! defined( $pass ); - return 0 if $user ne 'root'; + return 0 if $user eq '' || $pass eq ''; if( ! defined( $smart_check_login ) || $smart_check_login eq '' || ! -x $smart_check_login ) { return -1; } - return system( $smart_check_login, $user, $pass ) == 0 ? 1 : 0; + my $admin_group = defined( $smart_admin_group ) && $smart_admin_group ne '' ? $smart_admin_group : 'root'; + + my $rc = system( $smart_check_login, $user, $pass, $admin_group ); + + if( $rc == 0 ) + { + return 1; + } + + my $exit = $rc >> 8; + + return -2 if $exit == 2; + + return 0; } sub print_login_page( $ ) @@ -525,6 +540,13 @@ sub handle_login_route() return; } + if( $rv == -2 ) + { + my $admin_group = defined( $smart_admin_group ) && $smart_admin_group ne '' ? $smart_admin_group : 'root'; + print_login_page( 'Login denied. User is not a member of required admin group: ' . $admin_group ); + return; + } + if( $rv != 1 ) { print_login_page( 'Login failed.' ); diff --git a/smart.conf.cmake b/smart.conf.cmake index 18412eb..30a9c0b 100644 --- a/smart.conf.cmake +++ b/smart.conf.cmake @@ -61,9 +61,29 @@ $smart_static_dir = '@MARS_NWE_INSTALL_FULL_LIBEXECDIR@/static'; # Keep this separate from the nwwebui log file. $smart_log_path = '@MARS_NWE_LOG_DIR@/smart.log'; -# Path to the PAM-based login helper used for root authentication. +# Path to the PAM-based login helper used for SMArT authentication. $smart_check_login = '@MARS_NWE_INSTALL_FULL_LIBEXECDIR@/check_login'; +# Unix group allowed to log in to the SMArT/nwwebui admin interface. +# +# Authentication is still done through PAM service "smart", but a user must +# also be a member of this Unix group. +# +# The build-time default is "root" to preserve the traditional behavior on +# existing installations: the root user is allowed because its primary Unix +# group is normally also "root". Do not add normal users to the "root" group. +# +# For delegated administration, use a dedicated group instead, for example: +# +# cmake -DMARS_NWE_SMART_ADMIN_GROUP=nwadmin ... +# groupadd nwadmin +# usermod -aG nwadmin mario +# +# Changes to local group membership normally require the user to start a new +# login session before NSS/PAM reports the new membership. +$smart_admin_group = '@MARS_NWE_SMART_ADMIN_GROUP@'; + + # Path to the SMArT service-control helper. $smart_control_path = '@MARS_NWE_INSTALL_FULL_LIBEXECDIR@/control';