1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
18
-module(mod_auth_dets).
20
%% dets authentication storage
29
delete_group_member/3,
33
-export([store_directory_data/2]).
35
-include("httpd.hrl").
36
-include("mod_auth.hrl").
38
store_directory_data(_Directory, DirData) ->
39
?CDEBUG("store_directory_data -> ~n"
42
[_Directory, DirData]),
44
PWFile = httpd_util:key1search(DirData, auth_user_file),
45
GroupFile = httpd_util:key1search(DirData, auth_group_file),
46
Addr = httpd_util:key1search(DirData, bind_address),
47
Port = httpd_util:key1search(DirData, port),
49
PWName = httpd_util:make_name("httpd_dets_pwdb",Addr,Port),
50
case dets:open_file(PWName,[{type,set},{file,PWFile},{repair,true}]) of
52
GDBName = httpd_util:make_name("httpd_dets_groupdb",Addr,Port),
53
case dets:open_file(GDBName,[{type,set},{file,GroupFile},{repair,true}]) of
55
NDD1 = lists:keyreplace(auth_user_file, 1, DirData,
56
{auth_user_file, PWDB}),
57
NDD2 = lists:keyreplace(auth_group_file, 1, NDD1,
58
{auth_group_file, GDB}),
61
{error, {{file, GroupFile},Err}}
64
{error, {{file, PWFile},Err2}}
68
%% Storage format of users in the dets table:
69
%% {{UserName, Addr, Port, Dir}, Password, UserData}
72
add_user(DirData, UStruct) ->
73
{Addr, Port, Dir} = lookup_common(DirData),
74
PWDB = httpd_util:key1search(DirData, auth_user_file),
75
Record = {{UStruct#httpd_user.username, Addr, Port, Dir},
76
UStruct#httpd_user.password, UStruct#httpd_user.user_data},
77
case dets:lookup(PWDB, UStruct#httpd_user.username) of
79
{error, user_already_in_db};
81
dets:insert(PWDB, Record),
85
get_user(DirData, UserName) ->
86
{Addr, Port, Dir} = lookup_common(DirData),
87
PWDB = httpd_util:key1search(DirData, auth_user_file),
88
User = {UserName, Addr, Port, Dir},
89
case dets:lookup(PWDB, User) of
90
[{User, Password, UserData}] ->
91
{ok, #httpd_user{username=UserName, password=Password, user_data=UserData}};
96
list_users(DirData) ->
97
?DEBUG("list_users -> ~n"
98
" DirData: ~p", [DirData]),
99
{Addr, Port, Dir} = lookup_common(DirData),
100
PWDB = httpd_util:key1search(DirData, auth_user_file),
101
case dets:traverse(PWDB, fun(X) -> {continue, X} end) of %% SOOOO Ugly !
102
Records when list(Records) ->
103
?DEBUG("list_users -> ~n"
104
" Records: ~p", [Records]),
105
{ok, [UserName || {{UserName, AnyAddr, AnyPort, AnyDir},
106
_Password, _Data} <- Records,
107
AnyAddr == Addr, AnyPort == Port,
110
?DEBUG("list_users -> ~n"
115
delete_user(DirData, UserName) ->
116
{Addr, Port, Dir} = lookup_common(DirData),
117
PWDB = httpd_util:key1search(DirData, auth_user_file),
118
User = {UserName, Addr, Port, Dir},
119
case dets:lookup(PWDB, User) of
120
[{User, _SomePassword, _UserData}] ->
121
dets:delete(PWDB, User),
122
{ok, Groups} = list_groups(DirData),
123
lists:foreach(fun(Group) ->
124
delete_group_member(DirData,
125
Group, UserName) end,
129
{error, no_such_user}
133
%% Storage of groups in the dets table:
134
%% {Group, UserList} where UserList is a list of strings.
136
add_group_member(DirData, GroupName, UserName) ->
137
{Addr, Port, Dir} = lookup_common(DirData),
138
GDB = httpd_util:key1search(DirData, auth_group_file),
139
Group = {GroupName, Addr, Port, Dir},
140
case dets:lookup(GDB, Group) of
142
case lists:member(UserName, Users) of
146
dets:insert(GDB, {Group, [UserName|Users]}),
150
dets:insert(GDB, {Group, [UserName]}),
156
list_group_members(DirData, GroupName) ->
157
{Addr, Port, Dir} = lookup_common(DirData),
158
GDB = httpd_util:key1search(DirData, auth_group_file),
159
Group = {GroupName, Addr, Port, Dir},
160
case dets:lookup(GDB, Group) of
164
{error, no_such_group}
167
list_groups(DirData) ->
168
{Addr, Port, Dir} = lookup_common(DirData),
169
GDB = httpd_util:key1search(DirData, auth_group_file),
170
case dets:match(GDB, {'$1', '_'}) of
173
List when list(List) ->
174
Groups = lists:flatten(List),
176
{GroupName, AnyAddr, AnyPort, AnyDir} <- Groups,
177
AnyAddr == Addr, AnyPort == Port, AnyDir == Dir]};
182
delete_group_member(DirData, GroupName, UserName) ->
183
{Addr, Port, Dir} = lookup_common(DirData),
184
GDB = httpd_util:key1search(DirData, auth_group_file),
185
Group = {GroupName, Addr, Port, Dir},
186
case dets:lookup(GDB, GroupName) of
188
case lists:member(UserName, Users) of
190
dets:delete(GDB, Group),
191
dets:insert(GDB, {Group,
192
lists:delete(UserName, Users)}),
195
{error, no_such_group_member}
198
{error, no_such_group}
201
delete_group(DirData, GroupName) ->
202
{Addr, Port, Dir} = lookup_common(DirData),
203
GDB = httpd_util:key1search(DirData, auth_group_file),
204
Group = {GroupName, Addr, Port, Dir},
205
case dets:lookup(GDB, Group) of
207
dets:delete(GDB, Group),
210
{error, no_such_group}
213
lookup_common(DirData) ->
214
Dir = httpd_util:key1search(DirData, path),
215
Port = httpd_util:key1search(DirData, port),
216
Addr = httpd_util:key1search(DirData, bind_address),
221
%% Closes dets tables used by this auth mod.
224
PWDB = httpd_util:key1search(DirData, auth_user_file),
225
GDB = httpd_util:key1search(DirData, auth_group_file),