Per-Module ACLs

Webmin versions 0.72 and above support a standard method for restricting which features of a module a user can access. For example, the Apache module allows a Webmin user to be restricted to managing selected virtual servers, and the BIND module allows user to be limited to editing records only in certain domains.

Module ACL options are set in the Webmin Users module by clicking on the name of a module next to a user's name. The options available are generated by code from the module itself (except for the Can edit module configuration? option, which is always present). When the user clicks on Update the form parameters are also parsed by code from the module being configured, before being saved in the Webmin config directory.

A module wanting ACL options must contain a file called acl_security.pl in its directory. This file must contain two perl functions :

acl_security_form(acl)
This function takes a reference to a hash containing the current ACL options for this user, and must output HTML for form inputs to edit those ACL options. Because the HTML will be inside a 4-column table, you must generate the appropriate <tr> and <td> tags around your input elements.
acl_security_save(acl, inputs)
This function must fill in the given hash reference with values from the form created by acl_security_form. Form inputs are available in the global hash %in as generated by ReadParse, or from the second parameter to the function.
Because these functions are called in the context of your module, the acl_security.pl file can require the common functions file used by other CGI programs in your module. This gives you access to all the standard Webmin functions, and allows you to provide more meaningful inputs. For example, when setting ACL options for the Apache module a list of virtual servers from the Apache config is displayed for the user to select from.

If a user has not yet had any ACL options set for a module, a default set of options will be used. These are read from the file defaultacl in the module directory, which must contain name=value pairs one per line. These options should allow the user to do anything, so that the admin or master Webmin user is not restricted by default.

To actually enforced the chosen ACL options for each user, your module programs must use the get_module_acl function to get the ACL for the current users, and then verify that each action is allowed. When called with no parameters this function will return a hash containing the options set for the current user in the current module, which is almost always what you want. For example :

#!/usr/local/bin/perl
require './foo-lib.pl';
%access = &get_module_acl();
$access{'create'} ||
	&error("You are not allowed to create new foo users");

When designing a module that some users will have limited access to, remember the user can enter any URL, not just those that you link to. For example, just doing ACL checking in the program that displays a form is not enough - the program that processing the form should do all the same checks as well. Similarly, CGI parameters should never be trusted, especially hidden parameters.