<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.d3xt3r01.tk//index.php?action=history&amp;feed=atom&amp;title=Mod_lua_custom_auth</id>
	<title>Mod lua custom auth - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.d3xt3r01.tk//index.php?action=history&amp;feed=atom&amp;title=Mod_lua_custom_auth"/>
	<link rel="alternate" type="text/html" href="https://wiki.d3xt3r01.tk//index.php?title=Mod_lua_custom_auth&amp;action=history"/>
	<updated>2026-05-05T14:31:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.d3xt3r01.tk//index.php?title=Mod_lua_custom_auth&amp;diff=6617&amp;oldid=prev</id>
		<title>Admin: /* HOW */</title>
		<link rel="alternate" type="text/html" href="https://wiki.d3xt3r01.tk//index.php?title=Mod_lua_custom_auth&amp;diff=6617&amp;oldid=prev"/>
		<updated>2014-02-07T12:36:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;HOW&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 15:36, 7 February 2014&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l235&quot;&gt;Line 235:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 235:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Place the &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[&lt;/del&gt;[http://regex.info/code/JSON.lua&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]&lt;/del&gt;] in the same directory.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Place the [http://regex.info/code/JSON.lua &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;JSON.lua&lt;/ins&gt;] in the same directory.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;My mod_lua.conf&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;My mod_lua.conf&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.d3xt3r01.tk//index.php?title=Mod_lua_custom_auth&amp;diff=6616&amp;oldid=prev</id>
		<title>Admin: Created page with &quot;==WHY==  Because BasicAuth seemed a bad way to do stuff. With multiple .htaccess files all over the place... I wanted to be able to expire users. To mail them when they&#039;re not...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.d3xt3r01.tk//index.php?title=Mod_lua_custom_auth&amp;diff=6616&amp;oldid=prev"/>
		<updated>2014-02-07T12:34:12Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==WHY==  Because BasicAuth seemed a bad way to do stuff. With multiple .htaccess files all over the place... I wanted to be able to expire users. To mail them when they&amp;#039;re not...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==WHY==&lt;br /&gt;
&lt;br /&gt;
Because BasicAuth seemed a bad way to do stuff. With multiple .htaccess files all over the place...&lt;br /&gt;
I wanted to be able to expire users. To mail them when they&amp;#039;re not active .. etc.&lt;br /&gt;
You need to have at least 2.4.7&lt;br /&gt;
&lt;br /&gt;
==HOW==&lt;br /&gt;
&lt;br /&gt;
My /etc/apache2/lua_scripts/authcheck_hook.lua&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
require &amp;#039;apache2&amp;#039;&lt;br /&gt;
JSON = require &amp;quot;JSON&amp;quot;&lt;br /&gt;
&lt;br /&gt;
processhostnames = { &amp;#039;192.168.1.95&amp;#039;, &amp;#039;d3xbucharest.go.ro&amp;#039;, &amp;#039;d3xt3r01.tk&amp;#039; }&lt;br /&gt;
&lt;br /&gt;
function ivmsqlarrayset(r)&lt;br /&gt;
        local db, err = r:dbacquire(&amp;quot;mod_dbd&amp;quot;)&lt;br /&gt;
        if not db then&lt;br /&gt;
                r:info(&amp;quot;ivmsqlarrayset(): [500] DB Error: &amp;quot; .. err)&lt;br /&gt;
                return 500&lt;br /&gt;
        end&lt;br /&gt;
        local cdirgroup = {}&lt;br /&gt;
        local dirs, err = db:select(r, &amp;quot;SELECT * FROM `groupdirs` ORDER BY LENGTH(`dir`) DESC&amp;quot;)&lt;br /&gt;
        if not err then&lt;br /&gt;
                local rows = dirs(0)&lt;br /&gt;
                for k, row in pairs(rows) do&lt;br /&gt;
                        if row[3] == &amp;quot;&amp;quot; then&lt;br /&gt;
                                row[3] = &amp;quot; &amp;quot;&lt;br /&gt;
                        end&lt;br /&gt;
                        table.insert(cdirgroup, row[2] .. &amp;quot;:&amp;quot; .. row[3] .. &amp;quot;:&amp;quot; .. row[4])&lt;br /&gt;
                end&lt;br /&gt;
        else&lt;br /&gt;
                r:info(&amp;quot;ivmsqlarrayset(): Could not connect to the database: &amp;quot; .. err)&lt;br /&gt;
        end&lt;br /&gt;
        r:ivm_set(&amp;quot;cdirgroup&amp;quot;, JSON:encode(cdirgroup))&lt;br /&gt;
        db:close()&lt;br /&gt;
        return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function explode(d,p)&lt;br /&gt;
        local t, ll&lt;br /&gt;
        t={}&lt;br /&gt;
        ll=0&lt;br /&gt;
        if(#p == 1) then return {p} end&lt;br /&gt;
        while true do&lt;br /&gt;
                l=string.find(p,d,ll,true)&lt;br /&gt;
                if l ~= nil then&lt;br /&gt;
                        table.insert(t, string.sub(p,ll,l-1))&lt;br /&gt;
                        ll=l+1&lt;br /&gt;
                else&lt;br /&gt;
                        table.insert(t, string.sub(p,ll))&lt;br /&gt;
                        break&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ugallow(r, usergroup, cdirgroup)&lt;br /&gt;
        r:info(&amp;quot;ugallow(): usergroup: &amp;quot; .. usergroup)&lt;br /&gt;
        for key,value in pairs(cdirgroup) do&lt;br /&gt;
                local dir, group, skip = value:match(&amp;quot;^([^:]+):([^:]+):([^:]+)$&amp;quot;)&lt;br /&gt;
                if r.uri:match(&amp;quot;^&amp;quot; .. dir .. &amp;quot;?&amp;quot;) then&lt;br /&gt;
                        dirgroups = group&lt;br /&gt;
                        r:info(&amp;quot;ugallow(): dirgroups: &amp;#039;&amp;quot; .. group .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
                        break&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        local authpass = nil&lt;br /&gt;
        if dirgroups ~= &amp;quot; &amp;quot; then&lt;br /&gt;
                local usergroups = explode(&amp;quot; &amp;quot;, usergroup)&lt;br /&gt;
                dirgroups = explode(&amp;quot; &amp;quot;, dirgroups)&lt;br /&gt;
                if usergroups then&lt;br /&gt;
                        for k, row in pairs(dirgroups) do&lt;br /&gt;
                                for j, row2 in pairs(usergroups) do&lt;br /&gt;
                                        if row == row2 then&lt;br /&gt;
                                                authpass = true&lt;br /&gt;
                                        end&lt;br /&gt;
                                end&lt;br /&gt;
                        end&lt;br /&gt;
                else   &lt;br /&gt;
                        authpass = true&lt;br /&gt;
                end&lt;br /&gt;
        else&lt;br /&gt;
                authpass = true&lt;br /&gt;
        end&lt;br /&gt;
        if authpass then&lt;br /&gt;
                r:info(&amp;quot;ugallow(): return true&amp;quot;)&lt;br /&gt;
                return true&lt;br /&gt;
        else&lt;br /&gt;
                r:info(&amp;quot;ugallow(): return nil&amp;quot;)&lt;br /&gt;
                return nil&lt;br /&gt;
        end&lt;br /&gt;
end&lt;br /&gt;
function authcheck_hook(r)&lt;br /&gt;
        if r.uri == &amp;quot;/favicon.ico&amp;quot; then return apache2.DECLINED end&lt;br /&gt;
        for key,value in pairs(processhostnames) do&lt;br /&gt;
                if r.hostname == value then&lt;br /&gt;
                        process = true&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        if not process then&lt;br /&gt;
                return apache2.DECLINED&lt;br /&gt;
        end&lt;br /&gt;
        r:info(&amp;quot;authcheck_hook(): ----------------&amp;quot;)&lt;br /&gt;
        local okay = false&lt;br /&gt;
        r:info(&amp;quot;authcheck_hook(): running auth for &amp;quot; .. r.uri)&lt;br /&gt;
        local cdir = r:ivm_get(&amp;quot;cdirgroup&amp;quot;)&lt;br /&gt;
        if not cdir then&lt;br /&gt;
                ivmsqlarrayset(r)&lt;br /&gt;
        end&lt;br /&gt;
        local expcdir = r:ivm_get(&amp;quot;expcdir&amp;quot;)&lt;br /&gt;
        if not expcdir then&lt;br /&gt;
                r:ivm_set(&amp;quot;expcdir&amp;quot;, os.time())&lt;br /&gt;
                expcdir = os.time()&lt;br /&gt;
        else&lt;br /&gt;
                local cdirexpcheck = os.time() - expcdir&lt;br /&gt;
                if cdirexpcheck &amp;gt; 60 then&lt;br /&gt;
                        ivmsqlarrayset(r)&lt;br /&gt;
                        r:ivm_set(&amp;quot;expcdir&amp;quot;, os.time())&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        local cdirgroup = JSON:decode(r:ivm_get(&amp;quot;cdirgroup&amp;quot;))&lt;br /&gt;
        local directives = &amp;quot;no&amp;quot;&lt;br /&gt;
        for key,value in pairs(cdirgroup) do&lt;br /&gt;
                local dir, group, skip = value:match(&amp;quot;^([^:]+):([^:]+):([^:]+)$&amp;quot;)&lt;br /&gt;
                if r.uri:match(&amp;quot;^&amp;quot; .. dir .. &amp;quot;?&amp;quot;) then&lt;br /&gt;
                        if skip == &amp;quot;true&amp;quot; then&lt;br /&gt;
                                r:info(&amp;quot;authcheck_hook(): apache2.DECLINED because skip : &amp;quot; .. dir)&lt;br /&gt;
                                return apache2.DECLINED&lt;br /&gt;
                        end&lt;br /&gt;
                        r:info(&amp;quot;authcheck_hook(): Matched a policy .. will process...&amp;quot;)&lt;br /&gt;
                        directives = &amp;quot;yes&amp;quot;&lt;br /&gt;
                        dirgroups = group&lt;br /&gt;
                        break&lt;br /&gt;
                end&lt;br /&gt;
        end&lt;br /&gt;
        if directives == &amp;quot;no&amp;quot; then return apache2.DECLINED end&lt;br /&gt;
        r:info(&amp;quot;authcheck_hook(): PROCESSING REQUEST !!!&amp;quot;)&lt;br /&gt;
        local db, err = r:dbacquire(&amp;quot;mod_dbd&amp;quot;)&lt;br /&gt;
        if not db then &lt;br /&gt;
                r:info(&amp;quot;authcheck_hook(): [500] DB Error: &amp;quot; .. err)&lt;br /&gt;
                return 500&lt;br /&gt;
        end&lt;br /&gt;
        local str = (r.headers_in[&amp;#039;Authorization&amp;#039;] or &amp;quot;&amp;quot;):match(&amp;quot;^Basic (.+)$&amp;quot;)&lt;br /&gt;
        local decoded = r:base64_decode(str or &amp;quot;&amp;quot;)&lt;br /&gt;
        local usr, pass = decoded:match(&amp;quot;^([^:]+):([^:]+)$&amp;quot;)&lt;br /&gt;
        r:info((&amp;quot;authcheck_hook(): Checking against user %s and password %s ...&amp;quot;):format(usr or &amp;quot;nil&amp;quot;, pass or &amp;quot;nil&amp;quot;))&lt;br /&gt;
        if usr == nil or pass == nil then&lt;br /&gt;
                r:info(&amp;quot;authcheck_hook(): user or pass is nil, returning 401&amp;quot;)&lt;br /&gt;
                r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                db:close()&lt;br /&gt;
                return 401&lt;br /&gt;
        else&lt;br /&gt;
                pass = r:sha1(pass)&lt;br /&gt;
                r:info(&amp;quot;authcheck_hook(): User &amp;amp; password not nil .. checking cache&amp;quot;)&lt;br /&gt;
                local cached_and_okay = false&lt;br /&gt;
                local cached_entry = r:ivm_get(&amp;quot;auth_cache:&amp;quot; .. usr)&lt;br /&gt;
                if cached_entry then&lt;br /&gt;
                        local expiry, password, usergroup = cached_entry:match(&amp;quot;^(%d+):([^:]+):([^:]+)$&amp;quot;)&lt;br /&gt;
                        expiry = tonumber(expiry)&lt;br /&gt;
                        local expcheck = os.time() - expiry&lt;br /&gt;
                        r:info(&amp;quot;authcheck_hook(): &amp;quot; .. usr .. &amp;quot; found in cache .. &amp;quot; .. expcheck .. &amp;quot; expiry in &amp;quot;.. (300 - expcheck))&lt;br /&gt;
                        if expcheck &amp;lt; 300 then&lt;br /&gt;
                                cached_and_okay = true&lt;br /&gt;
                                r:info(&amp;quot;authcheck_hook(): Comparing &amp;#039;&amp;quot; .. password .. &amp;quot;&amp;#039; with &amp;#039;&amp;quot; .. pass .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
                                local authpass = ugallow(r, usergroup, cdirgroup)&lt;br /&gt;
                                if not authpass then&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): Group match failed... throwing: 401&amp;quot;)&lt;br /&gt;
                                        db:close()&lt;br /&gt;
                                        r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                                        return 401&lt;br /&gt;
                                end&lt;br /&gt;
                                if password == pass then&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): apache2.OK&amp;quot;)&lt;br /&gt;
                                        r.user = usr&lt;br /&gt;
                                        db:close()&lt;br /&gt;
                                        return apache2.OK&lt;br /&gt;
                                end&lt;br /&gt;
                        end&lt;br /&gt;
                end&lt;br /&gt;
                if not cached_and_okay then&lt;br /&gt;
                        r:info(&amp;quot;authcheck_hook(): &amp;quot; .. usr .. &amp;quot; not cached .. searching ..&amp;quot;)&lt;br /&gt;
                        local prep = db:prepare(r, &amp;quot;SELECT `id`, `expiry`, `groups` FROM `auth` WHERE `user` = %s AND `password` = %s AND `enabled` = &amp;#039;1&amp;#039; AND (`expiry` = &amp;#039;0000-00-00 00:00:00&amp;#039; OR `expiry` &amp;gt; NOW()) LIMIT 1&amp;quot;)&lt;br /&gt;
                        local result = prep:select(usr, pass)&lt;br /&gt;
                        if result then&lt;br /&gt;
                                r:info(&amp;quot;authcheck_hook(): Did the query&amp;quot;)&lt;br /&gt;
                                local rows = result(0)&lt;br /&gt;
                                if #rows == 1 then&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): We got results...&amp;quot;)&lt;br /&gt;
                                        okay = true&lt;br /&gt;
                                        local row = rows[1]&lt;br /&gt;
                                        local id = row[1]&lt;br /&gt;
                                        local expiry = row[2]&lt;br /&gt;
                                        usergroup = row[3]&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): One row ... id: &amp;quot; .. id .. &amp;quot; expiry: &amp;quot; .. expiry)&lt;br /&gt;
                                        if expiry ~= &amp;#039;0000-00-00 00:00:00&amp;#039; then&lt;br /&gt;
                                                local prep = db:prepare(r, &amp;quot;UPDATE `auth` SET `expiry` = NOW()+INTERVAL 1 MONTH, `last_accessed` = NOW(), `mailed` = &amp;#039;0&amp;#039;  WHERE `id` = %s LIMIT 1&amp;quot;)&lt;br /&gt;
                                                prep:query(id)&lt;br /&gt;
                                        end&lt;br /&gt;
                                        local authpass = ugallow(r, usergroup, cdirgroup)&lt;br /&gt;
                                        if not authpass then&lt;br /&gt;
                                                r:info(&amp;quot;authcheck_hook(): Group match failed... throwing: 401&amp;quot;)&lt;br /&gt;
                                                db:close()&lt;br /&gt;
                                                r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                                                return 401&lt;br /&gt;
                                        end&lt;br /&gt;
                                else&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): Received sha1pass: &amp;quot; .. pass)&lt;br /&gt;
                                        r:info(&amp;quot;authcheck_hook(): Wrong username and/or password ... throwing: 401&amp;quot;)&lt;br /&gt;
                                        db:close()&lt;br /&gt;
                                        r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                                        return 401&lt;br /&gt;
                                end&lt;br /&gt;
                                r:ivm_set(&amp;quot;auth_cache:&amp;quot; .. usr, os.time() .. &amp;quot;:&amp;quot; .. pass .. &amp;quot;:&amp;quot; .. usergroup)&lt;br /&gt;
                        else&lt;br /&gt;
                                r:info(&amp;quot;authcheck_hook(): No results .. 401 again&amp;quot;)&lt;br /&gt;
                                r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                                db:close()&lt;br /&gt;
                                return 401&lt;br /&gt;
                        end&lt;br /&gt;
                  end  &lt;br /&gt;
        end&lt;br /&gt;
        if not okay then&lt;br /&gt;
                r:info(&amp;quot;authcheck_hook(): Wrong username or password .. throwing: 401&amp;quot;)&lt;br /&gt;
                r.err_headers_out[&amp;#039;WWW-Authenticate&amp;#039;] = &amp;#039;Basic realm=&amp;quot;Restricted Files&amp;quot;&amp;#039;&lt;br /&gt;
                db:close()&lt;br /&gt;
                return 401&lt;br /&gt;
        end&lt;br /&gt;
&lt;br /&gt;
        r:info(&amp;quot;authcheck_hook(): apache2.OK&amp;quot;)&lt;br /&gt;
        r.user = usr   &lt;br /&gt;
        db:close()&lt;br /&gt;
        return apache2.OK&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Place the [[http://regex.info/code/JSON.lua]] in the same directory.&lt;br /&gt;
&lt;br /&gt;
My mod_lua.conf&lt;br /&gt;
&amp;lt;source lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
DBDParams host=localhost,dbname=apache,user=apacheupdate,pass=P4ssw0rd&lt;br /&gt;
DBDriver mysql&lt;br /&gt;
DBDMax 20&lt;br /&gt;
LoadModule lua_module         modules/mod_lua.so&lt;br /&gt;
AddHandler lua-script .lua&lt;br /&gt;
#LogLevel mod_lua.c:info&lt;br /&gt;
LuaScope thread&lt;br /&gt;
LuaCodeCache stat&lt;br /&gt;
LuaRoot /etc/apache2/lua_scripts/&lt;br /&gt;
LuaHookAccessChecker authcheck_hook.lua authcheck_hook&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `auth` (&lt;br /&gt;
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `user` varchar(32) NOT NULL,&lt;br /&gt;
  `password` varchar(64) NOT NULL,&lt;br /&gt;
  `email` varchar(64) NOT NULL,&lt;br /&gt;
  `groups` varchar(128) NOT NULL,&lt;br /&gt;
  `enabled` tinyint(1) DEFAULT &amp;#039;1&amp;#039;,&lt;br /&gt;
  `expiry` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,&lt;br /&gt;
  `last_accessed` timestamp NULL DEFAULT NULL,&lt;br /&gt;
  `mailed` tinyint(1) NOT NULL DEFAULT &amp;#039;0&amp;#039;,&lt;br /&gt;
  `comment` tinytext NOT NULL,&lt;br /&gt;
  PRIMARY KEY (`id`)&lt;br /&gt;
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=66 ;&lt;br /&gt;
CREATE TABLE IF NOT EXISTS `groupdirs` (&lt;br /&gt;
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,&lt;br /&gt;
  `dir` varchar(128) NOT NULL,&lt;br /&gt;
  `groups` varchar(128) NOT NULL,&lt;br /&gt;
  `skip` enum(&amp;#039;true&amp;#039;,&amp;#039;false&amp;#039;) NOT NULL DEFAULT &amp;#039;false&amp;#039;,&lt;br /&gt;
  PRIMARY KEY (`id`)&lt;br /&gt;
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>