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").
 

Reply via email to