From b4c5240c82ca7794dac1dcbaf954db6a997f561a Mon Sep 17 00:00:00 2001
From: s3lph <account-gitlab-ideynizv@kernelpanic.lol>
Date: Sat, 19 Dec 2020 02:44:37 +0100
Subject: [PATCH] Make NickServ & ChanServ configurable

---
 .../defaults/{main.yml => main/anope.yml}     |    0
 roles/anope/defaults/main/chanserv.yml        |   23 +
 roles/anope/defaults/main/nickserv.yml        |   31 +
 roles/anope/tasks/config.yml                  |   10 +-
 .../templates/etc/anope/chanserv.conf.j2      | 1179 +++++++++++++++++
 .../templates/etc/anope/nickserv.conf.j2      |  505 +++++++
 6 files changed, 1745 insertions(+), 3 deletions(-)
 rename roles/anope/defaults/{main.yml => main/anope.yml} (100%)
 create mode 100644 roles/anope/defaults/main/chanserv.yml
 create mode 100644 roles/anope/defaults/main/nickserv.yml
 create mode 100644 roles/anope/templates/etc/anope/chanserv.conf.j2
 create mode 100644 roles/anope/templates/etc/anope/nickserv.conf.j2

diff --git a/roles/anope/defaults/main.yml b/roles/anope/defaults/main/anope.yml
similarity index 100%
rename from roles/anope/defaults/main.yml
rename to roles/anope/defaults/main/anope.yml
diff --git a/roles/anope/defaults/main/chanserv.yml b/roles/anope/defaults/main/chanserv.yml
new file mode 100644
index 0000000..85db416
--- /dev/null
+++ b/roles/anope/defaults/main/chanserv.yml
@@ -0,0 +1,23 @@
+---
+
+anope_chanserv_service_nick: ChanServ
+anope_chanserv_servie_user: services
+anope_chanserv_service_host: services.host
+anope_chanserv_service_gecos: Channel Registration Service
+
+anope_chanserv_module_client: ChanServ
+anope_chanserv_module_defaults:
+  - keeptopic
+  - peace
+  - cs_secure
+  - securefounder
+  - signkick
+anope_chanserv_module_maxregistered: 20
+anope_chanserv_module_expire: 14d
+anope_chanserv_module_accessmax: 1024
+anope_chanserv_module_inhabit: 15s
+anope_chanserv_module_reasonmax:  200
+anope_chanserv_module_signkickformat: "%m (%n)"
+anope_chanserv_module_disallow_hostmask_access: no
+anope_chanserv_module_disallow_channel_access: no
+anope_chanserv_module_always_lower_ts: no
diff --git a/roles/anope/defaults/main/nickserv.yml b/roles/anope/defaults/main/nickserv.yml
new file mode 100644
index 0000000..92f95fe
--- /dev/null
+++ b/roles/anope/defaults/main/nickserv.yml
@@ -0,0 +1,31 @@
+---
+
+anope_nickserv_service_nick: NickServ
+anope_nickserv_servie_user: services
+anope_nickserv_service_host: services.host
+anope_nickserv_service_gecos: Nickname Registration Service
+
+anope_nickserv_module_client: NickServ
+anope_nickserv_module_forceemail: yes
+anope_nickserv_module_confirmemailchanges: no
+anope_nickserv_module_defaults:
+  - ns_secure
+  - ns_private
+  - hide_email
+  - hide_mask
+  - memo_signon
+  - memo_receive
+  - autoop
+anope_nickserv_module_regdelay: 30s
+anope_nickserv_module_expire: 21d
+anope_nickserv_module_secureadmins:  yes
+anope_nickserv_module_modeonid: yes
+anope_nickserv_module_hidenetsplitquit: no
+anope_nickserv_module_killquick: 20s
+anope_nickserv_module_kill: 60s
+anope_nickserv_module_enforceruser: enforcer
+anope_nickserv_module_enforcerhost: services.host
+anope_nickserv_module_releasetimeout: 1m
+anope_nickserv_module_guestnickprefix: Guest
+anope_nickserv_module_nonicknameownership: no
+anope_nickserv_module_passlen: 32
diff --git a/roles/anope/tasks/config.yml b/roles/anope/tasks/config.yml
index cf686dc..ec0d3ba 100644
--- a/roles/anope/tasks/config.yml
+++ b/roles/anope/tasks/config.yml
@@ -1,12 +1,16 @@
 ---
 
-- name: render /etc/anope/services.conf
+- name: render anope config files
   template:
-    src: etc/anope/services.conf.j2
-    dest: /etc/anope/services.conf
+    src: /etc/anope/{{ item }}.conf.j2
+    dest: /etc/anope/{{ item }}.conf
     owner: root
     group: irc
     mode: 0640
+  loop:
+    - services
+    - nickserv
+    - chanserv
   notify: restart anope
 
 - name: render /etc/default/anope
