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_plain).
20
-include("httpd.hrl").
21
-include("mod_auth.hrl").
23
-define(VMODULE,"AUTH_PLAIN").
26
-export([store_directory_data/2]).
36
delete_group_member/3,
45
%% Storage format of users in the ets table:
46
%% {UserName, Password, UserData}
49
add_user(DirData, #httpd_user{username = User} = UStruct) ->
50
PWDB = httpd_util:key1search(DirData, auth_user_file),
52
UStruct#httpd_user.password,
53
UStruct#httpd_user.user_data},
54
case ets:lookup(PWDB, User) of
55
[{User, _SomePassword, _SomeData}] ->
56
{error, user_already_in_db};
58
ets:insert(PWDB, Record),
62
get_user(DirData, User) ->
63
PWDB = httpd_util:key1search(DirData, auth_user_file),
64
case ets:lookup(PWDB, User) of
65
[{User, PassWd, Data}] ->
66
{ok, #httpd_user{username=User, password=PassWd, user_data=Data}};
71
list_users(DirData) ->
72
PWDB = httpd_util:key1search(DirData, auth_user_file),
73
Records = ets:match(PWDB, '$1'),
74
{ok, lists:foldr(fun({User, _PassWd, _Data}, A) -> [User | A] end,
75
[], lists:flatten(Records))}.
77
delete_user(DirData, UserName) ->
78
PWDB = httpd_util:key1search(DirData, auth_user_file),
79
case ets:lookup(PWDB, UserName) of
80
[{UserName, _SomePassword, _SomeData}] ->
81
ets:delete(PWDB, UserName),
82
{ok, Groups} = list_groups(DirData),
83
lists:foreach(fun(Group) ->
84
delete_group_member(DirData,
92
%% Storage of groups in the ets table:
93
%% {Group, UserList} where UserList is a list of strings.
96
add_group_member(DirData, Group, UserName) ->
97
GDB = httpd_util:key1search(DirData, auth_group_file),
98
case ets:lookup(GDB, Group) of
100
case lists:member(UserName, Users) of
104
ets:insert(GDB, {Group, [UserName|Users]}),
108
ets:insert(GDB, {Group, [UserName]}),
114
list_group_members(DirData, Group) ->
115
GDB = httpd_util:key1search(DirData, auth_group_file),
116
case ets:lookup(GDB, Group) of
120
{error, no_such_group}
123
list_groups(DirData) ->
124
GDB = httpd_util:key1search(DirData, auth_group_file),
125
Groups = ets:match(GDB, '$1'),
126
{ok, httpd_util:uniq(lists:foldr(fun({G, _}, A) -> [G|A] end,
127
[], lists:flatten(Groups)))}.
129
delete_group_member(DirData, Group, User) ->
130
GDB = httpd_util:key1search(DirData, auth_group_file),
131
case ets:lookup(GDB, Group) of
132
[{Group, Users}] when is_list(Users) ->
133
case lists:member(User, Users) of
135
ets:delete(GDB, Group),
136
ets:insert(GDB, {Group, lists:delete(User, Users)}),
139
{error, no_such_group_member}
142
{error, no_such_group}
145
delete_group(DirData, Group) ->
146
GDB = httpd_util:key1search(DirData, auth_group_file),
147
case ets:lookup(GDB, Group) of
149
ets:delete(GDB, Group),
152
{error, no_such_group}
155
store_directory_data(_Directory, DirData) ->
156
PWFile = httpd_util:key1search(DirData, auth_user_file),
157
GroupFile = httpd_util:key1search(DirData, auth_group_file),
158
case load_passwd(PWFile) of
160
case load_group(GroupFile) of
162
%% Address and port is included in the file names...
163
Addr = httpd_util:key1search(DirData, bind_address),
164
Port = httpd_util:key1search(DirData, port),
165
{ok, PasswdDB} = store_passwd(Addr,Port,PWDB),
166
{ok, GroupDB} = store_group(Addr,Port,GRDB),
167
NDD1 = lists:keyreplace(auth_user_file, 1, DirData,
168
{auth_user_file, PasswdDB}),
169
NDD2 = lists:keyreplace(auth_group_file, 1, NDD1,
170
{auth_group_file, GroupDB}),
183
load_passwd(AuthUserFile) ->
184
case file:open(AuthUserFile, read) of
186
parse_passwd(Stream, []);
188
{error, ?NICE("Can't open "++AuthUserFile)}
191
parse_passwd(Stream,PasswdList) ->
193
case io:get_line(Stream, '') of
197
httpd_conf:clean(String)
199
parse_passwd(Stream, PasswdList, Line).
201
parse_passwd(Stream, PasswdList, eof) ->
204
parse_passwd(Stream, PasswdList, "") ->
205
parse_passwd(Stream, PasswdList);
206
parse_passwd(Stream, PasswdList, [$#|_]) ->
207
parse_passwd(Stream, PasswdList);
208
parse_passwd(Stream, PasswdList, Line) ->
209
case regexp:split(Line,":") of
210
{ok, [User,Password]} ->
211
parse_passwd(Stream, [{User,Password, []}|PasswdList]);
218
load_group(AuthGroupFile) ->
219
case file:open(AuthGroupFile, read) of
221
parse_group(Stream,[]);
223
{error, ?NICE("Can't open "++AuthGroupFile)}
226
parse_group(Stream, GroupList) ->
228
case io:get_line(Stream,'') of
232
httpd_conf:clean(String)
234
parse_group(Stream, GroupList, Line).
236
parse_group(Stream, GroupList, eof) ->
239
parse_group(Stream, GroupList, "") ->
240
parse_group(Stream, GroupList);
241
parse_group(Stream, GroupList, [$#|_]) ->
242
parse_group(Stream, GroupList);
243
parse_group(Stream, GroupList, Line) ->
244
case regexp:split(Line, ":") of
245
{ok, [Group,Users]} ->
246
{ok, UserList} = regexp:split(Users," "),
247
parse_group(Stream, [{Group,UserList}|GroupList]);
255
store_passwd(Addr,Port,PasswdList) ->
256
Name = httpd_util:make_name("httpd_passwd",Addr,Port),
257
PasswdDB = ets:new(Name, [set, public]),
258
store_passwd(PasswdDB, PasswdList).
260
store_passwd(PasswdDB, []) ->
262
store_passwd(PasswdDB, [User|Rest]) ->
263
ets:insert(PasswdDB, User),
264
store_passwd(PasswdDB, Rest).
268
store_group(Addr,Port,GroupList) ->
269
Name = httpd_util:make_name("httpd_group",Addr,Port),
270
GroupDB = ets:new(Name, [set, public]),
271
store_group(GroupDB, GroupList).
274
store_group(GroupDB,[]) ->
276
store_group(GroupDB,[User|Rest]) ->
277
ets:insert(GroupDB, User),
278
store_group(GroupDB, Rest).
283
%% Deletes ets tables used by this auth mod.
286
PWDB = httpd_util:key1search(DirData, auth_user_file),
287
GDB = httpd_util:key1search(DirData, auth_group_file),