Only admins access _users design documents The check for admin when opening a design document in the authentication DB was previously being carried out in a callback function called when the document was read from the shard. In order to allow admins to access the design document via the clustered interface it is necessary to either modify the chttpd/fabric plumbing so that the user context can be passed through for all design document calls, or alternatively move the check to the http layer where we already have the user context.
Due to the number of places we would need to modify fabric to allow the option to be passed through the latter approach is taken. This commit checks for admin in the http layer for requests which access design documents in the authentication DB. The couch internals part of that work can be found in related commit: couchdb-couch/6266b95415f8c8d8cde49a8ce221e9d31ebf18b8 COUCHDB-2452 5/5 Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/25ec565c Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/25ec565c Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/25ec565c Branch: refs/heads/2452-users-db-security-on-clustered-interface Commit: 25ec565c18379ce5090b35c3186f6d4a27fbb6c8 Parents: 9b5406b Author: Mike Wallace <mikewall...@apache.org> Authored: Thu Nov 13 20:32:34 2014 +0000 Committer: Mike Wallace <mikewall...@apache.org> Committed: Fri Nov 14 18:27:39 2014 +0000 ---------------------------------------------------------------------- src/chttpd_db.erl | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/25ec565c/src/chttpd_db.erl ---------------------------------------------------------------------- diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl index 8f624c2..b78592a 100644 --- a/src/chttpd_db.erl +++ b/src/chttpd_db.erl @@ -202,6 +202,13 @@ handle_design_req(#httpd{ path_parts=[_DbName, _Design, Name, <<"_",_/binary>> = Action | _Rest], design_url_handlers = DesignUrlHandlers }=Req, Db) -> + case catch(check_admin_if_auth_db(Db)) of + ok -> + ok; + _ -> + throw({forbidden, + <<"Only administrators can view design docs in the users database.">>}) + end, DbName = mem3:dbname(Db#db.name), case ddoc_cache:open(DbName, <<"_design/", Name/binary>>) of {ok, DDoc} -> @@ -622,6 +629,18 @@ db_doc_req(#httpd{method='DELETE'}=Req, Db, DocId) -> send_updated_doc(Req, Db, DocId, couch_doc_from_req(Req, DocId, Body)); db_doc_req(#httpd{method='GET'}=Req, Db, DocId) -> + case DocId of + <<"_design/", _/binary>> -> + case catch(check_admin_if_auth_db(Db)) of + ok -> + ok; + _ -> + throw({forbidden, + <<"Only administrators can view design docs in the users database.">>}) + end; + _Else -> + ok + end, #doc_query_args{ rev = Rev, open_revs = Revs, @@ -1508,6 +1527,22 @@ put_security(#httpd{user_ctx=Ctx}=Req, Db, FetchRev) -> end end. +check_admin_if_auth_db(Db) -> + DbName = mem3:dbname(Db#db.name), + AuthDbName = ?l2b(config:get("chttpd_auth", "authentication_db")), + case AuthDbName of + DbName -> + {SecProps} = fabric:get_security(DbName), + case (catch couch_db:check_is_admin(Db#db{security=SecProps})) of + ok -> + ok; + _ -> + throw(forbidden) + end; + _Else -> + ok + end. + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl").