authz.c

来自「subversion-1.4.3-1.tar.gz 配置svn的源码」· C语言 代码 · 共 603 行 · 第 1/2 页

C
603
字号
/* authz.c : path-based access control * * ==================================================================== * Copyright (c) 2000-2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== *//*** Includes. ***/#include <assert.h>#include <apr_pools.h>#include <apr_file_io.h>#include "svn_pools.h"#include "svn_error.h"#include "svn_path.h"#include "svn_repos.h"#include "svn_config.h"#include "svn_ctype.h"/*** Structures. ***//* Information for the config enumerators called during authz   lookup. */struct authz_lookup_baton {  /* The authz configuration. */  svn_config_t *config;  /* The user to authorize. */  const char *user;  /* Explicitly granted rights. */  svn_repos_authz_access_t allow;  /* Explicitly denied rights. */  svn_repos_authz_access_t deny;  /* The rights required by the caller of the lookup. */  svn_repos_authz_access_t required_access;  /* The following are used exclusively in recursive lookups. */  /* The path in the repository to authorize. */  const char *repos_path;  /* repos_path prefixed by the repository name. */  const char *qualified_repos_path;  /* Whether, at the end of a recursive lookup, access is granted. */  svn_boolean_t access;};/* Information for the config enumeration functions called during the   validation process. */struct authz_validate_baton {  svn_config_t *config; /* The configuration file being validated. */  svn_error_t *err;     /* The error being thrown out of the                           enumerator, if any. */};/* Currently this structure is just a wrapper around a   svn_config_t. */struct svn_authz_t{  svn_config_t *cfg;};/*** Checking access. ***//* Determine whether the REQUIRED access is granted given what authz * to ALLOW or DENY.  Return TRUE if the REQUIRED access is * granted. * * Access is granted either when no required access is explicitly * denied (implicit grant), or when the required access is explicitly * granted, overriding any denials. */static svn_boolean_tauthz_access_is_granted(svn_repos_authz_access_t allow,                        svn_repos_authz_access_t deny,                        svn_repos_authz_access_t required){  svn_repos_authz_access_t stripped_req =    required & (svn_authz_read | svn_authz_write);  if ((deny & required) == svn_authz_none)    return TRUE;  else if ((allow & required) == stripped_req)    return TRUE;  else    return FALSE;}/* Decide whether the REQUIRED access has been conclusively * determined.  Return TRUE if the given ALLOW/DENY authz are * conclusive regarding the REQUIRED authz. * * Conclusive determination occurs when any of the REQUIRED authz are * granted or denied by ALLOW/DENY. */static svn_boolean_tauthz_access_is_determined(svn_repos_authz_access_t allow,                           svn_repos_authz_access_t deny,                           svn_repos_authz_access_t required){  if ((deny & required) || (allow & required))    return TRUE;  else    return FALSE;}/* Return TRUE if USER is in GROUP.  The group definitions are in the   "groups" section of CFG.  Use POOL for temporary allocations during   the lookup. */static svn_boolean_tauthz_group_contains_user(svn_config_t *cfg,                          const char *group,                          const char *user,                          apr_pool_t *pool){  const char *value;  apr_array_header_t *list;  int i;  svn_config_get(cfg, &value, "groups", group, NULL);  list = svn_cstring_split(value, ",", TRUE, pool);  for (i = 0; i < list->nelts; i++)    {      const char *group_user = APR_ARRAY_IDX(list, i, char *);      /* If the 'user' is a subgroup, recurse into it. */      if (*group_user == '@')        {          if (authz_group_contains_user(cfg, &group_user[1],                                        user, pool))            return TRUE;        }      /* If the user matches, stop. */      else if (strcmp(user, group_user) == 0)        return TRUE;    }  return FALSE;}/* Callback to parse one line of an authz file and update the * authz_baton accordingly. */static svn_boolean_tauthz_parse_line(const char *name, const char *value,                  void *baton, apr_pool_t *pool){  struct authz_lookup_baton *b = baton;  /* Work out whether this ACL line applies to the user. */  if (strcmp(name, "*") != 0)    {      /* Non-anon rule, anon user.  Stop. */      if (!b->user)        return TRUE;      /* Group rule and user not in group.  Stop. */      if (*name == '@')        {          if (!authz_group_contains_user(b->config, &name[1],                                         b->user, pool))            return TRUE;        }      /* User rule for wrong user.  Stop. */      else if (strcmp(name, b->user) != 0)        return TRUE;    }  /* Set the access grants for the rule. */  if (strchr(value, 'r'))    b->allow |= svn_authz_read;  else    b->deny |= svn_authz_read;  if (strchr(value, 'w'))    b->allow |= svn_authz_write;  else    b->deny |= svn_authz_write;  return TRUE;}/* Callback to parse a section and update the authz_baton if the * section denies access to the subtree the baton describes. */static svn_boolean_tauthz_parse_section(const char *section_name, void *baton, apr_pool_t *pool){  struct authz_lookup_baton *b = baton;  svn_boolean_t conclusive;  /* Does the section apply to us? */  if (svn_path_is_ancestor(b->qualified_repos_path,                           section_name) == FALSE      && svn_path_is_ancestor(b->repos_path,                              section_name) == FALSE)    return TRUE;  /* Work out what this section grants. */  b->allow = b->deny = 0;  svn_config_enumerate2(b->config, section_name,                        authz_parse_line, b, pool);  /* Has the section explicitly determined an access? */  conclusive = authz_access_is_determined(b->allow, b->deny,                                          b->required_access);  /* Is access granted OR inconclusive? */  b->access = authz_access_is_granted(b->allow, b->deny,                                      b->required_access)    || !conclusive;  /* As long as access isn't conclusively denied, carry on. */  return b->access;}/* Validate access to the given user for the given path.  This * function checks rules for exactly the given path, and first tries * to access a section specific to the given repository before falling * back to pan-repository rules. * * Update *access_granted to inform the caller of the outcome of the * lookup.  Return a boolean indicating whether the access rights were * successfully determined. */static svn_boolean_tauthz_get_path_access(svn_config_t *cfg, const char *repos_name,                      const char *path, const char *user,                      svn_repos_authz_access_t required_access,                      svn_boolean_t *access_granted,                      apr_pool_t *pool){  const char *qualified_path;  struct authz_lookup_baton baton = { 0 };  baton.config = cfg;  baton.user = user;  /* Try to locate a repository-specific block first. */  qualified_path = apr_pstrcat(pool, repos_name, ":", path, NULL);  svn_config_enumerate2(cfg, qualified_path,                        authz_parse_line, &baton, pool);  *access_granted = authz_access_is_granted(baton.allow, baton.deny,                                            required_access);  /* If the first test has determined access, stop now. */  if (authz_access_is_determined(baton.allow, baton.deny,                                 required_access))    return TRUE;  /* No repository specific rule, try pan-repository rules. */  svn_config_enumerate2(cfg, path, authz_parse_line, &baton, pool);  *access_granted = authz_access_is_granted(baton.allow, baton.deny,                                            required_access);  return authz_access_is_determined(baton.allow, baton.deny,                                    required_access);}/* Validate access to the given user for the subtree starting at the * given path.  This function walks the whole authz file in search of * rules applying to paths in the requested subtree which deny the * requested access. * * As soon as one is found, or else when the whole ACL file has been * searched, return the updated authorization status. */static svn_boolean_tauthz_get_tree_access(svn_config_t *cfg, const char *repos_name,                      const char *path, const char *user,                      svn_repos_authz_access_t required_access,                      apr_pool_t *pool){  struct authz_lookup_baton baton = { 0 };

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?