This module provides for basic user authentication using textual files, dets databases as well as mnesia databases. The following config directives are supported:
The Directory config directive is central to be able to restrict access to certain areas of the server. Please read about the Directory config directive.
Syntax: <Directory
regexp-filename>
Default: - None -
Module: mod_auth(3)
Related: allow,
deny,
AuthAccessPassword
AuthUserFile,
AuthGroupFile,
AuthName,
require
<Directory>
and </Directory> are used to
enclose a group of directives which applies only to the named
directory and sub-directories of that
directory. regexp-filename
is an extended regular
expression (See regexp(3)
). For example:
<Directory /usr/local/httpd[12]/htdocs> AuthAccessPassword sOmEpAsSwOrD AuthDBType plain AuthName My Secret Garden AuthUserFile /var/tmp/server_root/auth/user AuthGroupFile /var/tmp/server_root/auth/group require user ragnar edward require group group1 allow from 123.145.244.5 </Directory>
If multiple directory sections match the directory (or its
parents), then the directives are applied with the shortest
match first. For example if you have one directory section for
garden/
and one for garden/flowers
, the garden/
section matches first.
Syntax: AuthDBType
plain | dets | mnesia
Default: - None -
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthAccessPassword,
AuthName,
AuthUserFile,
AuthGroupFile,
require
AuthDBType
sets the type of authentication database that is used
for the directory.The key difference between the different methods is that
dynamic data can be saved when Mnesia and Dets is used.
If Mnesia is used as storage method, Mnesia must be started prio to
the webserver. The first time Mnesia is started the schema and the
tables must be created before Mnesia is started. A naive example
of a module with two functions that creates and start mnesia is provided here.
The function shall be sued the first time. first_start/0
creates
the schema and the tables. The second function start/0
shall be used in consecutive startups. start/0
Starts Mnesia and wait
for the tables to be initiated. This function must only be used when
the schema and the tables already is created.
-module(mnesia_test). -export([start/0,load_data/0]). -include("mod_auth.hrl"). first_start()-> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(httpd_user, [{type,bag},{disc_copies,[node()]}, {attributes,record_info(fields,httpd_user)}]), mnesia:create_table(httpd_group, [{type,bag},{disc_copies,[node()]}, {attributes,record_info(fields,httpd_group)}]), mnesia:wait_for_tables([httpd_user,httpd_group],60000). start()-> mnesia:start(), mnesia:wait_for_tables([httpd_user,httpd_group],60000).
To create the Mnesia tables we use two records defined in mod_auth.hrl so the file must be included.
The first function first_start/0
creates a schema that specify
on which nodes the database shall reside. Then it starts Mnesia and creates
the tables. The first argument is the name of the tables, the second argument
is a list of options how the table will be created, see Mnesia documentation
for more information. Since the current implementation of the mod_auth_mnesia
saves one row for each user the type must be bag.
When the schema and the tables is created the second function start/0
shall be used to
start Mensia. It starts Mnesia and wait for the tables to be loaded. Mnesia use
the directory specified as mnesia_dir
at startup if specified, otherwise Mnesia
use the current directory.
For security reasons, make sure that the Mnesia tables are stored outside the document tree of the Web server. If it is placed in the directory which it protects, clients will be able to download the tables. |
Only the |
Syntax: AuthUserFile
filename
Default: - None -
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthDBType,
AuthAccessPassword,
AuthGroupFile,
AuthName,
require
AuthUserFile
sets the name of a file which contains the list
of users and passwords for user authentication. filename
can be either absolute
or relative to the ServerRoot
.
If using the plain
storage method, this file is a plain text file, where each
line contains a user name followed by a colon, followed by the non-encrypted
password.
The behavior is undefined if user names are duplicated. For
example:
ragnar:s7Xxv7 edward:wwjau8
If using the dets
storage method, the user database is maintained by
dets
and should not be edited by hand. Use the
API in this module to create / edit the
user database.
This directive is ignored if using the mnesia
storage method.
For security reasons, make sure that the |
Syntax: AuthGroupFile
filename
Default: - None -
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthName,
AuthUserFile,
AuthDBType,
AuthAccessPassword,
require
AuthGroupFile
sets the name of a file which contains the list
of user groups for user authentication. filename
can be either absolute
or relative to the ServerRoot
.
If you use the plain
storage method, the group file is a plain text
file, where each line contains a group name followed by a colon, followed by
the member user names separated by spaces. For example:
group1: bob joe ante
If using the dets
storage method, the group database is maintained by
dets
and should not be edited by hand. Use the
API in this module to create / edit the
group database.
This directive is ignored if using the mnesia
storage method.
For security reasons, make sure that the |
Syntax: AuthName
auth-domain
Default: - None -
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthGroupFile,
AuthUserFile,
AuthDBType,
AuthAccessPassword,
require
AuthName
sets the name of the authorization realm
(auth-domain
) for a directory. This string informs the
client about which user name and password to use.
Syntax: AuthAccessPassword
password
Default: NoPassword
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthGroupFile,
AuthUserFile,
AuthDBType,
AuthName,
require
If AuthAccessPassword
is set to other than NoPassword the password is
required for all API calls. If the password is set to DummyPassword the password must
be changed before any other API calls. To secure the authenticating data the password
must be changed after the webserver is started since it otherwise is written in clear
text in the configuration file.
Syntax: allow from
host host ...
Default: allow from all
Module: mod_auth(3)
Context: <Directory>
Related: AuthAccessPassword,
deny,
AuthUserFile,
AuthGroupFile,
AuthName,
AuthDBType
require
allow
defines a set of hosts which should be granted
access to a given directory. host
is one of the following:
all
regexp(3)
)
For example:
allow from 123.34.56.11 150.100.23
The host 123.34.56.11 and all machines on the 150.100.23 subnet are allowed access.
Syntax: deny from
host host ...
Default: deny from all
Module: mod_auth(3)
Context: <Directory>
Related: allow,
AuthUserFile,
AuthGroupFile,
AuthName,
AuthDBType,
AuthAccessPassword,
require
deny
defines a set of hosts which should not be granted
access to a given directory. host
is one of the following:
all
regexp(3)
)
For example:
deny from 123.34.56.11 150.100.23
The host 123.34.56.11 and all machines on the 150.100.23 subnet are denied access.
Syntax: require
entity-name entity entity ...
Default: - None -
Module: mod_auth(3)
Context: <Directory>
Related: allow,
deny,
AuthUserFile,
AuthGroupFile,
AuthName,
AuthDBType,
AuthAccessPassword
require
defines users which should be granted
access to a given directory using a secret password. The allowed
syntaxes are:
require user user-name user-name ...
require group group-name group-name ...
Uses the following EWSAPI interaction data, if available:
{real_name, {Path, AfterPath}}
Exports the following EWSAPI interaction data, if possible:
{remote_user, User}
Uses the following exported EWSAPI functions:
add_user(UserName, Options) ->
true| {error, Reason}
add_user(UserName, Password, UserData, Port, Dir)
-> true | {error, Reason}
add_user(UserName, Password, UserData, Address, Port, Dir)
-> true | {error, Reason}
Types:
UserName = string()
Options = [Option]
Option = {password,Password} | {userData,UserData} | {port,Port} |
{addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Password = string()
UserData = term()
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
AuthPassword =string()
Reason = term()
add_user/2, add_user/5
and add_user/6
adds a user to the user
database. If the operation is succesful, this function returns
true
. If an error occurs, {error,Reason}
is returned. When add_user/2
is called the Password, UserData Port and Dir options is mandatory.
delete_user(UserName,Options)
-> true | {error, Reason}
delete_user(UserName, Port, Dir)
-> true | {error, Reason}
delete_user(UserName, Address, Port, Dir)
-> true | {error, Reason}
Types:
UserName = string()
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
AuthPassword = string()
Reason = term()
delete_user/2, delete_user/3
and delete_user/4
deletes a user
from the user database. If the operation is succesful, this
function returns true
. If an error occurs,
{error,Reason}
is returned. When delete_user/2
is
called the Port and Dir options are mandatory.
get_user(UserName,Options)
-> {ok, #httpd_user} |{error, Reason}
get_user(UserName, Port, Dir)
-> {ok, #httpd_user} | {error, Reason}
get_user(UserName, Address, Port, Dir)
-> {ok, #httpd_user} | {error, Reason}
Types:
UserName = string()
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
AuthPassword = string()
Reason = term()
get_user/2, get_user/3
and get_user/4
returns a
httpd_user
record containing the userdata for a
specific user. If the user cannot be found, {error, Reason}
is returned. When get_user/2
is called the Port and Dir
options are mandatory.
list_users(Options)
-> {ok, Users} | {error, Reason}
<name>list_users(Port, Dir)
-> {ok, Users} | {error, Reason}
list_users(Address, Port, Dir)
-> {ok, Users} | {error, Reason}
Types:
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
Users = list()
AuthPassword = string()
Reason = atom()
list_users/1, list_users/2
and list_users/3
returns a list
of users in the user database for a specific Port/Dir
.
When list_users/1
is called the Port and Dir
options are mandatory.
add_group_member(GroupName, UserName, Options)
-> true | {error, Reason}
add_group_member(GroupName, UserName, Port, Dir)
-> true | {error, Reason}
add_group_member(GroupName, UserName, Address, Port, Dir)
-> true | {error, Reason}
Types:
GroupName = string()
UserName = string()
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
AuthPassword = string()
Reason = term()
add_group_member/3, add_group_member/4
and add_group_member/5
adds a user to a group. If the group does not exist, it
is created and the user is added to the group. Upon successful
operation, this function returns true
. When add_group_members/3
is called the Port and Dir options are mandatory.
delete_group_member(GroupName, UserName, Options)
-> true | {error, Reason}
delete_group_member(GroupName, UserName, Port, Dir)
-> true | {error, Reason}
delete_group_member(GroupName, UserName, Address, Port, Dir)
-> true | {error, Reason}
Types:
GroupName = string()
UserName = string()
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
AuthPassword = string()
Reason = term()
delete_group_member/3, delete_group_member/4
and delete_group_member/5
deletes a user from a group.
If the group or the user does not exist,
this function returns an error, otherwise it returns true
.
When delete_group_member/3
is called the Port and Dir options
are mandatory.
list_group_members(GroupName, Options)
-> {ok, Users} | {error, Reason}
list_group_members(GroupName, Port, Dir)
-> {ok, Users} | {error, Reason}
list_group_members(GroupName, Address, Port, Dir)
-> {ok, Users} | {error, Reason}
Types:
GroupName = string()
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
Users = list()
AuthPassword = string()
Reason = term()
list_group_members/2, list_group_members/3
and list_group_members/4
lists the members of a specified group. If the group does not
exist or there is an error, {error, Reason}
is returned.
When list_group_members/2
is called the Port and Dir options
are mandatory.
list_groups(Options)
-> {ok, Groups} | {error, Reason}
list_groups(Port, Dir)
-> {ok, Groups} | {error, Reason}
list_groups(Address, Port, Dir)
-> {ok, Groups} | {error, Reason}
Types:
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
Groups = list()
AuthPassword = string()
Reason = term()
list_groups/1, list_groups/2
and list_groups/3
lists all
the groups available. If there is an error, {error, Reason}
is returned. When list_groups/1
is called the Port and Dir options
are mandatory.
delete_group(GroupName, Options)
-> true | {error,Reason}
<name>delete_group(GroupName, Port, Dir)
-> true | {error, Reason}
delete_group(GroupName, Address, Port, Dir)
-> true | {error, Reason}
Types:
Options = [Option]
Option = {port,Port} | {addr,Address} | {dir,Directory} | {authPassword,AuthPassword}
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
GroupName = string()
AuthPassword = string()
Reason = term()
delete_group/2, delete_group/3
and delete_group/4
deletes the
group specified and returns true
. If there is an error,
{error, Reason}
is returned. When delete_group/2
is called the
Port and Dir options are mandatory.
update_password(Port, Dir, OldPassword, NewPassword, NewPassword)
-> ok | {error, Reason}
update_password(Address,Port, Dir, OldPassword, NewPassword, NewPassword)
-> ok | {error, Reason}
Types:
Port = integer()
Address = {A,B,C,D} | string() | undefined
Dir = string()
GroupName = string()
OldPassword = string()
NewPassword = string()
Reason = term()
update_password/5
and update_password/6
Updates the AuthAccessPassword
for the specified directory. If NewPassword is equal to "NoPassword" no password is requires to
change authorisation data. If NewPassword is equal to "DummyPassword" no changes can be done
without changing the password first.