1%% ``Licensed under the Apache License, Version 2.0 (the "License"); 2%% you may not use this file except in compliance with the License. 3%% You may obtain a copy of the License at 4%% 5%% http://www.apache.org/licenses/LICENSE-2.0 6%% 7%% Unless required by applicable law or agreed to in writing, software 8%% distributed under the License is distributed on an "AS IS" BASIS, 9%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10%% See the License for the specific language governing permissions and 11%% limitations under the License. 12%% 13%% The Initial Developer of the Original Code is Ericsson Utvecklings AB. 14%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings 15%% AB. All Rights Reserved.'' 16%% 17%% $Id: mod_auth_mnesia.erl,v 1.2 2010/03/04 13:54:19 maria Exp $ 18%% 19-module(mod_auth_mnesia). 20-export([get_user/2, 21 list_group_members/2, 22 add_user/2, 23 add_group_member/3, 24 list_users/1, 25 delete_user/2, 26 list_groups/1, 27 delete_group_member/3, 28 delete_group/2]). 29 30-export([store_user/5, store_user/6, 31 store_group_member/5, store_group_member/6, 32 list_group_members/3, list_group_members/4, 33 list_groups/2, list_groups/3, 34 list_users/2, list_users/3, 35 remove_user/4, remove_user/5, 36 remove_group_member/5, remove_group_member/6, 37 remove_group/4, remove_group/5]). 38 39-export([store_directory_data/2]). 40 41-include("httpd.hrl"). 42-include("mod_auth.hrl"). 43 44 45 46store_directory_data(Directory, DirData) -> 47 %% We don't need to do anything here, we could ofcourse check that the appropriate 48 %% mnesia tables has been created prior to starting the http server. 49 ok. 50 51 52%% 53%% API 54%% 55 56%% Compatibility API 57 58 59store_user(UserName, Password, Port, Dir, AccessPassword) -> 60 %% AccessPassword is ignored - was not used in previous version 61 DirData = [{path,Dir},{port,Port}], 62 UStruct = #httpd_user{username = UserName, 63 password = Password}, 64 add_user(DirData, UStruct). 65 66store_user(UserName, Password, Addr, Port, Dir, AccessPassword) -> 67 %% AccessPassword is ignored - was not used in previous version 68 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 69 UStruct = #httpd_user{username = UserName, 70 password = Password}, 71 add_user(DirData, UStruct). 72 73store_group_member(GroupName, UserName, Port, Dir, AccessPassword) -> 74 DirData = [{path,Dir},{port,Port}], 75 add_group_member(DirData, GroupName, UserName). 76 77store_group_member(GroupName, UserName, Addr, Port, Dir, AccessPassword) -> 78 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 79 add_group_member(DirData, GroupName, UserName). 80 81list_group_members(GroupName, Port, Dir) -> 82 DirData = [{path,Dir},{port,Port}], 83 list_group_members(DirData, GroupName). 84 85list_group_members(GroupName, Addr, Port, Dir) -> 86 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 87 list_group_members(DirData, GroupName). 88 89list_groups(Port, Dir) -> 90 DirData = [{path,Dir},{port,Port}], 91 list_groups(DirData). 92 93list_groups(Addr, Port, Dir) -> 94 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 95 list_groups(DirData). 96 97list_users(Port, Dir) -> 98 DirData = [{path,Dir},{port,Port}], 99 list_users(DirData). 100 101list_users(Addr, Port, Dir) -> 102 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 103 list_users(DirData). 104 105remove_user(UserName, Port, Dir, _AccessPassword) -> 106 DirData = [{path,Dir},{port,Port}], 107 delete_user(DirData, UserName). 108 109remove_user(UserName, Addr, Port, Dir, _AccessPassword) -> 110 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 111 delete_user(DirData, UserName). 112 113remove_group_member(GroupName,UserName,Port,Dir,_AccessPassword) -> 114 DirData = [{path,Dir},{port,Port}], 115 delete_group_member(DirData, GroupName, UserName). 116 117remove_group_member(GroupName,UserName,Addr,Port,Dir,_AccessPassword) -> 118 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 119 delete_group_member(DirData, GroupName, UserName). 120 121remove_group(GroupName,Port,Dir,_AccessPassword) -> 122 DirData = [{path,Dir},{port,Port}], 123 delete_group(DirData, GroupName). 124 125remove_group(GroupName,Addr,Port,Dir,_AccessPassword) -> 126 DirData = [{path,Dir},{bind_address,Addr},{port,Port}], 127 delete_group(DirData, GroupName). 128 129%% 130%% Storage format of users in the mnesia table: 131%% httpd_user records 132%% 133 134add_user(DirData, UStruct) -> 135 {Addr, Port, Dir} = lookup_common(DirData), 136 UserName = UStruct#httpd_user.username, 137 Password = UStruct#httpd_user.password, 138 Data = UStruct#httpd_user.user_data, 139 User=#httpd_user{username={UserName,Addr,Port,Dir}, 140 password=Password, 141 user_data=Data}, 142 case mnesia:transaction(fun() -> mnesia:write(User) end) of 143 {aborted,Reason} -> 144 {error,Reason}; 145 _ -> 146 true 147 end. 148 149get_user(DirData, UserName) -> 150 {Addr, Port, Dir} = lookup_common(DirData), 151 case mnesia:transaction(fun() -> 152 mnesia:read({httpd_user, 153 {UserName,Addr,Port,Dir}}) 154 end) of 155 {aborted,Reason} -> 156 {error, Reason}; 157 {'atomic',[]} -> 158 {error, no_such_user}; 159 {'atomic', [Record]} when record(Record, httpd_user) -> 160 {ok, Record#httpd_user{username=UserName}}; 161 Other -> 162 {error, no_such_user} 163 end. 164 165list_users(DirData) -> 166 {Addr, Port, Dir} = lookup_common(DirData), 167 case mnesia:transaction(fun() -> 168 mnesia:match_object({httpd_user, 169 {'_',Addr,Port,Dir},'_','_'}) 170 end) of 171 {aborted,Reason} -> 172 {error,Reason}; 173 {'atomic',Users} -> 174 {ok, 175 lists:foldr(fun({httpd_user, {UserName, AnyAddr, AnyPort, AnyDir}, 176 Password, Data}, Acc) -> 177 [UserName|Acc] 178 end, 179 [], Users)} 180 end. 181 182delete_user(DirData, UserName) -> 183 {Addr, Port, Dir} = lookup_common(DirData), 184 case mnesia:transaction(fun() -> 185 mnesia:delete({httpd_user, 186 {UserName,Addr,Port,Dir}}) 187 end) of 188 {aborted,Reason} -> 189 {error,Reason}; 190 _ -> 191 true 192 end. 193 194%% 195%% Storage of groups in the mnesia table: 196%% Multiple instances of {#httpd_group, User} 197%% 198 199add_group_member(DirData, GroupName, User) -> 200 {Addr, Port, Dir} = lookup_common(DirData), 201 Group=#httpd_group{name={GroupName, Addr, Port, Dir}, userlist=User}, 202 case mnesia:transaction(fun() -> mnesia:write(Group) end) of 203 {aborted,Reason} -> 204 {error,Reason}; 205 _ -> 206 true 207 end. 208 209list_group_members(DirData, GroupName) -> 210 {Addr, Port, Dir} = lookup_common(DirData), 211 case mnesia:transaction(fun() -> 212 mnesia:read({httpd_group, 213 {GroupName,Addr,Port,Dir}}) 214 end) of 215 {aborted, Reason} -> 216 {error,Reason}; 217 {'atomic', Members} -> 218 {ok,[UserName || {httpd_group,{AnyGroupName,AnyAddr,AnyPort,AnyDir},UserName} <- Members, 219 AnyGroupName == GroupName, AnyAddr == Addr, 220 AnyPort == Port, AnyDir == Dir]} 221 end. 222 223list_groups(DirData) -> 224 {Addr, Port, Dir} = lookup_common(DirData), 225 case mnesia:transaction(fun() -> 226 mnesia:match_object({httpd_group, 227 {'_',Addr,Port,Dir},'_'}) 228 end) of 229 {aborted, Reason} -> 230 {error, Reason}; 231 {'atomic', Groups} -> 232 GroupNames= 233 [GroupName || {httpd_group,{GroupName,AnyAddr,AnyPort,AnyDir}, UserName} <- Groups, 234 AnyAddr == Addr, AnyPort == AnyPort, AnyDir == Dir], 235 {ok, httpd_util:uniq(lists:sort(GroupNames))} 236 end. 237 238delete_group_member(DirData, GroupName, UserName) -> 239 {Addr, Port, Dir} = lookup_common(DirData), 240 Group = #httpd_group{name={GroupName, Addr, Port, Dir}, userlist=UserName}, 241 case mnesia:transaction(fun() -> mnesia:delete_object(Group) end) of 242 {aborted,Reason} -> 243 {error,Reason}; 244 _ -> 245 true 246 end. 247 248%% THIS IS WRONG (?) ! 249%% Should first match out all httpd_group records for this group and then 250%% do mnesia:delete on those. Or ? 251 252delete_group(DirData, GroupName) -> 253 {Addr, Port, Dir} = lookup_common(DirData), 254 case mnesia:transaction(fun() -> 255 mnesia:delete({httpd_group, 256 {GroupName,Addr,Port,Dir}}) 257 end) of 258 {aborted,Reason} -> 259 {error,Reason}; 260 _ -> 261 true 262 end. 263 264%% Utility functions. 265 266lookup_common(DirData) -> 267 Dir = httpd_util:key1search(DirData, path), 268 Port = httpd_util:key1search(DirData, port), 269 Addr = httpd_util:key1search(DirData, bind_address), 270 {Addr, Port, Dir}. 271