diff --git a/roles/anope/templates/etc/anope/chanserv.conf.j2 b/roles/anope/templates/etc/anope/chanserv.conf.j2
new file mode 100644
index 0000000..d90d872
--- /dev/null
+++ b/roles/anope/templates/etc/anope/chanserv.conf.j2
@@ -0,0 +1,1179 @@
+/*
+{{ ansible_managed | comment(decoration=' *  ') }}
+ */
+
+service
+{
+	nick = "{{ anope_chanserv_service_nick }}"
+	user = "{{ anope_chanserv_servie_user }}"
+	host = "{{ anope_chanserv_service_host }}"
+	gecos = "{{ anope_chanserv_service_gecos }}"
+{% if anope_chanserv_service_modes is defined %}
+	modes = "{{ anope_chanserv_service_modes }}"
+{% endif %}
+{% if anope_chanserv_service_modes is defined %}
+	channels = "{{ anope_chanserv_service_channels }}"
+{% endif %}
+}
+
+module
+{
+	name = "chanserv"
+	client = "{{ anope_chanserv_module_client }}"
+	maxregistered = {{ anope_chanserv_module_maxregistered }}
+	expire = {{ anope_chanserv_module_expire }}
+	accessmax = {{ anope_chanserv_module_accessmax }}
+	inhabit = {{ anope_chanserv_module_inhabit }}
+{% if anope_chanserv_service_opersonly is defined %}
+	opersonly = {{ anope_chanserv_service_opersonly }}
+{% endif %}
+{% if anope_chanserv_service_nomlock is defined %}
+	nomlock = "{{ anope_chanserv_service_nomlock }}"
+{% endif %}
+{% if anope_chanserv_service_require is defined %}
+	require = "{{ anope_chanserv_service_require }}"
+{% endif %}
+	reasonmax = {{ anope_chanserv_module_reasonmax }}
+	signkickformat =  "{{ anope_chanserv_module_signkickformat }}"
+	disallow_hostmask_access = {{ anope_chanserv_module_disallow_hostmask_access | ternary('yes', 'no') }}
+	disallow_channel_access = {{ anope_chanserv_module_disallow_channel_access | ternary('yes', 'no') }}
+	always_lower_ts = {{ anope_chanserv_module_always_lower_ts | ternary('yes', 'no') }}
+}
+
+/*
+ * ChanServ privilege configuration.
+ *
+ * ChanServ privileges are used to determine who has what access in channels. By default the core has its own
+ * set of privileges it uses for various commands, which are defined below. Privilege ranks are used to
+ * determine how powerful privileges are relative to other privileges, which is used by Anope to determine
+ * who has greater access in a channel.
+ *
+ * If you load cs_access, you may define a level for the privilege, which is used by chanserv/access and chanserv/levels.
+ * The levels defined will be used as the default levels for newly registered channels.
+ * The level "founder" is a special level which means anyone with the privilege FOUNDER on the channel
+ * has that permission. Additionally, the level "disabled" means that no one can use the privilege, including founders.
+ *
+ * If you load cs_flags, you may define a flag associated with that privilege for use in chanserv/flags.
+ *
+ * If you load cs_xop, you may define a XOP command to associate the privilege with.
+ *
+ * The name of privileges are uesd to associate them with channel modes. If you are using an IRCd that allows you to define additional
+ * channel status modes, such as InspIRCd, you can associate privileges (and thus access levels, flags, xop) with the mode by naming
+ * the privileges appropriately. For example, if you had a channel mode called admin, you could create AUTOADMIN, ADMIN, and ADMINME
+ * privileges which would automatically be associated with that channel mode.
+ *
+ * Defining new privileges here is not useful unless you have a module (eg, a third party one) made to check for
+ * the specific level you are defining.
+ *
+ * Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
+ */
+
+/*
+ * ACCESS_CHANGE privilege.
+ *
+ * Used by chanserv/access, chanserv/flags and chanserv/xop.
+ *
+ * Users with this permission can modify the permissions of others.
+ */
+privilege
+{
+	name = "ACCESS_CHANGE"
+	rank = 0
+	level = 10
+	flag = "f"
+	xop = "SOP"
+}
+
+/*
+ * ACCESS_LIST privilege.
+ *
+ * Used by chanserv/access, chanserv/flags, and chanserv/xop.
+ *
+ * Users with this permission can view the access list of channels.
+ */
+privilege
+{
+	name = "ACCESS_LIST"
+	rank = 10
+	level = 3
+	flag = "f"
+	xop = "VOP"
+}
+
+/*
+ * AKICK privilege.
+ *
+ * Used by chanserv/akick and chanserv/enforce.
+ *
+ * Users with this permission can modify the AKICK list.
+ */
+privilege
+{
+	name = "AKICK"
+	rank = 250
+	level = 10
+	flag = "K"
+	xop = "SOP"
+}
+
+/*
+ * ASSIGN privilege.
+ *
+ * Used by botserv/assign.
+ *
+ * Users with this permission can assign and unassign BotServ bots to and from the channel.
+ */
+privilege
+{
+	name = "ASSIGN"
+	rank = 270
+	level = "founder"
+	flag = "s"
+	xop = "QOP"
+}
+
+/*
+ * AUTOHALFOP privilege.
+ *
+ * Used by the core.
+ *
+ * Users with this permission get halfop on join.
+ */
+privilege
+{
+	name = "AUTOHALFOP"
+	rank = 100
+	level = 4
+	flag = "H"
+	xop = "HOP"
+}
+
+/*
+ * AUTOOP privilege.
+ *
+ * Used by the core.
+ *
+ * Users with this permission get op on join.
+ */
+privilege
+{
+	name = "AUTOOP"
+	rank = 210
+	level = 5
+	flag = "O"
+	xop = "AOP"
+}
+
+/*
+ * AUTOOWNER privilege.
+ *
+ * Used by the core.
+ *
+ * Users with this permission get owner on join.
+ */
+privilege
+{
+	name = "AUTOOWNER"
+	rank = 330
+	level = 9999
+	flag = "Q"
+	xop = "QOP"
+}
+
+/*
+ * AUTOPROTECT privilege.
+ *
+ * Used by the core.
+ *
+ * Users with this permission get admin on join.
+ */
+privilege
+{
+	name = "AUTOPROTECT"
+	rank = 240
+	level = 10
+	flag = "A"
+	xop = "SOP"
+}
+
+/*
+ * AUTOVOICE privilege.
+ *
+ * Used by the core.
+ *
+ * Users with this permission get voice on join.
+ */
+privilege
+{
+	name = "AUTOVOICE"
+	rank = 50
+	level = 3
+	flag = "V"
+	xop = "VOP"
+}
+
+/*
+ * BADWORDS privilege.
+ *
+ * Used by botserv/badwords.
+ *
+ * Users with this permission can modify BotServ's BADWORDS list.
+ */
+privilege
+{
+	name = "BADWORDS"
+	rank = 260
+	level = 10
+	flag = "K"
+	xop = "SOP"
+}
+
+/*
+ * BAN privilege.
+ *
+ * Used by chanserv/ban.
+ *
+ * Users with this permission can use the BAN command.
+ */
+privilege
+{
+	name = "BAN"
+	rank = 150
+	level = 4
+	flag = "b"
+	xop = "HOP"
+}
+
+/*
+ * FANTASIA privilege.
+ *
+ * Used by botserv/main and chanserv/xop.
+ *
+ * Users with this permission can use fantasy commands in the channel.
+ */
+privilege
+{
+	name = "FANTASIA"
+	rank = 30
+	level = 3
+	flag = "c"
+	xop = "VOP"
+}
+
+/*
+ * FOUNDER privilege.
+ *
+ * Used by chanserv/access, chanserv/akick,
+ * chanserv/drop, chanserv/set/founder,
+ * chanserv/set/securefounder, chanserv/set/successor and chanserv/xop.
+ *
+ * Users with this permission are treated as founders and can use
+ * commands restricted to founders.
+ */
+privilege
+{
+	name = "FOUNDER"
+	rank = 360
+	level = 10000
+	flag = "F"
+	xop = "QOP"
+}
+
+/*
+ * GETKEY privilege.
+ *
+ * Used by chanserv/getkey and nickserv/ajoin.
+ *
+ * Users with this permission can get they channel key with GETKEY and
+ * can use nickserv/ajoin to join channels with keys.
+ */
+privilege
+{
+	name = "GETKEY"
+	rank = 180
+	level = 5
+	flag = "G"
+	xop = "AOP"
+}
+
+/*
+ * HALFOP privilege.
+ *
+ * Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop.
+ *
+ * Users with this permission can use ChanServ to halfop and dehalfop
+ * others in the channel.
+ */
+privilege
+{
+	name = "HALFOP"
+	rank = 120
+	level = 5
+	flag = "h"
+	xop = "AOP"
+}
+
+/*
+ * HALFOPME privilege.
+ *
+ * Used by chanserv/mode, chanserv/halfop and chanserv/dehalfop.
+ *
+ * Users with this permission can use ChanServ to halfop and dehalfop
+ * themselves in the channel.
+ */
+privilege
+{
+	name = "HALFOPME"
+	rank = 110
+	level = 4
+	flag = "h"
+	xop = "HOP"
+}
+
+/*
+ * INFO privilege.
+ *
+ * Used by botserv/info and chanserv/info.
+ *
+ * Users with this permission are allowed to get the full INFO output
+ * from BotServ and ChanServ.
+ */
+privilege
+{
+	name = "INFO"
+	rank = 80
+	level = 9999
+	flag = "I"
+	xop = "QOP"
+}
+
+/*
+ * INVITE privilege.
+ *
+ * Used by chanserv/invite and nickserv/ajoin.
+ *
+ * Users with this permission can invite users through ChanServ and
+ * join invite only channels with nickserv/ajoin.
+ */
+privilege
+{
+	name = "INVITE"
+	rank = 190
+	level = 5
+	flag = "i"
+	xop = "AOP"
+}
+
+/*
+ * KICK privilege.
+ *
+ * Used by chanserv/kick.
+ *
+ * Users with this permission can use the KICK command.
+ */
+privilege
+{
+	name = "KICK"
+	rank = 130
+	level = 4
+	flag = "k"
+	xop = "HOP"
+}
+
+/*
+ * MEMO privilege.
+ *
+ * Used by memoserv/del, memoserv/ignore, memoserv/info, memoserv/list,
+ * memoserv/main, memoserv/read and memoserv/set.
+ *
+ * Users with this permission can manage channel memos.
+ */
+privilege
+{
+	name = "MEMO"
+	rank = 280
+	level = 10
+	flag = "m"
+	xop = "SOP"
+}
+
+/*
+ * MODE privilege.
+ *
+ * Used by chanserv/mode.
+ *
+ * Users with this permission can set modes through ChanServ and change
+ * the mode lock.
+ */
+privilege
+{
+	name = "MODE"
+	rank = 170
+	level = 9999
+	flag = "s"
+	xop = "QOP"
+}
+
+/*
+ * NOKICK privilege.
+ *
+ * Used by botserv/kick.
+ *
+ * Users with this permission are spared from automated BotServ kicks.
+ */
+privilege
+{
+	name = "NOKICK"
+	rank = 20
+	level = 1
+	flag = "N"
+	xop = "VOP"
+}
+
+/*
+ * OP privilege.
+ *
+ * Used by chanserv/mode, chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to op and deop
+ * others in the channel.
+ */
+privilege
+{
+	name = "OP"
+	rank = 230
+	level = 5
+	flag = "o"
+	xop = "SOP"
+}
+
+/*
+ * OPME privilege.
+ *
+ * Used by chanserv/mode, chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to op and deop
+ * themselves in the channel.
+ */
+privilege
+{
+	name = "OPME"
+	rank = 220
+	level = 5
+	flag = "o"
+	xop = "AOP"
+}
+
+/*
+ * OWNER privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to owner and deowner
+ * others in the channel.
+ */
+privilege
+{
+	name = "OWNER"
+	rank = 350
+	level = "founder"
+	flag = "q"
+	xop = "QOP"
+}
+
+/*
+ * OWNERME privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to owner and deowner
+ * themselves in the channel.
+ */
+privilege
+{
+	name = "OWNERME"
+	rank = 340
+	level = 9999
+	flag = "q"
+	xop = "QOP"
+}
+
+/*
+ * PROTECT privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to protect and deprotect
+ * others in the channel.
+ */
+privilege
+{
+	name = "PROTECT"
+	rank = 310
+	level = 9999
+	flag = "a"
+	xop = "QOP"
+}
+
+/*
+ * PROTECTME privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to protect and deprotect
+ * themselves in the channel.
+ */
+privilege
+{
+	name = "PROTECTME"
+	rank = 300
+	level = 10
+	flag = "a"
+	xop = "AOP"
+}
+
+/*
+ * SAY privilege.
+ *
+ * Used by botserv/control.
+ *
+ * Users with this permission can use the BotServ bot in the channel to
+ * say or do a /me with the provided message.
+ */
+privilege
+{
+	name = "SAY"
+	rank = 90
+	level = 5
+	flag = "B"
+	xop = "AOP"
+}
+
+/*
+ * SET privilege.
+ *
+ * Used by botserv/kick, botserv/set, chanserv/clone, chanserv/log,
+ * chanserv/saset/noexpire and chanserv/set.
+ *
+ * Users with this permission can set what BotServ will kick for, change
+ * BotServ and ChanServ settings, clone ChanServ channel setings, and
+ * set ChanServ logging options.
+ */
+privilege
+{
+	name = "SET"
+	rank = 320
+	level = 9999
+	flag = "s"
+	xop = "QOP"
+}
+
+/*
+ * SIGNKICK privilege.
+ *
+ * Used by chanserv/ban and chanserv/kick.
+ *
+ * Users with this permission won't get their nick shown in the kick
+ * through ChanServ when the setting SIGNKICK is set to LEVEL.
+ */
+privilege
+{
+	name = "SIGNKICK"
+	rank = 140
+	level = 9999
+	flag = "K"
+	xop = "QOP"
+}
+
+/*
+ * TOPIC privilege.
+ *
+ * Used by chanserv/topic.
+ *
+ * Users with this permission can change the channel topic through ChanServ.
+ */
+privilege
+{
+	name = "TOPIC"
+	rank = 160
+	level = 5
+	flag = "t"
+	xop = "AOP"
+}
+
+/*
+ * UNBAN privilege.
+ *
+ * Used by chanserv/unban.
+ *
+ * Users with this permission can unban themselves and others through ChanServ.
+ */
+privilege
+{
+	name = "UNBAN"
+	rank = 200
+	level = 4
+	flag = "u"
+	xop = "HOP"
+}
+
+/*
+ * VOICE privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to voice and devoice
+ * others in the channel.
+ */
+privilege
+{
+	name = "VOICE"
+	rank = 70
+	level = 4
+	flag = "v"
+	xop = "HOP"
+}
+
+/*
+ * VOICEME privilege.
+ *
+ * Used by chanserv/mode and chanserv/modes.
+ *
+ * Users with this permission can use ChanServ to voice and devoice
+ * themselves in the channel.
+ */
+privilege
+{
+	name = "VOICEME"
+	rank = 60
+	level = 3
+	flag = "v"
+	xop = "VOP"
+}
+
+/*
+ * Core ChanServ commands.
+ *
+ * In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
+ * are loaded you can then configure the commands to be added to any client you like with any name you like.
+ *
+ * Additionally, you may provide a permission name that must be in the opertype of users executing the command.
+ *
+ * Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
+ */
+
+/* Command group configuration for ChanServ.
+ *
+ * Commands may optionally be placed into groups to make ChanServ's HELP output easier to understand.
+ * Remove the following groups to use the old behavior of simply listing all ChanServ commands from HELP.
+ */
+command_group
+{
+	name = "chanserv/access"
+	description = _("Used to manage the list of privileged users")
+}
+
+command_group
+{
+	name = "chanserv/status"
+	description = _("Used to modify the channel status of you or other users")
+}
+
+command_group
+{
+	name = "chanserv/management"
+	description = _("Used to manage channels")
+}
+
+command_group
+{
+	name = "chanserv/admin"
+	description = _("Services Operator commands")
+}
+
+/* Give it a help command. */
+command { service = "ChanServ"; name = "HELP"; command = "generic/help"; }
+
+/*
+ * cs_access
+ *
+ * Provides commands chanserv/access and chanserv/levels.
+ * Provides the access system "levels".
+ *
+ * Used for giving users access in channels using a levels system. Allows allows redefining which privileges
+ * are representated by given level on a per channel basis.
+ *
+ * The "LIST" subcommand of chanserv/access will show every access entry on the channel, including access
+ * entries not added by cs_access. The "level" of these entries will be the representation of the access
+ * entry by the other access system, which could be an XOP command name, or a set of flags.
+ */
+module { name = "cs_access" }
+command { service = "ChanServ"; name = "ACCESS"; command = "chanserv/access"; group = "chanserv/access"; }
+command { service = "ChanServ"; name = "LEVELS"; command = "chanserv/levels"; group = "chanserv/access"; }
+
+/*
+ * cs_akick
+ *
+ * Provides the command chanserv/akick.
+ *
+ * Used for preventing users from joining channels.
+ */
+module
+{
+	name = "cs_akick"
+
+	/*
+	 * The maximum number of entries on a channel's autokick list.
+	 */
+	autokickmax = 32
+
+	/*
+	 * The default reason for an autokick if none is given.
+	 */
+	autokickreason = "User has been banned from the channel"
+}
+command { service = "ChanServ"; name = "AKICK"; command = "chanserv/akick"; group = "chanserv/management"; }
+
+/*
+ * cs_ban
+ *
+ * Provides the command chanserv/ban.
+ *
+ * The configuration option 'kick' may be set in a command block for this command to control
+ * whether or not users will be kicked from the channel once banned. The default is 'yes'.
+ *
+ * The configuration option 'mode' may be set to control which mode is set, such as BAN or QUIET.
+ * The default is BAN.
+ *
+ * Used for banning users from channels.
+ */
+module { name = "cs_ban" }
+command { service = "ChanServ"; name = "BAN"; command = "chanserv/ban"; }
+
+/*
+ * cs_clone
+ *
+ * Provides the command chanserv/clone.
+ *
+ * Used for copying channel settings from one channel to another.
+ */
+module { name = "cs_clone" }
+command { service = "ChanServ"; name = "CLONE"; command = "chanserv/clone"; group = "chanserv/management"; }
+
+/*
+ * cs_drop
+ *
+ * Provides the command chanserv/drop.
+ *
+ * Used for unregistering channels.
+ */
+module { name = "cs_drop" }
+command { service = "ChanServ"; name = "DROP"; command = "chanserv/drop"; }
+
+/*
+ * cs_enforce
+ *
+ * Provides the command chanserv/enforce.
+ *
+ * Used to enforce various channel settings such as secureops and restricted.
+ */
+module { name = "cs_enforce" }
+command { service = "ChanServ"; name = "ENFORCE"; command = "chanserv/enforce"; group = "chanserv/management"; }
+
+/*
+ * cs_entrymsg
+ *
+ * Provides the command chanserv/entrymsg.
+ *
+ * Used to configure entry messages sent to users when they join a channel.
+ */
+module
+{
+	name = "cs_entrymsg"
+
+	/* The maximum number of entrymsgs allowed per channel. If not set, defaults to 5. */
+	maxentries = 5
+}
+command { service = "ChanServ"; name = "ENTRYMSG"; command = "chanserv/entrymsg"; group = "chanserv/management"; }
+
+/*
+ * cs_flags
+ *
+ * Provides the command chanserv/flags.
+ * Provides the access system "flags".
+ *
+ * Used for giving users access in channels.
+ *
+ * The "LIST" subcommand of chanserv/flags will show every access entry on the channel, including access
+ * entries not added by cs_flags. The "Flags" of these entries will be the flags representation of the
+ * privilege set granted by the access entry.
+ */
+module { name = "cs_flags" }
+command { service = "ChanServ"; name = "FLAGS"; command = "chanserv/flags"; group = "chanserv/access"; }
+
+/*
+ * cs_getkey
+ *
+ * Provides the command chanserv/getkey.
+ *
+ * Used for getting the key for channels.
+ */
+module { name = "cs_getkey" }
+command { service = "ChanServ"; name = "GETKEY"; command = "chanserv/getkey"; }
+
+/*
+ * cs_info
+ *
+ * Provides the command chanserv/info.
+ *
+ * Used for getting information about channels.
+ */
+module { name = "cs_info" }
+command { service = "ChanServ"; name = "INFO"; command = "chanserv/info"; }
+
+/*
+ * cs_invite
+ *
+ * Provides the command chanserv/invite.
+ *
+ * Used for inviting yourself in to channels.
+ */
+module { name = "cs_invite" }
+command { service = "ChanServ"; name = "INVITE"; command = "chanserv/invite"; }
+
+/*
+ * cs_kick
+ *
+ * Provides the command chanserv/kick.
+ *
+ * Used for kicking users from channels.
+ */
+module { name = "cs_kick" }
+command { service = "ChanServ"; name = "KICK"; command = "chanserv/kick"; }
+
+/*
+ * cs_list
+ *
+ * Provides the commands:
+ *   chanserv/list - Used for retrieving and searching the registered channel list.
+ *   chanserv/set/private - Used for setting whether channels should show up in chanserv/list.
+ */
+module
+{
+	name = "cs_list"
+
+	/*
+	 * The maximum number of channels to be returned for a ChanServ LIST command.
+	 */
+	listmax = 50
+}
+command { service = "ChanServ"; name = "LIST"; command = "chanserv/list"; }
+
+command { service = "ChanServ"; name = "SET PRIVATE"; command = "chanserv/set/private"; }
+
+
+/*
+ * cs_log
+ *
+ * Provides the command chanserv/log.
+ *
+ * Use for configuring what actions on channels are logged and where.
+ */
+module
+{
+	name = "cs_log"
+
+	/* Default log settings for newly registered channels */
+
+	#default
+	{
+		command = "chanserv/modes"
+		method = "MESSAGE @"
+	}
+
+	#default
+	{
+		service = "ChanServ"
+		command = "ACCESS"
+		method = "MESSAGE @"
+	}
+
+	#default
+	{
+		command = "chanserv/xop"
+		method = "MESSAGE @"
+	}
+
+	#default
+	{
+		service = "ChanServ"
+		command = "FLAGS"
+		method = "MESSAGE @"
+	}
+}
+command { service = "ChanServ"; name = "LOG"; command = "chanserv/log"; group = "chanserv/management"; }
+
+/*
+ * cs_mode
+ *
+ * Provides the command chanserv/mode and chanserv/modes.
+ *
+ * Used for changing mode locks and changing modes. Multiple commands may be mapped to chanserv/modes, the
+ * configuration directive 'set' and 'unset' are used to tell chanserv/modes which modes should be set or
+ * unset when the command is executed.
+ */
+module
+{
+	name = "cs_mode"
+
+	/*
+	 * Default modes for mode lock, these are set on newly registered channels.
+	 *
+	 * If not set, the default is +nt.
+	 */
+	mlock = "+nt"
+
+	/*
+	 * The maximum number of entries that may be on a mode lock list.
+	 *
+	 * This directive is optional.
+	 */
+	max = 32
+}
+command { service = "ChanServ"; name = "MODE"; command = "chanserv/mode"; group = "chanserv/management"; }
+
+command { service = "ChanServ"; name = "OWNER"; command = "chanserv/modes"; group = "chanserv/status"; set = "OWNER" }
+command { service = "ChanServ"; name = "DEOWNER"; command = "chanserv/modes"; group = "chanserv/status"; unset = "OWNER" }
+
+command { service = "ChanServ"; name = "PROTECT"; command = "chanserv/modes"; group = "chanserv/status"; set = "PROTECT" }
+command { service = "ChanServ"; name = "DEPROTECT"; command = "chanserv/modes"; group = "chanserv/status"; unset = "PROTECT" }
+
+command { service = "ChanServ"; name = "OP"; command = "chanserv/modes"; group = "chanserv/status"; set = "OP" }
+command { service = "ChanServ"; name = "DEOP"; command = "chanserv/modes"; group = "chanserv/status"; unset = "OP" }
+
+command { service = "ChanServ"; name = "HALFOP"; command = "chanserv/modes"; group = "chanserv/status"; set = "HALFOP" }
+command { service = "ChanServ"; name = "DEHALFOP"; command = "chanserv/modes"; group = "chanserv/status"; unset = "HALFOP" }
+
+command { service = "ChanServ"; name = "VOICE"; command = "chanserv/modes"; group = "chanserv/status"; set = "VOICE" }
+command { service = "ChanServ"; name = "DEVOICE"; command = "chanserv/modes"; group = "chanserv/status"; unset = "VOICE" }
+
+
+/*
+ * cs_register
+ *
+ * Provides the commands chanserv/register.
+ *
+ * Used for registering channels.
+ */
+module { name = "cs_register" }
+command { service = "ChanServ"; name = "REGISTER"; command = "chanserv/register"; }
+
+/*
+ * cs_seen
+ *
+ * Provides the commands chanserv/seen and operserv/seen.
+ *
+ * Records the last time a user was seen and what they were doing and allows users to request this data.
+ * Also allows administrators to view stats about seen data and purge the database.
+ */
+module
+{
+	name = "cs_seen"
+
+	/* If set, uses the older 1.8 style seen, which is less resource intensive */
+	simple = false
+
+	/* Sets the time to keep seen entries in the seen database. */
+	purgetime = "30d"
+}
+command { service = "OperServ"; name = "SEEN"; command = "operserv/seen"; permission = "operserv/seen"; }
+
+/*
+ * cs_set
+ *
+ * Provides the commands:
+ *   chanserv/set and chanserv/saset - Dummy help wrappers for the SET commands.
+ *   chanserv/set/autoop - Used for configuring whether or not ChanServ automatically gives channel status to users.
+ *   chanserv/set/bantype - Used for controlling what format of bans are placed on channels.
+ *   chanserv/set/description - Used for changing channels descriptions.
+ *   chanserv/set/founder - Used for changing a channel's founder.
+ *   chanserv/set/keepmodes - Used for enabling or disabling keepmodes, which retains channel modes.
+ *   chanserv/set/peace - Used for configuring if users are able to kick other users with higher access than them.
+ *   chanserv/set/persist - Used for setting whether ChanServ should stay in channels after the last user leaves.
+ *   chanserv/set/restricted - Used for setting whether users not on a channel's access list can join.
+ *   chanserv/set/secure - Used for setting whether users who are recognized for accounts should have their access in channels.
+ *   chanserv/set/securefounder - Used for setting whether users with founder level access in channels have true founder or not.
+ *   chanserv/set/secureops - Used for restricting who can have channel op privilege in a channel to those whom have access in the channel.
+ *   chanserv/set/signkick - Used for setting signkick, which appends the kicker's name to kicks sent through ChanServ.
+ *   chanserv/set/successor - Used for setting channel successors, which become channel founders if the founders' account expires.
+ *   chanserv/saset/noexpire - Used for setting noexpire, which prevents channels from expiring.
+ *
+ * This is a dummy command to provide a help wrapper for the various SET commands.
+ */
+module
+{
+	name = "cs_set"
+
+	/*
+	 * The default ban type for newly registered channels.
+	 *
+	 * defbantype can be:
+	 *
+	 * 0: ban in the form of *!user@host
+	 * 1: ban in the form of *!*user@host
+	 * 2: ban in the form of *!*@host
+	 * 3: ban in the form of *!*user@*.domain
+	 */
+	defbantype = 2
+
+	/*
+	 * If set, persisent channels have their creation times lowered to their
+	 * original registration dates.
+	 */
+	persist_lower_ts = true
+}
+command { service = "ChanServ"; name = "SET"; command = "chanserv/set"; group = "chanserv/management"; }
+command { service = "ChanServ"; name = "SET AUTOOP"; command = "chanserv/set/autoop"; }
+command { service = "ChanServ"; name = "SET BANTYPE"; command = "chanserv/set/bantype"; }
+command { service = "ChanServ"; name = "SET DESCRIPTION"; command = "chanserv/set/description"; }
+command { service = "ChanServ"; name = "SET DESC"; command = "chanserv/set/description"; hide = yes; }
+command { service = "ChanServ"; name = "SET FOUNDER"; command = "chanserv/set/founder"; }
+command { service = "ChanServ"; name = "SET KEEPMODES"; command = "chanserv/set/keepmodes"; }
+command { service = "ChanServ"; name = "SET PEACE"; command = "chanserv/set/peace"; }
+command { service = "ChanServ"; name = "SET PERSIST"; command = "chanserv/set/persist"; }
+command { service = "ChanServ"; name = "SET RESTRICTED"; command = "chanserv/set/restricted"; }
+command { service = "ChanServ"; name = "SET SECURE"; command = "chanserv/set/secure"; }
+command { service = "ChanServ"; name = "SET SECUREFOUNDER"; command = "chanserv/set/securefounder"; }
+command { service = "ChanServ"; name = "SET SECUREOPS"; command = "chanserv/set/secureops"; }
+command { service = "ChanServ"; name = "SET SIGNKICK"; command = "chanserv/set/signkick"; }
+command { service = "ChanServ"; name = "SET SUCCESSOR"; command = "chanserv/set/successor"; }
+command { service = "ChanServ"; name = "SET NOEXPIRE"; command = "chanserv/saset/noexpire"; permission = "chanserv/saset/noexpire"; }
+
+/*
+ * cs_set_misc
+ *
+ * Provides the command chanserv/set/misc.
+ *
+ * Allows you to create arbitrary commands to set data, and have that data show up in chanserv/info.
+ * A field named misc_description may be given for use with help output.
+ */
+module { name = "cs_set_misc" }
+command { service = "ChanServ"; name = "SET URL"; command = "chanserv/set/misc"; misc_description = _("Associate a URL with the channel"); }
+command { service = "ChanServ"; name = "SET EMAIL"; command = "chanserv/set/misc"; misc_description = _("Associate an E-mail address with the channel"); }
+
+/*
+ * cs_status
+ *
+ * Provides the command chanserv/status.
+ *
+ * Used for determining a user's access on a channel and whether
+ * or not they match any autokick entries.
+ */
+module { name = "cs_status" }
+command { service = "ChanServ"; name = "STATUS"; command = "chanserv/status"; }
+
+/*
+ * cs_suspend
+ *
+ * Provides the commands chanserv/suspend and chanserv/unsuspend.
+ *
+ * Used for suspending and unsuspending channels. Suspended channels can not be used but their settings are stored.
+ */
+module
+{
+	name = "cs_suspend"
+
+	/*
+	 * The length of time before a suspended channel expires.
+	 *
+	 * This directive is optional.
+	 * If not set, the default is never.
+	 */
+	expire = 90d
+
+	/*
+	 * Settings to show to non-opers in ChanServ's INFO output.
+	 * Comment to completely disable showing any information about
+	 * suspended channels to non-opers.
+	 */
+	show = "suspended, by, reason, on, expires"
+}
+command { service = "ChanServ"; name = "SUSPEND"; command = "chanserv/suspend"; permission = "chanserv/suspend"; group = "chanserv/admin"; }
+command { service = "ChanServ"; name = "UNSUSPEND"; command = "chanserv/unsuspend"; permission = "chanserv/suspend"; group = "chanserv/admin"; }
+
+/*
+ * cs_sync
+ *
+ * Provides the command chanserv/sync.
+ *
+ * Used to sync users channel status modes with what access they have.
+ */
+module { name = "cs_sync" }
+command { service = "ChanServ"; name = "SYNC"; command = "chanserv/sync"; group = "chanserv/management"; }
+
+/*
+ * cs_topic
+ *
+ * Provides the commands:
+ *   chanserv/topic - Used for changing the channel topic. Useful in conjunction with chanserv/set/topiclock.
+ *   chanserv/set/keeptopic - Used for configuring if ChanServ is to restore the channel topic when a channel is created.
+ *
+ */
+module { name = "cs_topic" }
+command { service = "ChanServ"; name = "TOPIC"; command = "chanserv/topic"; group = "chanserv/management"; }
+command { service = "ChanServ"; name = "SET KEEPTOPIC"; command = "chanserv/set/keeptopic"; }
+
+/*
+ * cs_unban
+ *
+ * Provides the command chanserv/unban.
+ *
+ * Used for unbanning users from channels.
+ */
+module { name = "cs_unban" }
+command { service = "ChanServ"; name = "UNBAN"; command = "chanserv/unban"; }
+
+/*
+ * cs_updown
+ *
+ * Provides the commands chanserv/up and chanserv/down.
+ *
+ * Used for setting or removing your status modes on a channel.
+ */
+module { name = "cs_updown" }
+command { service = "ChanServ"; name = "DOWN"; command = "chanserv/down"; group = "chanserv/status"; }
+command { service = "ChanServ"; name = "UP"; command = "chanserv/up"; group = "chanserv/status"; }
+
+/*
+ * cs_xop
+ *
+ * Provides the command chanserv/xop.
+ * Provides the access system "XOP".
+ *
+ * Used for giving users access in channels. Many commands may be linked to chanserv/xop, but the
+ * privileges given by each is determined by the privilege:xop settings above. These commands should
+ * be ordered from highest to lowest, as each command inherits the privileges of the commands below
+ * it.
+ *
+ * The "LIST" subcommand of chanserv/xop will show only XOP access entries of the given XOP type. You
+ * can not view the entire access list at once, and instead should use another access system to do that.
+ */
+module { name = "cs_xop" }
+command { service = "ChanServ"; name = "QOP"; command = "chanserv/xop"; group = "chanserv/access"; }
+command { service = "ChanServ"; name = "SOP"; command = "chanserv/xop"; group = "chanserv/access"; }
+command { service = "ChanServ"; name = "AOP"; command = "chanserv/xop"; group = "chanserv/access"; }
+command { service = "ChanServ"; name = "HOP"; command = "chanserv/xop"; group = "chanserv/access"; }
+command { service = "ChanServ"; name = "VOP"; command = "chanserv/xop"; group = "chanserv/access"; }
+
+
+/*
+ * Extra ChanServ related modules.
+ */
+
+/*
+ * cs_statusupdate
+ *
+ * This module automatically updates users status on channels when the
+ * channel's access list is modified.
+ */
+module { name = "cs_statusupdate" }
diff --git a/roles/anope/templates/etc/anope/nickserv.conf.j2 b/roles/anope/templates/etc/anope/nickserv.conf.j2
new file mode 100644
index 0000000..931baaa
--- /dev/null
+++ b/roles/anope/templates/etc/anope/nickserv.conf.j2
@@ -0,0 +1,505 @@
+/*
+{{ ansible_managed | comment(decoration=' *  ') }}
+ */
+
+service
+{
+	nick = "{{ anope_nickserv_service_nick }}"
+	user = "{{ anope_nickserv_servie_user }}"
+	host = "{{ anope_nickserv_service_host }}"
+	gecos = "{{ anope_nickserv_service_gecos }}"
+{% if anope_nickserv_service_modes is defined %}
+	modes = "{{ anope_nickserv_service_modes }}"
+{% endif %}
+{% if anope_nickserv_service_modes is defined %}
+	channels = "{{ anope_nickserv_service_channels }}"
+{% endif %}
+}
+
+module
+{
+	name = "nickserv"
+	client = "{{ anope_nickserv_module_client }}"
+	forceemail = {{ anope_nickserv_module_forceemail | ternary('yes', 'no') }}
+	confirmemailchanges = {{ anope_nickserv_module_confirmemailchanges | ternary('yes', 'no') }}
+{% if anope_nickserv_module_unregistered_notice is defined %}
+	unregistered_notice = "{{ anope_nickserv_module_unregistered_notice }}"
+{% endif %}
+	defaults = "{{ anope_nickserv_module_defaults | join(' ') }}"
+	regdelay = {{ anope_nickserv_module_regdelay }}
+	expire = {{ anope_nickserv_module_expire }}
+	secureadmins = {{ anope_nickserv_module_secureadmins | ternary('yes', 'no') }}
+	modeonid = {{ anope_nickserv_module_modeonid | ternary('yes', 'no') }}
+{% if anope_nickserv_module_modesonid is defined %}
+	modesonid = "{{ anope_nickserv_module_modesonid }}"
+{% endif %}
+	hidenetsplitquit = {{ anope_nickserv_module_hidenetsplitquit | ternary('yes', 'no') }}
+	killquick = {{ anope_nickserv_module_killquick }}
+	kill = {{ anope_nickserv_module_kill }}
+{% if anope_nickserv_module_restrictopernicks is defined %}
+	restrictopernicks = {{ anope_nickserv_module_restrictopernicks | ternary('yes', 'no') }}
+{% endif %}
+	enforceruser = "{{ anope_nickserv_module_enforceruser }}"
+	enforcerhost = "{{ anope_nickserv_module_enforcerhost }}"
+	releasetimeout = {{ anope_nickserv_module_releasetimeout }}
+	guestnickprefix = "{{ anope_nickserv_module_guestnickprefix }}"
+	nonicknameownership = {{ anope_nickserv_module_nonicknameownership | ternary('yes', 'no') }}
+	passlen = {{ anope_nickserv_module_passlen }}
+}
+
+
+/*
+ * Core NickServ commands.
+ *
+ * In Anope modules can provide (multiple) commands, each of which has a unique command name. Once these modules
+ * are loaded you can then configure the commands to be added to any client you like with any name you like.
+ *
+ * Additionally, you may provide a permission name that must be in the opertype of users executing the command.
+ *
+ * Sane defaults are provided below that do not need to be edited unless you wish to change the default behavior.
+ */
+
+/* Command group configuration for NickServ.
+ *
+ * Commands may optionally be placed into groups to make NickServ's HELP output easier to understand.
+ * Remove the following groups to use the old behavior of simply listing all NickServ commands from HELP.
+ */
+command_group
+{
+	name = "nickserv/admin"
+	description = _("Services Operator commands")
+}
+
+/* Give it a help command. */
+command { service = "NickServ"; name = "HELP"; command = "generic/help"; }
+
+/*
+ * ns_access
+ *
+ * Provides the command nickserv/access.
+ *
+ * Used for configuring what hosts have access to your account.
+ */
+module
+{
+	name = "ns_access"
+
+	/*
+	 * The maximum number of entries allowed on a nickname's access list.
+	 * If not set, the default is 32. This number cannot be set to 0.
+	 */
+	accessmax = 32
+
+	/*
+	 * If set, Services will add the usermask of registering users to the access list of their
+	 * newly created account. If not set, users will always have to identify to NickServ before
+	 * being recognized, unless they manually add an address to the access list of their account.
+	 * This directive is optional.
+	 */
+	addaccessonreg = yes
+}
+command { service = "NickServ"; name = "ACCESS"; command = "nickserv/access"; }
+
+/*
+ * ns_ajoin
+ *
+ * Provides the command nickserv/ajoin.
+ *
+ * Used for configuring channels to join once you identify.
+ */
+module
+{
+	name = "ns_ajoin"
+
+	/*
+	 * The maximum number of channels a user can have on NickServ's AJOIN command.
+	 */
+	ajoinmax = 10
+}
+command { service = "NickServ"; name = "AJOIN"; command = "nickserv/ajoin"; }
+
+/*
+ * ns_alist
+ *
+ * Provides the command nickserv/alist.
+ *
+ * Used for viewing what channels you have access to.
+ */
+module { name = "ns_alist" }
+command { service = "NickServ"; name = "ALIST"; command = "nickserv/alist"; }
+
+/*
+ * ns_cert
+ *
+ * Provides the command nickserv/cert.
+ *
+ * Used for configuring your SSL certificate list, which can be used to automatically identify you.
+ */
+module
+{
+	name = "ns_cert"
+
+	/*
+	 * The maximum number of entries allowed on a nickname's certificate fingerprint list.
+	 * The default is 5. This number cannot be set to 0.
+	 */
+	max = 5
+}
+command { service = "NickServ"; name = "CERT"; command = "nickserv/cert"; }
+
+/*
+ * ns_drop
+ *
+ * Provides the command nickserv/drop.
+ *
+ * Used for unregistering names.
+ */
+module { name = "ns_drop" }
+command { service = "NickServ"; name = "DROP"; command = "nickserv/drop"; }
+
+/*
+ * ns_getemail
+ *
+ * Provides the command nickserv/getemail.
+ *
+ * Used for getting registered accounts by searching for emails.
+ */
+module { name = "ns_getemail" }
+command { service = "NickServ"; name = "GETEMAIL"; command = "nickserv/getemail"; permission = "nickserv/getemail"; group = "nickserv/admin"; }
+
+/*
+ * ns_getpass
+ *
+ * Provides the command nickserv/getpass.
+ *
+ * Used for getting users passwords.
+ *
+ * Requires no encryption is being used.
+ */
+#module { name = "ns_getpass" }
+#command { service = "NickServ"; name = "GETPASS"; command = "nickserv/getpass"; permission = "nickserv/getpass"; }
+
+/*
+ * ns_group
+ *
+ * Provides the commands nickserv/group, nickserv/glist, and nickserv/ungroup.
+ *
+ * Used for controlling nick groups.
+ */
+module
+{
+	name = "ns_group"
+
+	/*
+	 * The maximum number of nicks allowed in a group.
+	 *
+	 * This directive is optional, but recommended. If not set or set to 0, no limits will be applied.
+	 */
+	maxaliases = 16
+
+	/*
+	 * If set, the NickServ GROUP command won't allow any group changes. This is recommended to
+	 * prevent users from accidentally dropping their nicks, as it forces users to explicitly
+	 * drop their nicks before adding it to another group.
+	 *
+	 * This directive is optional, but recommended.
+	 */
+	nogroupchange = yes
+}
+command { service = "NickServ"; name = "GLIST"; command = "nickserv/glist"; }
+command { service = "NickServ"; name = "GROUP"; command = "nickserv/group"; }
+command { service = "NickServ"; name = "UNGROUP"; command = "nickserv/ungroup"; }
+
+/*
+ * ns_identify
+ *
+ * Provides the command nickserv/identify.
+ *
+ * Used for identifying to accounts.
+ */
+module
+{
+	name = "ns_identify"
+
+	/*
+	 * If set, limits the number of concurrent users that can be logged in as a given account at once.
+	 */
+	maxlogins = 10
+}
+command { service = "NickServ"; name = "ID"; command = "nickserv/identify"; hide = true; }
+command { service = "NickServ"; name = "IDENTIFY"; command = "nickserv/identify"; }
+
+/*
+ * ns_info
+ *
+ * Provides the commands:
+ * nickserv/info. - Used for gathering information about an account.
+ * nickserv/set/hide, nickserv/saset/hide - Used for configuring which options are publicly shown in nickserv/info.
+ *
+ */
+module { name = "ns_info" }
+command { service = "NickServ"; name = "INFO"; command = "nickserv/info"; }
+
+command { service = "NickServ"; name = "SET HIDE"; command = "nickserv/set/hide"; }
+command { service = "NickServ"; name = "SASET HIDE"; command = "nickserv/saset/hide"; permission = "nickserv/saset/hide"; }
+
+
+/*
+ * ns_list
+ *
+ * Provides the commands:
+ *   nickserv/list - Used for retrieving and searching the registered account list.
+ *   nickserv/set/private, nickserv/saset/private - Used for configuring whether or a users account shows up in nickserv/list.
+ *
+ */
+module
+{
+	name = "ns_list"
+
+	/*
+	 * The maximum number of nicks to be returned for a NickServ LIST command.
+	 */
+	listmax = 50
+}
+command { service = "NickServ"; name = "LIST"; command = "nickserv/list"; }
+
+command { service = "NickServ"; name = "SET PRIVATE"; command = "nickserv/set/private"; }
+command { service = "NickServ"; name = "SASET PRIVATE"; command = "nickserv/saset/private"; permission = "nickserv/saset/private"; }
+
+
+/*
+ * ns_logout
+ *
+ * Provides the command nickserv/logout.
+ *
+ * Used for logging out of your account.
+ */
+module { name = "ns_logout" }
+command { service = "NickServ"; name = "LOGOUT"; command = "nickserv/logout"; }
+
+/*
+ * ns_recover
+ *
+ * Provides the command nickserv/recover.
+ *
+ * Used for recovering your nick from services or another user.
+ */
+module
+{
+	name = "ns_recover"
+
+	/*
+	 * If set, Services will svsnick and svsjoin users who use the recover
+	 * command on an identified user to the nick and channels of the recovered user.
+	 *
+	 * This directive is opional.
+	 */
+	restoreonrecover = yes
+}
+command { service = "NickServ"; name = "RECOVER"; command = "nickserv/recover"; }
+# Uncomment below to emulate 1.8's behavior of ghost and release.
+#command { service = "NickServ"; name = "GHOST"; command = "nickserv/recover"; }
+#command { service = "NickServ"; name = "RELEASE"; command = "nickserv/recover"; }
+
+/*
+ * ns_register
+ *
+ * Provides the commands nickserv/confirm, nickserv/register, and nickserv/resend.
+ *
+ * Used for registering accounts.
+ */
+module
+{
+	name = "ns_register"
+
+	/*
+	 * Registration confirmation setting. Set to "none" for no registration confirmation,
+	 * "mail" for email confirmation, and "admin" to have services operators manually confirm
+	 * every registration. Set to "disable" to completely disable all registrations.
+	 */
+	registration = "none"
+
+	/*
+	 * The minimum length of time between consecutive uses of NickServ's RESEND command.
+	 *
+	 * This directive is optional, but recommended. If not set, this restriction will be disabled.
+	 */
+	resenddelay = 90s
+
+	/*
+	 * Prevents users from registering their nick if they are not connected
+	 * for at least the given number of seconds.
+	 *
+	 * This directive is optional.
+	 */
+	#nickregdelay = 30s
+
+	/*
+	 * The length of time a user using an unconfirmed account has
+	 * before the account will be released for general use again.
+	 */
+	#unconfirmedexpire = 1d
+}
+command { service = "NickServ"; name = "CONFIRM"; command = "nickserv/confirm"; }
+command { service = "NickServ"; name = "REGISTER"; command = "nickserv/register"; }
+command { service = "NickServ"; name = "RESEND"; command = "nickserv/resend"; }
+
+/*
+ * ns_resetpass
+ *
+ * Provides the command nickserv/resetpass.
+ *
+ * Used for resetting passwords by emailing users a temporary one.
+ */
+module { name = "ns_resetpass" }
+command { service = "NickServ"; name = "RESETPASS"; command = "nickserv/resetpass"; }
+
+/*
+ * ns_set
+ *
+ * Provides the commands:
+ *   nickserv/set, nickserv/saset - Dummy help wrappers for the SET and SASET commands.
+ *   nickserv/set/autoop, nickserv/saset/autoop - Determines whether or not modes are automatically set users when joining a channel.
+ *   nickserv/set/display, nickserv/saset/display - Used for setting a users display name.
+ *   nickserv/set/email, nickserv/saset/email - Used for setting a users email address.
+ *   nickserv/set/keepmodes, nickserv/saset/keepmodes - Configure whether or not services should retain a user's modes across sessions.
+ *   nickserv/set/kill, nickserv/saset/kill - Used for configuring nickname protection.
+ *   nickserv/set/language, nickserv/saset/language - Used for configuring what language services use.
+ *   nickserv/set/message, nickserv/saset/message - Used to configure how services send messages to you.
+ *   nickserv/set/password, nickserv/saset/password  - Used for changing a users password.
+ *   nickserv/set/secure, nickserv/saset/secure - Used for configuring whether a user can identify by simply being recognized by nickserv/access.
+ *   nickserv/saset/noexpire - Used for configuring noexpire, which prevents nicks from expiring.
+ */
+module
+{
+	name = "ns_set"
+
+	/*
+	 * Allow the use of the IMMED option in the NickServ SET KILL command.
+	 *
+	 * This directive is optional.
+	 */
+	#allowkillimmed = yes
+}
+
+command { service = "NickServ"; name = "SET"; command = "nickserv/set"; }
+command { service = "NickServ"; name = "SASET"; command = "nickserv/saset"; permission = "nickserv/saset/"; group = "nickserv/admin"; }
+
+command { service = "NickServ"; name = "SET AUTOOP"; command = "nickserv/set/autoop"; }
+command { service = "NickServ"; name = "SASET AUTOOP"; command = "nickserv/saset/autoop"; permission = "nickserv/saset/autoop"; }
+
+command { service = "NickServ"; name = "SET DISPLAY"; command = "nickserv/set/display"; }
+command { service = "NickServ"; name = "SASET DISPLAY"; command = "nickserv/saset/display"; permission = "nickserv/saset/display"; }
+
+command { service = "NickServ"; name = "SET EMAIL"; command = "nickserv/set/email"; }
+command { service = "NickServ"; name = "SASET EMAIL"; command = "nickserv/saset/email"; permission = "nickserv/saset/email"; }
+
+command { service = "NickServ"; name = "SET KEEPMODES"; command = "nickserv/set/keepmodes"; }
+command { service = "NickServ"; name = "SASET KEEPMODES"; command = "nickserv/saset/keepmodes"; permission = "nickserv/saset/keepmodes"; }
+
+command { service = "NickServ"; name = "SET KILL"; command = "nickserv/set/kill"; }
+command { service = "NickServ"; name = "SASET KILL"; command = "nickserv/saset/kill"; permission = "nickserv/saset/kill"; }
+
+command { service = "NickServ"; name = "SET LANGUAGE"; command = "nickserv/set/language"; }
+command { service = "NickServ"; name = "SASET LANGUAGE"; command = "nickserv/saset/language"; permission = "nickserv/saset/language"; }
+
+command { service = "NickServ"; name = "SET MESSAGE"; command = "nickserv/set/message"; }
+command { service = "NickServ"; name = "SASET MESSAGE"; command = "nickserv/saset/message"; permission = "nickserv/saset/message"; }
+
+command { service = "NickServ"; name = "SET PASSWORD"; command = "nickserv/set/password"; }
+command { service = "NickServ"; name = "SASET PASSWORD"; command = "nickserv/saset/password"; permission = "nickserv/saset/password"; }
+
+command { service = "NickServ"; name = "SET SECURE"; command = "nickserv/set/secure"; }
+command { service = "NickServ"; name = "SASET SECURE"; command = "nickserv/saset/secure"; permission = "nickserv/saset/secure"; }
+
+command { service = "NickServ"; name = "SASET NOEXPIRE"; command = "nickserv/saset/noexpire"; permission = "nickserv/saset/noexpire"; }
+
+
+/*
+ * ns_set_misc
+ *
+ * Provides the command nickserv/set/misc.
+ *
+ * Allows you to create arbitrary commands to set data, and have that data show up in nickserv/info.
+ * A field named misc_description may be given for use with help output.
+ */
+module { name = "ns_set_misc" }
+command { service = "NickServ"; name = "SET URL"; command = "nickserv/set/misc"; misc_description = _("Associate a URL with your account"); }
+command { service = "NickServ"; name = "SASET URL"; command = "nickserv/saset/misc"; misc_description = _("Associate a URL with this account"); permission = "nickserv/saset/url"; group = "nickserv/admin"; }
+#command { service = "NickServ"; name = "SET ICQ"; command = "nickserv/set/misc"; misc_description = _("Associate an ICQ account with your account"); }
+#command { service = "NickServ"; name = "SASET ICQ"; command = "nickserv/saset/misc"; misc_description = _("Associate an ICQ account with this account"); permission = "nickserv/saset/icq"; group = "nickserv/admin"; }
+#command { service = "NickServ"; name = "SET TWITTER"; command = "nickserv/set/misc"; misc_description = _("Associate a Twitter account with your account"); }
+#command { service = "NickServ"; name = "SASET TWITTER"; command = "nickserv/saset/misc"; misc_description = _("Associate a Twitter account with this account"); permission = "nickserv/saset/twitter"; group = "nickserv/admin"; }
+#command { service = "NickServ"; name = "SET FACEBOOK"; command = "nickserv/set/misc"; misc_description = _("Associate a Facebook URL with your account"); }
+#command { service = "NickServ"; name = "SASET FACEBOOK"; command = "nickserv/saset/misc"; misc_description = _("Associate a Facebook URL with this account"); permission = "nickserv/saset/facebook"; group = "nickserv/admin"; }
+
+/*
+ * ns_status
+ *
+ * Provides the nickserv/status command.
+ *
+ * Used to determine if a user is recognized or identified by services.
+ */
+module { name = "ns_status" }
+command { service = "NickServ"; name = "STATUS"; command = "nickserv/status"; }
+
+/*
+ * ns_suspend
+ *
+ * Provides the commands nickserv/suspend and nickserv/unsuspend.
+ *
+ * Used to suspend and unsuspend nicknames. Suspended nicknames can not be used but their settings are preserved.
+ */
+module
+{
+	name = "ns_suspend"
+
+	/*
+	 * The length of time before a suspended nick becomes unsuspended.
+	 *
+	 * This directive is optional. If not set, the default is never.
+	 */
+	#suspendexpire = 90d
+
+	/*
+	 * Settings to show to non-opers in NickServ's INFO output.
+	 * Comment to completely disable showing any information about
+	 * suspended nicknames to non-opers.
+	 */
+	show = "suspended, by, reason, on, expires"
+}
+command { service = "NickServ"; name = "SUSPEND"; command = "nickserv/suspend"; permission = "nickserv/suspend"; group = "nickserv/admin"; }
+command { service = "NickServ"; name = "UNSUSPEND"; command = "nickserv/unsuspend"; permission = "nickserv/suspend"; group = "nickserv/admin"; }
+
+/*
+ * ns_update
+ *
+ * Provides the command nickserv/update.
+ *
+ * Used to update your status on all channels, turn on your vHost, etc.
+ */
+module { name = "ns_update" }
+command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
+
+
+/*
+ * Extra NickServ related modules.
+ */
+
+/*
+ * ns_maxemail
+ *
+ * Limits how many times the same email address may be used in Anope
+ * to register accounts.
+ */
+#module
+{
+	name = "ns_maxemail"
+
+	/*
+	 * The limit to how many registered nicks can use the same e-mail address. If set to 0 or left
+	 * commented, there will be no limit enforced when registering new accounts or using
+	 * /msg NickServ SET EMAIL.
+	 */
+	maxemails = 1
+}