couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikewall...@apache.org
Subject [5/5] chttpd commit: updated refs/heads/2452-users-db-security-on-clustered-interface to 569b00f
Date Tue, 11 Nov 2014 00:24:13 GMT
Only admins access _users _all_docs on 5984

When couch_httpd_auth/users_db_public is set to false and the
_users DB is on the admin interface (5986) only admins can read
the _all_docs view.

This commit creates the same behaviour on the clustered interface
(5984) when chttpd_auth/users_db_public is set to false.

COUCHDB-2452 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/569b00f3
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/569b00f3
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/569b00f3

Branch: refs/heads/2452-users-db-security-on-clustered-interface
Commit: 569b00f301232a4b4ce2e038ef5bdf92c3b52079
Parents: 593462c
Author: Mike Wallace <mikewallace@apache.org>
Authored: Mon Nov 10 23:41:35 2014 +0000
Committer: Mike Wallace <mikewallace@apache.org>
Committed: Mon Nov 10 23:41:35 2014 +0000

----------------------------------------------------------------------
 src/chttpd_db.erl | 54 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/569b00f3/src/chttpd_db.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl
index 695e540..38a3e9e 100644
--- a/src/chttpd_db.erl
+++ b/src/chttpd_db.erl
@@ -258,9 +258,23 @@ delete_db_req(#httpd{}=Req, DbName) ->
         throw(Error)
     end.
 
+% TODO this duplicates code in couch_db:maybe_add_sys_db_callbacks/2. generalize and put
somewhere sensible
+% though only sys DBs which we'd allow on 5984, so _replicator and _users
+get_db_options(DbName) ->
+    IsReplicatorDb = DbName == config:get("replicator", "db", "_replicator"),
+    IsUsersDb = DbName ==config:get("chttpd_auth", "authentication_db", "_users") orelse
+    binary_to_list(mem3:dbname(DbName)) == config:get("chttpd_auth", "authentication_db",
"_users"),
+    case {IsReplicatorDb, IsUsersDb} of
+    {false, false} ->
+        [];
+    _Else ->
+        [sys_db]
+    end.
+
 do_db_req(#httpd{path_parts=[DbName|_], user_ctx=Ctx}=Req, Fun) ->
     cassim:get_security(DbName, [{user_ctx,Ctx}]), % calls check_is_reader
-    Fun(Req, #db{name=DbName, user_ctx=Ctx}).
+    Options = get_db_options(DbName),
+    Fun(Req, #db{name=DbName, user_ctx=Ctx, options=Options}).
 
 db_req(#httpd{method='GET',path_parts=[DbName]}=Req, _Db) ->
     % measure the time required to generate the etag, see if it's worth it
@@ -426,9 +440,9 @@ db_req(#httpd{path_parts=[_,<<"_purge">>]}=Req, _Db) ->
 db_req(#httpd{method='GET',path_parts=[_,<<"_all_docs">>]}=Req, Db) ->
     case chttpd:qs_json_value(Req, "keys", nil) of
     Keys when is_list(Keys) ->
-        all_docs_view(Req, Db, Keys);
+        all_docs_req(Req, Db, Keys);
     nil ->
-        all_docs_view(Req, Db, undefined);
+        all_docs_req(Req, Db, undefined);
     _ ->
         throw({bad_request, "`keys` parameter must be an array."})
     end;
@@ -437,9 +451,9 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_all_docs">>]}=Req,
Db) ->
     {Fields} = chttpd:json_body_obj(Req),
     case couch_util:get_value(<<"keys">>, Fields, nil) of
     Keys when is_list(Keys) ->
-        all_docs_view(Req, Db, Keys);
+        all_docs_req(Req, Db, Keys);
     nil ->
-        all_docs_view(Req, Db, undefined);
+        all_docs_req(Req, Db, undefined);
     _ ->
         throw({bad_request, "`keys` body member must be an array."})
     end;
@@ -542,6 +556,36 @@ db_req(#httpd{path_parts=[_, DocId]}=Req, Db) ->
 db_req(#httpd{path_parts=[_, DocId | FileNameParts]}=Req, Db) ->
     db_attachment_req(Req, Db, DocId, FileNameParts).
 
+all_docs_req(Req, Db, Keys) ->
+    case couch_db:is_system_db(Db) of
+    true ->
+        case (catch couch_db:check_is_admin(Db)) of
+        ok ->
+            all_docs_view(Req, Db, Keys);
+        _ ->
+            DbName = ?b2l(Db#db.name),
+            case config:get("chttpd_auth",
+                                  "authentication_db",
+                                  "_users") of
+            DbName ->
+                UsersDbPublic = config:get("chttpd_auth", "users_db_public", "false"),
+                PublicFields = config:get("chttpd_auth", "public_fields"),
+                case {UsersDbPublic, PublicFields} of
+                {"true", PublicFields} when PublicFields =/= undefined ->
+                    all_docs_view(Req, Db, Keys);
+                {_, _} ->
+                    throw({forbidden, <<"Only admins can access _all_docs",
+                                        " of system databases.">>})
+                end;
+            _ ->
+                throw({forbidden, <<"Only admins can access _all_docs",
+                                    " of system databases.">>})
+            end
+        end;
+    false ->
+        all_docs_view(Req, Db, Keys)
+    end.
+
 all_docs_view(Req, Db, Keys) ->
     Args0 = couch_mrview_http:parse_params(Req, Keys),
     ETagFun = fun(Sig, Acc0) ->


Mime
View raw message