2007-05-06 22:36:48 +00:00
|
|
|
/*
|
2010-01-28 15:48:33 +00:00
|
|
|
* include/proto/acl.h
|
|
|
|
* This file provides interface definitions for ACL manipulation.
|
|
|
|
*
|
MEDIUM: samples: move payload-based fetches and ACLs to their own file
The file acl.c is a real mess, it both contains functions to parse and
process ACLs, and some sample extraction functions which act on buffers.
Some other payload analysers were arbitrarily dispatched to proto_tcp.c.
So now we're moving all payload-based fetches and ACLs to payload.c
which is capable of extracting data from buffers and rely on everything
that is protocol-independant. That way we can safely inflate this file
and only use the other ones when some fetches are really specific (eg:
HTTP, SSL, ...).
As a result of this cleanup, the following new sample fetches became
available even if they're not really useful :
always_false, always_true, rep_ssl_hello_type, rdp_cookie_cnt,
req_len, req_ssl_hello_type, req_ssl_sni, req_ssl_ver, wait_end
The function 'acl_fetch_nothing' was wrong and never used anywhere so it
was removed.
The "rdp_cookie" sample fetch used to have a mandatory argument while it
was optional in ACLs, which are supposed to iterate over RDP cookies. So
we're making it optional as a fetch too, and it will return the first one.
2013-01-07 20:59:07 +00:00
|
|
|
* Copyright (C) 2000-2013 Willy Tarreau - w@1wt.eu
|
2010-01-28 15:48:33 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation, version 2.1
|
|
|
|
* exclusively.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
2007-05-06 22:36:48 +00:00
|
|
|
|
|
|
|
#ifndef _PROTO_ACL_H
|
|
|
|
#define _PROTO_ACL_H
|
|
|
|
|
|
|
|
#include <common/config.h>
|
|
|
|
#include <types/acl.h>
|
2012-04-27 19:52:18 +00:00
|
|
|
#include <proto/sample.h>
|
2007-05-06 22:36:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* FIXME: we need destructor functions too !
|
|
|
|
*/
|
|
|
|
|
2008-07-09 14:18:21 +00:00
|
|
|
/* Negate an acl result. This turns (ACL_PAT_FAIL, ACL_PAT_MISS, ACL_PAT_PASS)
|
|
|
|
* into (ACL_PAT_PASS, ACL_PAT_MISS, ACL_PAT_FAIL).
|
|
|
|
*/
|
|
|
|
static inline int acl_neg(int res)
|
|
|
|
{
|
|
|
|
return (3 >> res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert an acl result to a boolean. Only ACL_PAT_PASS returns 1. */
|
|
|
|
static inline int acl_pass(int res)
|
|
|
|
{
|
|
|
|
return (res >> 1);
|
|
|
|
}
|
2007-05-06 22:36:48 +00:00
|
|
|
|
|
|
|
/* Return a pointer to the ACL <name> within the list starting at <head>, or
|
|
|
|
* NULL if not found.
|
|
|
|
*/
|
|
|
|
struct acl *find_acl_by_name(const char *name, struct list *head);
|
|
|
|
|
|
|
|
/* Return a pointer to the ACL keyword <kw> within the list starting at <head>,
|
|
|
|
* or NULL if not found. Note that if <kw> contains an opening parenthesis,
|
|
|
|
* only the left part of it is checked.
|
|
|
|
*/
|
|
|
|
struct acl_keyword *find_acl_kw(const char *kw);
|
|
|
|
|
|
|
|
/* Parse an ACL expression starting at <args>[0], and return it.
|
|
|
|
* Right now, the only accepted syntax is :
|
|
|
|
* <subject> [<value>...]
|
|
|
|
*/
|
MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
While ACL args were resolved after all the config was parsed, it was not the
case with sample fetch args because they're almost everywhere now.
The issue is that ACLs now solely rely on sample fetches, so their args
resolving doesn't work anymore. And many fetches involving a server, a
proxy or a userlist don't work at all.
The real issue is that at the bottom layers we have no information about
proxies, line numbers, even ACLs in order to report understandable errors,
and that at the top layers we have no visibility over the locations where
fetches are referenced (think log node).
After failing multiple unsatisfying solutions attempts, we now have a new
concept of args list. The principle is that every proxy has a list head
which contains a number of indications such as the config keyword, the
context where it's used, the file and line number, etc... and a list of
arguments. This list head is of the same type as the elements, so it
serves as a template for adding new elements. This way, it is filled from
top to bottom by the callers with the information they have (eg: line
numbers, ACL name, ...) and the lower layers just have to duplicate it and
add an element when they face an argument they cannot resolve yet.
Then at the end of the configuration parsing, a loop passes over each
proxy's list and resolves all the args in sequence. And this way there is
all necessary information to report verbose errors.
The first immediate benefit is that for the first time we got very precise
location of issues (arg number in a keyword in its context, ...). Second,
in order to do this we had to parse log-format and unique-id-format a bit
earlier, so that was a great opportunity for doing so when the directives
are encountered (unless it's a default section). This way, the recorded
line numbers for these args are the ones of the place where the log format
is declared, not the end of the file.
Userlists report slightly more information now. They're the only remaining
ones in the ACL resolving function.
2013-04-02 14:34:32 +00:00
|
|
|
struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *al);
|
2007-05-06 22:36:48 +00:00
|
|
|
|
[MEDIUM] Fix memory freeing at exit
New functions implemented:
- deinit_pollers: called at the end of deinit())
- prune_acl: called via list_for_each_entry_safe
Add missing pool_destroy2 calls:
- p->hdr_idx_pool
- pool2_tree64
Implement all task stopping:
- health-check: needs new "struct task" in the struct server
- queue processing: queue_mgt
- appsess_refresh: appsession_refresh
before (idle system):
==6079== LEAK SUMMARY:
==6079== definitely lost: 1,112 bytes in 75 blocks.
==6079== indirectly lost: 53,356 bytes in 2,090 blocks.
==6079== possibly lost: 52 bytes in 1 blocks.
==6079== still reachable: 150,996 bytes in 504 blocks.
==6079== suppressed: 0 bytes in 0 blocks.
after (idle system):
==6945== LEAK SUMMARY:
==6945== definitely lost: 7,644 bytes in 137 blocks.
==6945== indirectly lost: 9,913 bytes in 587 blocks.
==6945== possibly lost: 0 bytes in 0 blocks.
==6945== still reachable: 0 bytes in 0 blocks.
==6945== suppressed: 0 bytes in 0 blocks.
before (running system for ~2m):
==9343== LEAK SUMMARY:
==9343== definitely lost: 1,112 bytes in 75 blocks.
==9343== indirectly lost: 54,199 bytes in 2,122 blocks.
==9343== possibly lost: 52 bytes in 1 blocks.
==9343== still reachable: 151,128 bytes in 509 blocks.
==9343== suppressed: 0 bytes in 0 blocks.
after (running system for ~2m):
==11616== LEAK SUMMARY:
==11616== definitely lost: 7,644 bytes in 137 blocks.
==11616== indirectly lost: 9,981 bytes in 591 blocks.
==11616== possibly lost: 0 bytes in 0 blocks.
==11616== still reachable: 4 bytes in 1 blocks.
==11616== suppressed: 0 bytes in 0 blocks.
Still not perfect but significant improvement.
2008-05-29 21:53:44 +00:00
|
|
|
/* Purge everything in the acl <acl>, then return <acl>. */
|
|
|
|
struct acl *prune_acl(struct acl *acl);
|
|
|
|
|
2007-05-06 22:36:48 +00:00
|
|
|
/* Parse an ACL with the name starting at <args>[0], and with a list of already
|
|
|
|
* known ACLs in <acl>. If the ACL was not in the list, it will be added.
|
|
|
|
* A pointer to that ACL is returned.
|
|
|
|
*
|
|
|
|
* args syntax: <aclname> <acl_expr>
|
|
|
|
*/
|
MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
While ACL args were resolved after all the config was parsed, it was not the
case with sample fetch args because they're almost everywhere now.
The issue is that ACLs now solely rely on sample fetches, so their args
resolving doesn't work anymore. And many fetches involving a server, a
proxy or a userlist don't work at all.
The real issue is that at the bottom layers we have no information about
proxies, line numbers, even ACLs in order to report understandable errors,
and that at the top layers we have no visibility over the locations where
fetches are referenced (think log node).
After failing multiple unsatisfying solutions attempts, we now have a new
concept of args list. The principle is that every proxy has a list head
which contains a number of indications such as the config keyword, the
context where it's used, the file and line number, etc... and a list of
arguments. This list head is of the same type as the elements, so it
serves as a template for adding new elements. This way, it is filled from
top to bottom by the callers with the information they have (eg: line
numbers, ACL name, ...) and the lower layers just have to duplicate it and
add an element when they face an argument they cannot resolve yet.
Then at the end of the configuration parsing, a loop passes over each
proxy's list and resolves all the args in sequence. And this way there is
all necessary information to report verbose errors.
The first immediate benefit is that for the first time we got very precise
location of issues (arg number in a keyword in its context, ...). Second,
in order to do this we had to parse log-format and unique-id-format a bit
earlier, so that was a great opportunity for doing so when the directives
are encountered (unless it's a default section). This way, the recorded
line numbers for these args are the ones of the place where the log format
is declared, not the end of the file.
Userlists report slightly more information now. They're the only remaining
ones in the ACL resolving function.
2013-04-02 14:34:32 +00:00
|
|
|
struct acl *parse_acl(const char **args, struct list *known_acl, char **err, struct arg_list *al);
|
2007-05-06 22:36:48 +00:00
|
|
|
|
|
|
|
/* Purge everything in the acl_cond <cond>, then return <cond>. */
|
|
|
|
struct acl_cond *prune_acl_cond(struct acl_cond *cond);
|
|
|
|
|
|
|
|
/* Parse an ACL condition starting at <args>[0], relying on a list of already
|
|
|
|
* known ACLs passed in <known_acl>. The new condition is returned (or NULL in
|
|
|
|
* case of low memory). Supports multiple conditions separated by "or".
|
|
|
|
*/
|
MAJOR: sample: maintain a per-proxy list of the fetch args to resolve
While ACL args were resolved after all the config was parsed, it was not the
case with sample fetch args because they're almost everywhere now.
The issue is that ACLs now solely rely on sample fetches, so their args
resolving doesn't work anymore. And many fetches involving a server, a
proxy or a userlist don't work at all.
The real issue is that at the bottom layers we have no information about
proxies, line numbers, even ACLs in order to report understandable errors,
and that at the top layers we have no visibility over the locations where
fetches are referenced (think log node).
After failing multiple unsatisfying solutions attempts, we now have a new
concept of args list. The principle is that every proxy has a list head
which contains a number of indications such as the config keyword, the
context where it's used, the file and line number, etc... and a list of
arguments. This list head is of the same type as the elements, so it
serves as a template for adding new elements. This way, it is filled from
top to bottom by the callers with the information they have (eg: line
numbers, ACL name, ...) and the lower layers just have to duplicate it and
add an element when they face an argument they cannot resolve yet.
Then at the end of the configuration parsing, a loop passes over each
proxy's list and resolves all the args in sequence. And this way there is
all necessary information to report verbose errors.
The first immediate benefit is that for the first time we got very precise
location of issues (arg number in a keyword in its context, ...). Second,
in order to do this we had to parse log-format and unique-id-format a bit
earlier, so that was a great opportunity for doing so when the directives
are encountered (unless it's a default section). This way, the recorded
line numbers for these args are the ones of the place where the log format
is declared, not the end of the file.
Userlists report slightly more information now. They're the only remaining
ones in the ACL resolving function.
2013-04-02 14:34:32 +00:00
|
|
|
struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int pol, char **err, struct arg_list *al);
|
2007-05-06 22:36:48 +00:00
|
|
|
|
2010-01-28 15:48:33 +00:00
|
|
|
/* Builds an ACL condition starting at the if/unless keyword. The complete
|
|
|
|
* condition is returned. NULL is returned in case of error or if the first
|
|
|
|
* word is neither "if" nor "unless". It automatically sets the file name and
|
2013-03-24 06:22:08 +00:00
|
|
|
* the line number in the condition for better error reporting, and sets the
|
|
|
|
* HTTP initialization requirements in the proxy. If <err> is not NULL, it will
|
2012-04-27 10:38:15 +00:00
|
|
|
* be set to an error message upon errors, that the caller will have to free.
|
2010-01-28 15:48:33 +00:00
|
|
|
*/
|
2012-04-27 10:38:15 +00:00
|
|
|
struct acl_cond *build_acl_cond(const char *file, int line, struct proxy *px, const char **args, char **err);
|
2010-01-28 15:48:33 +00:00
|
|
|
|
2008-07-09 14:18:21 +00:00
|
|
|
/* Execute condition <cond> and return either ACL_PAT_FAIL, ACL_PAT_MISS or
|
|
|
|
* ACL_PAT_PASS depending on the test results. This function only computes the
|
|
|
|
* condition, it does not apply the polarity required by IF/UNLESS, it's up to
|
|
|
|
* the caller to do this.
|
2007-05-06 22:36:48 +00:00
|
|
|
*/
|
2012-04-25 08:13:36 +00:00
|
|
|
int acl_exec_cond(struct acl_cond *cond, struct proxy *px, struct session *l4, void *l7, unsigned int opt);
|
2007-05-06 22:36:48 +00:00
|
|
|
|
2013-03-25 07:12:18 +00:00
|
|
|
/* Returns a pointer to the first ACL conflicting with usage at place <where>
|
|
|
|
* which is one of the SMP_VAL_* bits indicating a check place, or NULL if
|
|
|
|
* no conflict is found. Only full conflicts are detected (ACL is not usable).
|
|
|
|
* Use the next function to check for useless keywords.
|
2008-07-27 20:02:32 +00:00
|
|
|
*/
|
2013-03-25 07:12:18 +00:00
|
|
|
const struct acl *acl_cond_conflicts(const struct acl_cond *cond, unsigned int where);
|
|
|
|
|
|
|
|
/* Returns a pointer to the first ACL and its first keyword to conflict with
|
|
|
|
* usage at place <where> which is one of the SMP_VAL_* bits indicating a check
|
|
|
|
* place. Returns true if a conflict is found, with <acl> and <kw> set (if non
|
|
|
|
* null), or false if not conflict is found. The first useless keyword is
|
|
|
|
* returned.
|
|
|
|
*/
|
2013-03-31 20:59:32 +00:00
|
|
|
int acl_cond_kw_conflicts(const struct acl_cond *cond, unsigned int where, struct acl const **acl, char const **kw);
|
2008-07-27 20:02:32 +00:00
|
|
|
|
2010-01-29 18:26:18 +00:00
|
|
|
/*
|
|
|
|
* Find targets for userlist and groups in acl. Function returns the number
|
|
|
|
* of errors or OK if everything is fine.
|
|
|
|
*/
|
|
|
|
int acl_find_targets(struct proxy *p);
|
|
|
|
|
2007-05-06 22:36:48 +00:00
|
|
|
/* Return a pointer to the ACL <name> within the list starting at <head>, or
|
|
|
|
* NULL if not found.
|
|
|
|
*/
|
|
|
|
struct acl *find_acl_by_name(const char *name, struct list *head);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Registers the ACL keyword list <kwl> as a list of valid keywords for next
|
|
|
|
* parsing sessions.
|
|
|
|
*/
|
|
|
|
void acl_register_keywords(struct acl_kw_list *kwl);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unregisters the ACL keyword list <kwl> from the list of valid keywords.
|
|
|
|
*/
|
|
|
|
void acl_unregister_keywords(struct acl_kw_list *kwl);
|
|
|
|
|
2013-01-11 14:49:37 +00:00
|
|
|
/* initializes ACLs by resolving the sample fetch names they rely upon.
|
|
|
|
* Returns 0 on success, otherwise an error.
|
|
|
|
*/
|
|
|
|
int init_acl();
|
|
|
|
|
2007-05-06 22:36:48 +00:00
|
|
|
|
|
|
|
#endif /* _PROTO_ACL_H */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* c-indent-level: 8
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|