summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDamien F. Katz <damien@apache.org>2008-08-05 16:54:45 +0000
committerDamien F. Katz <damien@apache.org>2008-08-05 16:54:45 +0000
commitba83243fd31766a30be5ecd84a010d8ef612b381 (patch)
treefb3dbdcc620250ecf9008ecd50dba0fb6bc827f4 /src
parent06fe49ed64013eda225593d6423d36129a4c50db (diff)
Readded file name checks for open and delete, as an attacker could use relative file names to open/delete otherwise inaccessible db files. Also changed view server shutdown when the parent db shutdowns into a non-normal termination, so that the linked supservisor correctly removes the process from its indexes.
git-svn-id: https://svn.apache.org/repos/asf/incubator/couchdb/trunk@682790 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_server.erl98
-rw-r--r--src/couchdb/couch_view.erl2
2 files changed, 56 insertions, 44 deletions
diff --git a/src/couchdb/couch_server.erl b/src/couchdb/couch_server.erl
index 86cdb2f8..b89f5abc 100644
--- a/src/couchdb/couch_server.erl
+++ b/src/couchdb/couch_server.erl
@@ -158,36 +158,43 @@ try_close_lru(StartTime) ->
end
end.
+handle_call(get_server, _From, Server) ->
+ {reply, Server, Server};
handle_call(get_root, _From, #server{root_dir=Root}=Server) ->
{reply, {ok, Root}, Server};
handle_call({open, DbName, Options}, {FromPid,_}, Server) ->
- Filepath = get_full_filename(Server, DbName),
- LruTime = now(),
- case ets:lookup(couch_dbs_by_name, DbName) of
- [] ->
- case maybe_close_lru_db(Server) of
- {ok, Server2} ->
- case couch_db:start_link(DbName, Filepath, Options) of
- {ok, MainPid} ->
- true = ets:insert(couch_dbs_by_name, {DbName, {MainPid, LruTime}}),
- true = ets:insert(couch_dbs_by_pid, {MainPid, DbName}),
- true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
- DbsOpen = Server2#server.current_dbs_open + 1,
- {reply,
- couch_db:open_ref_counted(MainPid, FromPid),
- Server2#server{current_dbs_open=DbsOpen}};
+ case check_dbname(Server, DbName) of
+ ok ->
+ Filepath = get_full_filename(Server, DbName),
+ LruTime = now(),
+ case ets:lookup(couch_dbs_by_name, DbName) of
+ [] ->
+ case maybe_close_lru_db(Server) of
+ {ok, Server2} ->
+ case couch_db:start_link(DbName, Filepath, Options) of
+ {ok, MainPid} ->
+ true = ets:insert(couch_dbs_by_name, {DbName, {MainPid, LruTime}}),
+ true = ets:insert(couch_dbs_by_pid, {MainPid, DbName}),
+ true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
+ DbsOpen = Server2#server.current_dbs_open + 1,
+ {reply,
+ couch_db:open_ref_counted(MainPid, FromPid),
+ Server2#server{current_dbs_open=DbsOpen}};
+ Error ->
+ {reply, Error, Server2}
+ end;
CloseError ->
- {reply, CloseError, Server2}
+ {reply, CloseError, Server}
end;
- Error ->
- {reply, Error, Server}
+ [{_, {MainPid, PrevLruTime}}] ->
+ true = ets:insert(couch_dbs_by_name, {DbName, {MainPid, LruTime}}),
+ true = ets:delete(couch_dbs_by_lru, PrevLruTime),
+ true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
+ {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
end;
- [{_, {MainPid, PrevLruTime}}] ->
- true = ets:insert(couch_dbs_by_name, {DbName, {MainPid, LruTime}}),
- true = ets:delete(couch_dbs_by_lru, PrevLruTime),
- true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
- {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
+ Error ->
+ {reply, Error, Server}
end;
handle_call({create, DbName, Options}, {FromPid,_}, Server) ->
case check_dbname(Server, DbName) of
@@ -216,27 +223,32 @@ handle_call({create, DbName, Options}, {FromPid,_}, Server) ->
{reply, Error, Server}
end;
handle_call({delete, DbName}, _From, Server) ->
- FullFilepath = get_full_filename(Server, DbName),
- Server2 =
- case ets:lookup(couch_dbs_by_name, DbName) of
- [] -> Server;
- [{_, {Pid, LruTime}}] ->
- exit(Pid, kill),
- receive {'EXIT', Pid, _Reason} -> ok end,
- true = ets:delete(couch_dbs_by_name, DbName),
- true = ets:delete(couch_dbs_by_pid, Pid),
- true = ets:delete(couch_dbs_by_lru, LruTime),
- DbsOpen = Server#server.current_dbs_open - 1,
- Server#server{current_dbs_open=DbsOpen}
- end,
- case file:delete(FullFilepath) of
+ case check_dbname(Server, DbName) of
ok ->
- couch_db_update_notifier:notify({deleted, DbName}),
- {reply, ok, Server2};
- {error, enoent} ->
- {reply, not_found, Server2};
- Else ->
- {reply, Else, Server2}
+ FullFilepath = get_full_filename(Server, DbName),
+ Server2 =
+ case ets:lookup(couch_dbs_by_name, DbName) of
+ [] -> Server;
+ [{_, {Pid, LruTime}}] ->
+ exit(Pid, kill),
+ receive {'EXIT', Pid, _Reason} -> ok end,
+ true = ets:delete(couch_dbs_by_name, DbName),
+ true = ets:delete(couch_dbs_by_pid, Pid),
+ true = ets:delete(couch_dbs_by_lru, LruTime),
+ DbsOpen = Server#server.current_dbs_open - 1,
+ Server#server{current_dbs_open=DbsOpen}
+ end,
+ case file:delete(FullFilepath) of
+ ok ->
+ couch_db_update_notifier:notify({deleted, DbName}),
+ {reply, ok, Server2};
+ {error, enoent} ->
+ {reply, not_found, Server2};
+ Else ->
+ {reply, Else, Server2}
+ end;
+ Error ->
+ {reply, Error, Server}
end;
handle_call(remote_restart, _From, #server{remote_restart=false}=Server) ->
{reply, ok, Server};
diff --git a/src/couchdb/couch_view.erl b/src/couchdb/couch_view.erl
index a29a809c..3ed51d80 100644
--- a/src/couchdb/couch_view.erl
+++ b/src/couchdb/couch_view.erl
@@ -426,7 +426,7 @@ get_notify_pids(Wait) ->
[Pid | get_notify_pids()];
{'DOWN', _MonitorRef, _Type, _Pid, _Info} ->
?LOG_DEBUG("View monitor received parent db shutdown notification. Shutting down instance.", []),
- exit(normal);
+ exit(db_shutdown);
Else ->
?LOG_ERROR("Unexpected message in view updater: ~p", [Else]),
exit({error, Else})