authz.c

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

C
603
字号
  baton.config = cfg;  baton.user = user;  baton.required_access = required_access;  baton.repos_path = path;  baton.qualified_repos_path = apr_pstrcat(pool, repos_name,                                           ":", path, NULL);  /* Default to access granted if no rules say otherwise. */  baton.access = TRUE;  svn_config_enumerate_sections2(cfg, authz_parse_section,                                 &baton, pool);  return baton.access;}/* Callback to parse sections of the configuration file, looking for   any kind of granted access.  Implements the   svn_config_section_enumerator2_t interface. */static svn_boolean_tauthz_global_parse_section(const char *section_name, void *baton,                           apr_pool_t *pool){  struct authz_lookup_baton *b = baton;  /* Does the section apply to the query? */  if (section_name[0] == '/'      || strncmp(section_name, b->repos_path,                 strlen(b->repos_path)) == 0)    {      b->allow = b->deny = svn_authz_none;      svn_config_enumerate2(b->config, section_name,                            authz_parse_line, baton, pool);      b->access = authz_access_is_granted(b->allow, b->deny,                                          b->required_access);      /* Continue as long as we don't find a granted access. */      return !b->access;    }  return TRUE;}/* Walk through the authz CFG to check if USER has the REQUIRED_ACCESS * to any path within the REPOSITORY.  Return TRUE if so.  Use POOL * for temporary allocations. */static svn_boolean_tauthz_get_global_access(svn_config_t *cfg, const char *repos_name,                        const char *user,                        svn_repos_authz_access_t required_access,                        apr_pool_t *pool){  struct authz_lookup_baton baton = { 0 };  baton.config = cfg;  baton.user = user;  baton.required_access = required_access;  baton.access = FALSE; /* Deny access by default. */  baton.repos_path = apr_pstrcat(pool, repos_name, ":/", NULL);  svn_config_enumerate_sections2(cfg, authz_global_parse_section,                                 &baton, pool);  return baton.access;}/*** Validating the authz file. ***//* Check for errors in GROUP's definition of CFG.  The errors * detected are references to non-existent groups and circular * dependencies between groups.  If an error is found, return * SVN_ERR_AUTHZ_INVALID_CONFIG.  Use POOL for temporary * allocations only. * * CHECKED_GROUPS should be an empty (it is used for recursive calls). */static svn_error_t *authz_group_walk(svn_config_t *cfg,                 const char *group,                 apr_hash_t *checked_groups,                 apr_pool_t *pool){  const char *value;  apr_array_header_t *list;  int i;  svn_config_get(cfg, &value, "groups", group, NULL);  /* Having a non-existent group in the ACL configuration might be the     sign of a typo.  Refuse to perform authz on uncertain rules. */  if (!value)    return svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,                             "An authz rule refers to group '%s', "                             "which is undefined",                             group);  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 == '@')        {          /* A circular dependency between groups is a Bad Thing.  We             don't do authz with invalid ACL files. */          if (apr_hash_get(checked_groups, &group_user[1],                           APR_HASH_KEY_STRING))            return svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG,                                     NULL,                                     "Circular dependency between "                                     "groups '%s' and '%s'",                                     &group_user[1], group);          /* Add group to hash of checked groups. */          apr_hash_set(checked_groups, &group_user[1],                       APR_HASH_KEY_STRING, "");          /* Recurse on that group. */          SVN_ERR(authz_group_walk(cfg, &group_user[1],                                   checked_groups, pool));          /* Remove group from hash of checked groups, so that we don't             incorrectly report an error if we see it again as part of             another group. */          apr_hash_set(checked_groups, &group_user[1],                       APR_HASH_KEY_STRING, NULL);        }    }  return SVN_NO_ERROR;}/* Callback to check whether GROUP is a group name, and if so, whether   the group definition exists.  Return TRUE if the rule has no   errors.  Use BATON for context and error reporting. */static svn_boolean_t authz_validate_rule(const char *group,                                         const char *value,                                         void *baton,                                         apr_pool_t *pool){  const char *val;  struct authz_validate_baton *b = baton;  /* If the rule applies to a group, check its existence. */  if (*group == '@')    {      svn_config_get(b->config, &val, "groups", &group[1], NULL);      /* Having a non-existent group in the ACL configuration might be         the sign of a typo.  Refuse to perform authz on uncertain         rules. */      if (!val)        {          b->err = svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,                                     "An authz rule refers to group "                                     "'%s', which is undefined",                                     group);          return FALSE;        }    }  val = value;  while (*val)    {      if (*val != 'r' && *val != 'w' && ! svn_ctype_isspace(*val))        {          b->err = svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,                                     "The character '%c' in rule '%s' is not "                                     "allowed in authz rules", *val, group);          return FALSE;        }      ++val;    }  return TRUE;}/* Callback to check GROUP's definition for cyclic dependancies.  Use   BATON for context and error reporting. */static svn_boolean_t authz_validate_group(const char *group,                                          const char *value,                                          void *baton,                                          apr_pool_t *pool){  struct authz_validate_baton *b = baton;  b->err = authz_group_walk(b->config, group, apr_hash_make(pool), pool);  if (b->err)    return FALSE;  return TRUE;}/* Callback to check the contents of the configuration section given   by NAME.  Use BATON for context and error reporting. */static svn_boolean_t authz_validate_section(const char *name,                                            void *baton,                                            apr_pool_t *pool){  struct authz_validate_baton *b = baton;  /* If the section is the groups definition, use the group checking     callback. Otherwise, use the rule checking callback. */  if (strncmp(name, "groups", 6) == 0)    svn_config_enumerate2(b->config, name, authz_validate_group,                          baton, pool);  else    svn_config_enumerate2(b->config, name, authz_validate_rule,                          baton, pool);  if (b->err)    return FALSE;  return TRUE;}/*** Public functions. ***/svn_error_t *svn_repos_authz_read(svn_authz_t **authz_p, const char *file,                     svn_boolean_t must_exist, apr_pool_t *pool){  svn_authz_t *authz = apr_palloc(pool, sizeof(*authz));  struct authz_validate_baton baton = { 0 };  baton.err = SVN_NO_ERROR;  /* Load the rule file. */  SVN_ERR(svn_config_read(&authz->cfg, file, must_exist, pool));  baton.config = authz->cfg;  /* Step through the entire rule file, stopping on error. */  svn_config_enumerate_sections2(authz->cfg, authz_validate_section,                                 &baton, pool);  SVN_ERR(baton.err);  *authz_p = authz;  return SVN_NO_ERROR;}svn_error_t *svn_repos_authz_check_access(svn_authz_t *authz, 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 *current_path = path;  /* If PATH is NULL, do a global access lookup. */  if (!path)    {      *access_granted = authz_get_global_access(authz->cfg, repos_name,                                                user, required_access,                                                pool);      return SVN_NO_ERROR;    }  /* Determine the granted access for the requested path. */  while (!authz_get_path_access(authz->cfg, repos_name,                                current_path, user,                                required_access,                                access_granted,                                pool))    {      /* Stop if the loop hits the repository root with no         results. */      if (current_path[0] == '/' && current_path[1] == '\0')        {          /* Deny access by default. */          *access_granted = FALSE;          return SVN_NO_ERROR;        }      /* Work back to the parent path. */      svn_path_split(current_path, &current_path, NULL, pool);    }  /* If the caller requested recursive access, we need to walk through     the entire authz config to see whether any child paths are denied     to the requested user. */  if (*access_granted && (required_access & svn_authz_recursive))    *access_granted = authz_get_tree_access(authz->cfg, repos_name, path,                                            user, required_access, pool);  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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