aboutsummaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_repos/authz_info.c
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
committerPeter Wemm <peter@FreeBSD.org>2018-05-08 03:44:38 +0000
commit3faf8d6bffc5d0fb2525ba37bb504c53366caf9d (patch)
tree7e47911263e75034b767fe34b2f8d3d17e91f66d /subversion/libsvn_repos/authz_info.c
parenta55fb3c0d5eca7d887798125d5b95942b1f01d4b (diff)
downloadsrc-3faf8d6bffc5d0fb2525ba37bb504c53366caf9d.tar.gz
src-3faf8d6bffc5d0fb2525ba37bb504c53366caf9d.zip
Import Subversion-1.10.0vendor/subversion/subversion-1.10.0
Notes
Notes: svn path=/vendor/subversion/dist/; revision=333347 svn path=/vendor/subversion/subversion-1.10.0/; revision=333348; tag=vendor/subversion/subversion-1.10.0
Diffstat (limited to 'subversion/libsvn_repos/authz_info.c')
-rw-r--r--subversion/libsvn_repos/authz_info.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/subversion/libsvn_repos/authz_info.c b/subversion/libsvn_repos/authz_info.c
new file mode 100644
index 000000000000..8f3a8b63b12a
--- /dev/null
+++ b/subversion/libsvn_repos/authz_info.c
@@ -0,0 +1,184 @@
+/* authz_info.c : Information derived from authz settings.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include <apr_hash.h>
+#include <apr_pools.h>
+#include <apr_tables.h>
+
+#include "svn_hash.h"
+
+#include "svn_private_config.h"
+
+#include "authz.h"
+
+
+svn_boolean_t
+svn_authz__acl_applies_to_repo(const authz_acl_t *acl,
+ const char *repos)
+{
+ /* The repository name must match the one in the rule, iff the rule
+ was defined for a specific repository. */
+ return (0 == strcmp(acl->rule.repos, AUTHZ_ANY_REPOSITORY))
+ || (0 == strcmp(repos, acl->rule.repos));
+}
+
+svn_boolean_t
+svn_authz__get_acl_access(authz_access_t *access_p,
+ const authz_acl_t *acl,
+ const char *user, const char *repos)
+{
+ authz_access_t access;
+ svn_boolean_t has_access;
+ int i;
+
+ /* The repository name must match the one in the rule, iff the rule
+ was defined for a specific repository. */
+ if (!svn_authz__acl_applies_to_repo(acl, repos))
+ return FALSE;
+
+ /* Check anonymous access first. */
+ if (!user || 0 == strcmp(user, AUTHZ_ANONYMOUS_USER))
+ {
+ if (!acl->has_anon_access)
+ return FALSE;
+
+ if (access_p)
+ *access_p = acl->anon_access;
+ return TRUE;
+ }
+
+ /* Get the access rights for all authenticated users. */
+ has_access = acl->has_authn_access;
+ access = (has_access ? acl->authn_access : authz_access_none);
+
+ /* Scan the ACEs in the ACL and merge the access rights. */
+ for (i = 0; i < acl->user_access->nelts; ++i)
+ {
+ const authz_ace_t *const ace =
+ &APR_ARRAY_IDX(acl->user_access, i, authz_ace_t);
+ const svn_boolean_t match =
+ ((ace->members && svn_hash_gets(ace->members, user))
+ || (!ace->members && 0 == strcmp(user, ace->name)));
+
+ if (!match != !ace->inverted) /* match XNOR ace->inverted */
+ {
+ access |= ace->access;
+ has_access = TRUE;
+ }
+ }
+
+ if (access_p)
+ *access_p = access;
+ return has_access;
+}
+
+/* Set *RIGHTS_P to the combination of LHS and RHS, i.e. intersect the
+ * minimal rights and join the maximum rights.
+ */
+static void
+combine_rights(authz_rights_t *rights_p,
+ const authz_rights_t *lhs,
+ const authz_rights_t *rhs)
+{
+ rights_p->min_access = lhs->min_access & rhs->min_access;
+ rights_p->max_access = lhs->max_access | rhs->max_access;
+}
+
+
+/* Given GLOBAL_RIGHTS and a repository name REPOS, set *RIGHTS_P to
+ * to the actual accumulated rights defined for that repository.
+ * Return TRUE if these rights were defined explicitly.
+ */
+static svn_boolean_t
+resolve_global_rights(authz_rights_t *rights_p,
+ const authz_global_rights_t *global_rights,
+ const char *repos)
+{
+ if (0 == strcmp(repos, AUTHZ_ANY_REPOSITORY))
+ {
+ /* Return the accumulated rights that are not repository-specific. */
+ *rights_p = global_rights->any_repos_rights;
+ return TRUE;
+ }
+ else
+ {
+ /* Check if we have explicit rights for this repository. */
+ const authz_rights_t *const rights =
+ svn_hash_gets(global_rights->per_repos_rights, repos);
+
+ if (rights)
+ {
+ combine_rights(rights_p, rights, &global_rights->any_repos_rights);
+ return TRUE;
+ }
+ }
+
+ /* Fall-through: return the rights defined for "any" repository
+ because this user has no specific rules for this specific REPOS. */
+ *rights_p = global_rights->any_repos_rights;
+ return FALSE;
+}
+
+
+svn_boolean_t
+svn_authz__get_global_rights(authz_rights_t *rights_p,
+ const authz_full_t *authz,
+ const char *user, const char *repos)
+{
+ if (!user || 0 == strcmp(user, AUTHZ_ANONYMOUS_USER))
+ {
+ /* Check if we have explicit rights for anonymous access. */
+ if (authz->has_anon_rights)
+ return resolve_global_rights(rights_p, &authz->anon_rights, repos);
+ }
+ else
+ {
+ /* Check if we have explicit rights for this user. */
+ const authz_global_rights_t *const user_rights =
+ svn_hash_gets(authz->user_rights, user);
+
+ if (user_rights)
+ {
+ svn_boolean_t explicit
+ = resolve_global_rights(rights_p, user_rights, repos);
+
+ /* Rights given to _any_ authenticated user may apply, too. */
+ if (authz->has_authn_rights)
+ {
+ authz_rights_t authn;
+ explicit |= resolve_global_rights(&authn, &authz->authn_rights,
+ repos);
+ combine_rights(rights_p, rights_p, &authn);
+ }
+ return explicit;
+ }
+
+ /* Check if we have explicit rights for authenticated access. */
+ if (authz->has_authn_rights)
+ return resolve_global_rights(rights_p, &authz->authn_rights, repos);
+ }
+
+ /* Fall-through: return the implicit rights, i.e., none. */
+ rights_p->min_access = authz_access_none;
+ rights_p->max_access = authz_access_none;
+ return FALSE;
+}