Proxy Rules
A DLP server proxy rule consists primarily of a condition and a set of actions to be executed by the DLP server if the data in the running operation match the condition. Proxy rule types include:
-
User-routing rules, where the target server selection is made according to an explicit user DN, a regular expression for a user’s DN and/or a node DN below which a user resides. User-routing rules can be defined, for example, to redirect groups of users to a specific target server or servers. Note that if the DN represents a group, the DNs inside the group are not dereferenced; that is, users inside a group are not implicitly used if the DN describes a group.
-
Operation-routing rules, where the target server selection is made according to the type of operation to be forwarded. Operation-routing rules can be defined, for example, to direct all modification operations to a master server while searches are directed to a shadow server, or to direct all searches with a particular base object to a dedicated server while all other operations are forwarded to another target server.
-
Request-and result-rewriting rules, where modifications to an operation’s data are made according to the actions defined in the rule if the running operation matches the condition defined in the rule. Rewriting rules can be defined, for example, to update attributes like organization names associated with communication between legacy clients and a directory service or to remove sensitive information returned in search results before returning them to clients.
The ProxyRule DLP server configuration object defines a proxy rule. Multiple proxy rules can be defined; the DLP server evaluates and executes proxy rules in the order in which they appear in the DLP server configuration file.
This chapter provides detailed syntax and operational information for each proxy rule type and also provides information about special character handling that applies to all proxy rule types. The section “The ProxyRule Object" in the “Configuration” chapter provides syntax and operational information that is common to all proxy rule types.
User-routing Rules
The UserRouting proxy rule type defines an operation-forwarding rule for one explicitly-specified user, for users whose DN match a regular expression (wildcard) or for users below a given node in the DIT.If the DN of the bound user matches the configured condition in this rule, the rule is applied.The next sections describe how to specify user-routing rules and how the DLP server processes them.
Syntax Description
User-routing rules are specified as ProxyRule objects in the DLP server configuration file.Here is an example of a user-routing rule:
{
"object" : "ProxyRule",
"ruleType" : "UserRouting",
"name" : "USERROUTING1",
"condition" : "(|(user=cn=richter,ou=sales,o=my-company)(wcuser=^cn=D.*o=my-company)(subuser=ou=sales,o=my-company))",
"actions" : [ "forwardto(LDAP2,LDAP1)" ],
"loadbalance" : 0,
"failover" : 1
}
In the object definition:
-
The object key is mandatory and must be the string ProxyRule.
-
The ruleType key is mandatory and must be UserRouting.
-
The name key is mandatory and can have any string value as long as the value is unique.
-
The condition key is a mandatory LDAP filter string in the format token assertion value that describes the criteria that the user DN in the incoming bind operation must satisfy in order for the DLP server to perform the forwarding action defined in the rule.
For user-routing rules, token is one of the following user classes:
-
user – the rule is to be applied to one explicitly specified user. If the DN of the bound user matches the configured DN in this rule, the rule is applied. The value must be a syntactically legal LDAP DN. The rule will be selected according to this DN when this user invokes an LDAP bind operation. You can specify the string anonymous for the user DN to define a rule that applies to anonymous users that do not perform a bind operation or bind as an anonymous user. As authentication via method EXTERNAL SASL is not supported, users identified by their X.509 certificate cannot be used.
-
subuser – the rule is to be applied to the users below a given node in the DIT. The subuser rule works like the user rule except that instead of defining a single user, all users below the specified node are affected. However, if a user in the specified subtree has an explicit user rule assigned, this specific rule overrides the subuser rule because a user rule takes precedence over a subuser rule.
-
wcuser – defines a rule for users whose DN match a regular expression (wildcard). This rule works exactly like the user rule except that the user’s DN is matched against a regular expression given in the wcuser value. The regular expression follows the Linux/Perl regular expression syntax and is performed case-insensitive.
Although assertion can be any valid LDAP assertion (see the section “Rewriting Rules → “The Condition Key” → “Condition Rule Syntax” for the list of supported and unsupported assertions), the power of using the wildcard user (wcuser) condition, where you can assign almost any kind of abbreviation for a DN, means that the equal assertion is the most meaningful assertion to use in user-routing rules.
In the example wcuser=^cn=D.*o=my-company above, users like
cn=Digger,ou=development,o=my-company
cn=Digger,ou=sales,o=my-company
cn=Digger,ou=support2,ou=support1,o=my-company
match the rule.
-
The actions key is mandatory. For user-routing rules, the forwardto action is the only action supported (besides the general action denyreq) and defines a JSON array of LDAP target servers enclosed in square brackets [ ]. The target servers are indicated by their names and must match the name of an LDAPserver object definition in the same configuration file. At least one name must be present in the array (an empty array is not allowed). The first server given in the list is considered to be the default primary server. Be sure to avoid leading and trailing blanks in LDAP server names as they will be interpreted as part of the name.
User-routing rules can also specify the denyreq general action. For more information on what this action does, see “Rewriting Rules” → “Syntax Description” → “The actions Key” → “General Actions”.
-
The loadbalance key is optional and defines how the DLP server handles the servers listed in the forwardto action during primary server selection (the first server to be contacted from the list). The DLP server does not perform load balancing by default: the first server from the list is always the primary server. To change the default behavior, specify the loadbalance key and set it to 1. Now, for every new bind from the user, the DLP server selects the next server from the list using a round-robin scheme.
-
The failover key is optional and defines how the DLP server handles the servers listed in the forwardto action when an error occurs while sending a request to the target server. By default, there is a failover to the next server if an error occurs with the selected target server. To change the default behavior, specify the failover key and set it to 0. Now the operation will fail if the primary server fails.
| The default behavior for loadbalance and failover differs between user, subuser and wcuser rule conditions. The reason for this difference is the general assumption that multi-user rules (subuser and wcuser) will generate too much traffic for a single target server and thus load balancing is the desired behavior. In contrast, the traffic from a single user is not so relevant to the total server load. |
If failover is active and all configured servers fail, the entire operation fails.
The section “How User-routing rules are Processed” provides more information about how the DLP server selects user-routing rules and target servers given load-balancing and failover settings.
Each LDAP client has its own backend LDAP connection; no backend sharing takes place even if credential match or backend sharing has been configured in the LDAP configuration subentry. Once established, the backend connection to the selected target remains open until the client performs an unbind operation, drops the connection to the DLP server, the target server closes the connection (for example, because of client-idle-timeout) or a network error occurs. Due to the one-to-one relationship between frontend client connections and backend server connections, the possible number of parallel client connection depends on the number of available socket descriptors.
How User-routing Rules are Processed
A target server from a user-routing rule is selected by one the following events:
-
A client performs a bind operation. It doesn’t matter whether the bind operation is the first operation on a LDAP connection or if it occurs at later time on the existing connection.
Whenever the DLP server detects a bind, it searches for a user-routing rule for the user defined by the incoming bind operation. If the DLP server finds a rule, it sets the target server according to the rule. If a target server has already been selected (for example, because a bind occurred earlier on this connection) the DLP server drops the existing connection and uses the target server from the last bind operation for all subsequent operations; that is, a total target shift is performed. If the new target server(s) cannot be connected, the existing connection remains intact and all further operations will go to the old target (shift on success).
-
The first operation on a newly created LDAP connection is not a bind. In this case, the DLP server assumes an anonymous user, searches for a user-routing rule for anonymous and sets the target server accordingly. If no rule is found, the DLP server uses the LB-servers as a fallback.
The DLP server evaluates user-routing rules in the order in which they are specified in the DLP server configuration file; that is, it evaluate the first user-routing rule if finds, then the second and so on.
If a condition matches the user, the DLP server stops searching and assigns the servers from the corresponding user-routing rule to the user as new target servers for LDAP requests. The servers from a matching user-routing rule are called the “relevant servers” for the current user. Note that servers that have been previously detected to fail or are marked as offline are automatically excluded from the relevant servers.
In a list of servers, the server that the DLP server selects first is defined by the loadbalance option in the rule.A value of 0 specifies that the first server in the list is always selected for the requests.A value of 1 specifies that a target server is to be selected using a simple round-robin selection process.
Once a target server is selected and successfully contacted, all subsequent requests are sent to the same selected server until a new bind operation is performed on the same LDAP connection or the connection ends.If the DLP server cannot contact a target server or an established connection to this server fails, the failover option defines whether or not the next server from the relevant servers list is selected and the request resubmitted to this server.If failover is set to 1 and the connection to a server breaks, the next server from the list is selected as the new target server and all subsequent requests are sent to this new server (until this server also fails) This automatic reselection is transparent to the client and continues until all relevant servers have been contacted and have failed at least once.
For example: Let’s assume that the list of target servers for user X is LDAP1, LDAP2, LDAP3 and that failover=1 and loadbalancing=1 are set.
When user X binds for the first time LDAP1 is selected.If LDAP1 can be contacted successfully, LDAP1 is the target server for all subsequent operations.
After performing some operations, user X closes his connection (unbind).Sometime later, user X again performs a bind and LDAP2 is selected (loadbalancing=1) but now LDAP2 is down and cannot be reached.As failover=1 is set, the next selected target server is LDAP3, which is up and the bind succeeds.Again, user X performs some operations against LDAP3 and finally closes the connection.A few moments later, user X binds again and because loadbalancing=1, LDAP3 is selected (last time, LDAP2 was selected due to load-balancing and then failed; failover occurred but the selection for load-balancing is not influenced by failover) Thus we now have LDAP3 again as the target server for all remaining operations.This example shows that load-balancing selection and failover selection are independent from each other although they select from the same list.
Operation-routing Rules
The OprRouting proxy rule type defines an operation-forwarding rule for one explicitly-specified LDAP operation.Operation-routing rules can direct single operations, based upon the request parameters, to dedicated target servers.If the operation matches the configured condition in the rule, the rule is applied.
Syntax Description
Operation-routing rules are specified as ProxyRule objects in the DLP server configuration file.Here is an example of an operation-routing rule:
{
"object" : "ProxyRule",
"ruleType" : "OprRouting",
"name" : "OPRROUTING2",
"condition" : "(&(opr.req.type=search)(search.req.baseObject=o=pqr))",
"actions" : [ "singleforwardto(LDAP1,LDAP3)" ],
"failover" : 1,
"keepconn" : 1
}
In the object definition:
-
The object key is mandatory and must be the string ProxyRule.
-
The ruleType key is mandatory and must be OprRouting.
-
The name key is mandatory and can have any string value as long as the value is unique.
-
The condition key is a mandatory LDAP filter string in the format token assertion value that describes the criteria that the running operation must satisfy in order for the DLP server to perform the action on the operation defined in the rule. See the condition syntax description in the section “Rewriting Rules” → “Syntax Description” → “The Condition Key” → “Condition Rule Syntax” for details about this format as it applies to operation-routing rules and rewriting rules.
For operation-routing rules, token can be any of the tokens described in the table “Condition Token Names and Assignments” provided in the section “Rewriting Rules”. Note that condition keys that specify bind operations - for example, opr.req.type=bind opr.req.type=* - are not permitted to be used in operation-routing rules because bind operations are handled separately by the user-routing rules and specifying them here may lead to unwanted behavior.
-
The actions key is mandatory. For operation-routing rules, the singleforwardto action is the only action supported (besides the general action denyreq) and defines a JSON array of LDAP target servers enclosed in square brackets [ ]. The target servers are indicated by their names and must match the name of a definition of an LDAPserver object in the same configuration file. At least one name must be present in the array (an empty array is not allowed). The first server given in the list is considered to be the primary server. The next servers are only contacted if the previous servers are unreachable and the failover key is set to 1. Avoid leading and trailing blanks in LDAP server names because they will be interpreted as part of the server names.
Operation-routing rules can also specify the denyreq action. For more information on how this action works, see “Rewriting Rules” → “Syntax Description” → “The actions Key” → “General Actions”.
-
The failover key defines how the DLP server handles the servers listed in singleforwardto when an error occurs while sending a request to the target server. If failover is set to 1 the request is sent to the next server if an error occurs with the selected target server. To change this behavior, set the failover key to 0. Now the operation will fail if the primary server fails.
-
The keepconn key defines whether (1) or not (0) the connection to the selected target server is to remain open after the operation is performed. Keeping the new connection open may be important if the operation performed was a paged search: the cookies for paged search are maintained by the servers only for the same connection, so closing a new connection that was caused by an operation-routing rule will break subsequent paged searches. Note: If keepconn is set to 1 for an operation, subsequent operations for which no other operation-routing rule is defined will use the connection that has been kept open.
Note, too, that when keepconn=1 is set and the operation governed by an operation rule succeeds, the target server that was selected by the bind operation is overlaid with the target from the operation-routing rule and therefore becomes obsolete. For more information about this behavior, see the examples in the chapter "Examples and Considerations".
Note that operation-routing rules are applied before any defined rewriting rules, so target server selection is based on the original LDAP input from the client.
How Operation-routing Rules are Processed
When a client connects to the DLP server for the first time (mostly via the bind operation), a user-routing procedure is performed that determines the target server for all operations of this user.
Target server selection is governed either by an existing user-routing rule or, if no suitable rule is found in the list of user-routing rules, by the default LB-server selection.
The result of this process is a set of 1-n target servers that are used whenever the user issues an operation that does not match an operation-routing rule; in other words, an operation-routing rule overrides the target server settings from the user-routing rule.
Thus, when an operation comes in from a user, the DLP server first determines whether there is a matching operation-routing rule and if so, uses the target servers from this rule. If there is no matching operation-routing rule, the DLP server uses the user-routing target servers as selections for forwarding the request.
When the DLP server searches for a matching operation-routing rule, it processes the operation-routing rules in the order in which they are defined in the DLP server configuration file and stops searching when it finds a match. Consequently, we recommend placing the rules with specific conditions in the configuration file before the more general ones.
For example, suppose there are two operation-routing rules ORR#1 and ORR#2:
ORR#1 (opr.req.type=search)
ORR#2 (&(opr.req.type=search)(search.req.baseObject=o=my-company))
In this example, ORR#2 should appear before ORR#1 in the DLP server configuration file, otherwise the more specific ORR#2 will never be reached, as opr.req.type=search is true for both rules but the search will stop after the first match.
Note that the same restrictions apply for operation-routing conditions as for ReqRewrite rule conditions.For example, you are not allowed to OR the opr.req.type token with other tokens, for example:
(|(opr.req.type=search)(user=cn=admin,o=my-company))
See “Rewriting Rules” → “Syntax Description” → “The condition Key” → “Using the opr.req.type Token” for more information.
Rewriting Rules
The ReqRewrite and ResRewrite rule types define rules for changing data in client requests and server responses.
Syntax Description
Request and result rewriting rules are specified as ProxyRule object definitions in the DLP server configuration file.This section describes their syntax, while the chapter “Examples and Considerations” provides several examples of their function.
The ruleType key
The ruleType key is mandatory; for rewriting rules, it determines when the DLP server is to invoke the rule. Use the string ReqRewrite for a rule to be invoked on LDAP requests. Use the string ResRewrite for a rule to be invoked on LDAP results. ReqRewrite rules are applied before the request is forwarded to an LDAP server. ResRewrite rules are applied after the result is received from the LDAP server and before it is returned to the client. Although it is syntactically allowed to have actions that operate on request parameters in ResRewrite rule types, they have no effect on the result since changing the request after the result is received does not change anything in the result for the client. Note that it is the rule condition that determines whether or not the rule is applied; the ruleType value simply determines when a rule is invoked.
The name Key
The name key is mandatory and can have any string value as long as the value is unique. The name appears in DLP server audit records to indicate which rules were applied to a specific request. We recommend using descriptive names like SetSearchSizeLimitTo500 to make it easier for offline analysis of traffic in audit records later on.
The condition Key
The condition key is mandatory and defines whether or not a rule will be applied to the running operation. For rewriting rules, a condition can be seen as a further refinement that tells the DLP server how the incoming request or received result must appear in order to be modified by one or more actions.
A simple condition can look something like this:
"(&(opr.req.type=search)(search.req.baseObject=o=my-company))"
This condition defines two sub-conditions that must both match in order to execute the rule actions:
-
opr.req.type=search
-
search.req.baseObject=o=my-company
Because the two sub-conditions are combined with a logical and (&), both must evaluate to true to create a match.
The next sections explain the syntax for condition rules in more detail.
Condition Rule Syntax
For rewriting rules and operation-routing rules, a condition rule is an LDAP assertion in the format:
token assertion value
where:
token is a predefined string that represents an LDAP PDU operation. The predefined token opr.req.type is a mandatory element of an operation-routing or a rewriting condition rule and defines the operation type for which the rule is targeted; for example, opr.req.type=search. The sections on token syntax provide more detail about how to use opr.req.type and list the predefined tokens available for use in operation-routing and rewriting rule conditions.
assertion is one of the LDAP assertion operators equal, present, substr (initial, final, any), lessorequal and greaterorequal (approx and ext_match are not supported) in LDAP filter notation syntax:
| equal | *=*value |
|---|---|
present |
=* |
initial (begins with) |
=*value ** |
final (ends with) |
=*value |
any (contains) |
=value |
lessorequal |
*⇐*value |
greaterorequal |
*>=*value |
Rule conditions follow LDAP filter semantics:
-
You can use complex combinations of and, or and not sub-filters items within a condition.
-
You can use substring values like initial, final and any as well as present items.
-
lessorequal and greaterorequal are also supported.
| Approximate and extensible filters are currently unsupported. |
The DLP server recognizes all assigned values as strings and automatically converts them to integer for comparison if necessary. For example, the DLP server automatically recognizes a condition like:
search.req.sizeLimit>=1000
as an integer with a value of 1000 when comparing the request against the condition.
| You are responsible for assigning meaningful values to the LDAP PDU components mapped by the pre-defined tokens, or undefined behavior may occur. For example, the condition definition |
search.req.baseObject=700
is not meaningful and should be avoided.
| The DLP server does not perform any syntax checking or matching rule compliance on any assigned value. The server only compares strings. Consequently, a condition like search.req.baseObject=700 will be accepted but during comparison it will be compared to the DN baseObject of the request as a string of value 700 which definitely will never match. |
Condition Token Syntax
The general token syntax for addressing a specific LDAP component in a rule condition is:
operation-type.{req|res}.component-name
where
operation-type specifies the LDAP operation (bind, search, modify, add, delete, modDN, compare)
req|res specifies whether it is targeted for the request (req) or the result (res)
component-name specifies the component name as provided in the LDAP standard RFC4511ff.
Here are some examples:
search.req.baseObject addresses the requested baseObject
search.res.attributes addresses the resulting attributes
Using the opr.req.type Token
The opr.req.type token is a special token that defines the targeted operation type (for example, a search). This token must be present in a rule condition to specify the operation type for which the rule is targeted. The absence of opr.req.type is considered to be an error.
The value for the opr.req.type token represents the necessary LDAP operations and can be one of
bind, search, modify, add, delete, modDN, compare
or “*” to indicate that the condition can match with any of the operation types. Note that the values for opr.req.type are case sensitive.
Using the OR operator to OR the opr.req.type token to other tokens in a rule condition is not allowed due to the token’s special status and function. If you want the same actions to be performed for different operation types – for example, for add or for modify – you must write separate rules for each operation type. For example, the following rule is not allowed:
Condition: (|(opr.req.type=add)(opr.req.type=modify))
Action: "denyreq"
The following rules are allowed:
Condition: (opr.req.type=add)
Action: "denyreq"
Condition: (opr.req.type=modify)
Action: "denyreq"
We recommend keeping rule conditions simple, not because of easier parsing, but to keep track of the existing rules.
Condition Token Names and Assignments
The following table shows the token names and assignments that are supported for rewriting and operation-routing rule conditions. Assignments can be: E (equal), SI (substring-initial), SF (substring-final), SA (substring-any), P (present), LE (lessorequal), GE (greaterorequal):
| Token Name | Supported Assignments |
Description | ||
|---|---|---|---|---|
opr.req.type |
E, P |
The operation type for which this condition is targeted. The value must be one of bind, search, add, modify, delete, compare or modDN. If the value is “”, any operation type will match. This token is mandatory for a condition. Example: *opr.req.type=search. |
||
user |
E, SI, SA, SF, P |
The user for which the condition is targeted. The user-name is determined by the last successful bind operation or is “anonymous” if no successful authenticated bind was performed. The value must be a legal LDAP distinguished name of a user; for example: cn=richter,ou=sales,o=my-company. If the value is “”, any user will match. If the value is “anonymous”, the unauthenticated user will match. Example: *user=*cn=admin* (any user that has cn=admin in its name). |
||
ip |
E |
The IP address for which the condition is targeted. The IP is expected to be a valid IPv4 address; for example, 111.22.33.76. If the value is “...”, any IP address will match. You can also specify subnet IP ranges like ip=192.33..** which evaluates the condition to match for all IP addresses from the B-subnet 192.33. Only IPv4 addresses are currently supported. |
||
security |
E |
The security level of the operation to be processed. Possible values are plain or tls. |
||
bind.req.name |
E, SI, SA, SF,P |
The string value that must be present in the bind- DN. If the value is “”, any DN will match except anonymous users. If the value is “anonymous”, the unauthenticated user will match. This token is very similar to the *user token except that this one is only allowed for bind operations. Example: bind.req.name=*o=my-company* matches to all bind requests for users with a component o=my-company in their bind-DN name; that is, it matches to users like cn=admin,o=my-company or cn=richter,ou=sales,o=my-company but not to cn=admin,o=pqr. |
||
search.req.baseObject |
E, SI, SA, SF,P |
The baseObject that must be present in an incoming search request to match the condition. The baseObject must be specified as a legal LDAP DN; for example, search.req.baseObject=ou=sales,o=my-company. The value can also be a substring of a DN; for example, o=my-comp* which matches to a baseObject o=my-company via an INITIAL substring match. You can also use FINAL and CONTAINS substrings. |
||
search.req.scope |
E |
The scope that must be present in an incoming search request to match the condition. The value must be one of
This token is only applicable to search operations. |
||
search.req.sizeLimit |
E, LE, GE |
The sizeLimit value that must be present in an incoming search request to match the condition. The assigned value can either be an equal, lessorequal or greaterorequal assignment; for example, search.req.sizeLimit>=1000. The assigned string (here, 1000) is automatically converted and compared to the integer value of sizeLimit in the incoming LDAP PDU. |
||
search.req.timeLimit |
E, LE, GE |
The timeLimit value that must be present in an incoming search request to match the condition. The assigned value can either be an equal, lessorequal or greaterorequal assignment; for example, search.req.timeLimit⇐1. The assigned string (here, 1) is automatically converted and compared to the integer value of timeLimit in the incoming LDAP PDU. |
||
search.req.attributes |
E |
The name of a requested attribute that must be present in an incoming search request to match the condition. The assigned value must be a legal LDAP attribute name. Multiple attribute names must be added to the condition by adding another AND item, for example, (&(search.req.attributes=street)(search.req.attributes=sn)), which evaluates to true if the incoming search contains both street and sn in the list of requested attributes.
|
||
search.req.control |
E |
The LDAPV3 control that must be present in the incoming search request. Possible values are simplePagedResult or serverSideSorting. These values can be abbreviated to PR and SSS. |
||
modify.req.object |
E, SI, SA, SF |
The name of the target entry that must be present in the incoming request. The assigned value must be a legal LDAP DN; for example: modify.req.object=cn=richter,ou=sales,o=pqr. The assigned value can also consist of a combination of one or more substrings; for example, modify.req.object=*richter* or modify.req.object=cn*abele*o=pqr which evaluate to a filter expression of three substrings: This condition means that the incoming target entry name of the modification must begin with cn, must contain the substring abele and must end with o=pqr. The condition will evaluate to true only if all three conditions match. |
||
add.req.entry |
E, SI, SA, SF |
The name of the target entry that must be present in the incoming request. The assigned value must be a legal LDAP DN; for example: add.req.entry=cn=richter,ou=sales,o=pqr The assigned value can also consist of a combination of one or more substrings; for example: add.req.entry=*richter* or add.req.entry=cn*abele*o=pqr |
||
delete.req.entry |
E, SI, SA, SF |
The name of the target entry that must be present in the incoming request. The assigned value must be a legal LDAP DN; for example: delete.req.entry=cn=richter,ou=sales,o=pqr. The assigned value can also consist of a combination of one or more substrings; for example: delete.req.entry=*richter* or delete.req.entry=cn*abele*o=pqr* |
||
modDN.req.entry |
E, SI, SA, SF |
The name of the target entry that must be present in the incoming request. The assigned value must be a legal LDAP DN; for example: delete.req.entry=cn=richter,ou=sales,o=pqr The assigned value can also consist of a combination of one or more substrings; for example: delete.req.entry=*richter* or delete.req.entry=cn*abele*o=pqr |
||
compare.req.entry |
E, SI, SA, SF |
The name of the target entry that must be present in the incoming request. The assigned value must be a legal LDAP DN; for example: delete.req.entry=cn=richter,ou=sales,o=pqr The assigned value may also consist of a combination of one or more substrings, e.g. delete.req.entry=*richter* or delete.req.entry=cn*abele*o=pqr* |
||
compare.req.attr |
E |
The name of the attribute in the incoming request that is to be compared. |
| LDAP search filters cannot be configured as conditions for proxy rules. |
The actions Key
Actions operate on the request or the result. Actions can be general (for example, to reject the entire request) or they can be specific to the LDAP PDU components (for example, to change the baseObject of an incoming search request).
A general action is described by a simple token like denyreq while a protocol-specific action has a more complex syntax described in this section.
Every proxy rule can have 1-n actions. If multiple actions are defined for a rule, they are executed in the order in which they are defined within the rule (top-down). The input for a subsequent action is the result of the all previous actions performed and not the original request, that is
OriginalReq → Action1 → ChangedReq1 → Action2 → ChangedReq2 → …..
Consequently, when you are defining multiple actions in a rule, make sure that each action definition considers the actions that precede it.
General Actions
The only general action currently supported for all rule types is denyreq, which rejects the incoming request with an UNWILLING_TO_PERFORM error. The operation is not forwarded to any LDAP server. The DLP server stops its processing operation when it detects a denyreq action within a sequence of actions. Be careful when using the denyreq action with general conditions. For example, consider the following condition/action pair:
condition : (&(opr.req.type=)(user=))
action : denyreq
This combination effectively locks out all users and all operations from the server.
Protocol-Specific Actions
Rewriting rules can specify protocol-specific actions to execute rewriting operations on specific LDAP components within a request or result. The first three elements of a protocol-specific action definition specify the component to be modified and mirror the condition rule syntax. The fourth element is the action to be performed (for example, replace) and the last three elements are the necessary parameters for the action.
Protocol-Specific Action Syntax
The general token syntax for addressing a specific LDAP component in a rule condition is:
operation-type.\{req|res}.component-name.action(parameter1, parameter2, parameter3)
where
operation-type specifies the LDAP operation (bind, search, modify, add, delete, modDN, compare)
req|res specifies whether it is targeted for the request (req) or the result (res)
component-name specifies the component name as provided in the LDAP standard RFC4511ff.
action is a string that specifies the operation to be performed on the component and can be one of:
-
replace – exchange an existing value with a new one (note that wildcard (*) replacements are not supported)
-
add – add new value to the existing values
-
delete – delete an existing value
-
clear – remove either all values of an attribute or all values
-
set – set a single value – existing values are lost
-
hide – hide a resulting entry from a search result
-
showonly – show only a list of attributes
| Not all actions are possible for all LDAP components; for example, an add operation on a baseObject is not possible. Also note that only the following LDAP controls can be added: |
-
LDAP_CTRL_SESSION_ID 1.3.6.1.4.1.21008.108.63.1
-
LDAP_CTRL_RELAXED_UPD 1.3.12.2.1107.1.3.2.12.5
The rewriting of LDAP controls (for example, changing attribute names in server-side-sorting) is currently not supported.
parameter1, parameter2 and parameter3 are action parameters that may be necessary to fulfill a specific rewriting operation and can be one of the following values:
-
The string NULL, which indicates that the parameter is not used.
-
An assignment string in the format type*=value; for example, *cn=smith
-
A plain string; for example, objectClass
-
An integer; for example, 700
The required syntax for these parameters depends on the specific action and on the intended change to be applied. See the tables “Tokens for Actions on Requests” and “Tokens for Actions on Results” for complete details about which parameter must be set for a specific action. If a parameter is not of use for an action, the NULL string must be specified. (You can use the NullParamStr key in the Defaults object to change the string to be used for unused parameters to something other than NULL. See the section "The Defaults Object" for details.)
Do not enter unnecessary blanks before or after the enclosing parentheses and before or after the comma. If parameter1, parameter2 or parameter3 is an assignment (for example, cn=abele), do not enter blanks on either side of the equal sign because they will be interpreted as part of the value and may therefore generate undesired results.
Here is an example of an action definition:
search.req.baseObject.replace(o=pqr,o=my-company,NULL)
In this example, parameter1 o=pqr indicates to the action (replace) that an incoming baseObject o=pqr is to be replaced by a new value of o=my-company in a search request. You are responsible for defining meaningful actions; for example, defining baseObject rewriting actions for operations other than search should be avoided.
The DLP server ignores anything beyond the first closing parenthesis “)” in an action string; for example, in search.req.baseObject.replace(cn=a,,NULL)), the extra close parenthesis “)” is ignored.
Tokens for Actions on Requests
The following table shows the supported tokens and actions for request rewriting:
| Token Name | Action | P1 | P2 | P3 | Description |
|---|---|---|---|---|---|
bind.req.name |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P! in the binder’s distinguished name (DN). |
search.req.baseObject |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with pattern specified by P2 in the baseObject of the search request. Example: with P1: ou=sales and P2: ou=NewSales, an incoming baseObject cn=richter,ou=sales,o=pqr is modified to cn=richter,ou=NewSales,o=pqr. If P2 is an empty string, the pattern P1 is removed from the original baseObject DN. |
set |
New LDAP DN |
NULL |
NULL |
Replaces the existing baseObject DN with the one given by P1. |
|
search.req.attributes |
del |
Attribute name. Example: cn. |
NULL |
NULL |
Removes the attribute (for example, cn) specified by P1 from the list of requested attributes. |
replace |
Old attribute name. Example: strasse. |
New attribute name. Example:*street*. |
NULL |
Renames an existing attribute whose name is specified by P1 with the name specified by P2 in the requested attributes list. |
|
add |
Attribute name. Ex:*cn*. |
NULL |
NULL |
Adds a new attribute (specified by P1) to the list of requested attributes. |
|
set |
NULL |
NULL |
NULL |
Empties the list of requested attributes; that is, no attributes will be returned. |
|
replace |
Old attribute name. Example: road. |
New attribute name. Example: street. |
NULL |
Replaces an existing attribute type name (P1) with a new attribute type name (P2) in the filter. |
|
search.req.filter |
replace |
Attribute name. Example: member. |
Old string pattern. Example: o=pqr. |
New string pattern Example:*o=my-company*. |
Replaces a substring in the filter value of an attribute specified by P1. The old substring (P2) is replaced with the new substring (P3). If P1 is “”, the replacement is made in any existing attribute-value independent of the attribute type. Both patterns (old and new) must not contain the character “**”. |
search.req.sizeLimit |
set |
New limit. Example: 100. |
NULL |
NULL |
Sets sizeLimit of the search request to the value specified by P1. |
search.req.timeLimit |
set |
New limit. Example: 300. |
NULL |
NULL |
Sets timeLimit of the search request to the value specified by P1. |
*.req.controls |
add |
Symbolic name or OID of control to be added. |
NULL |
NULL |
Adds a well-defined LDAPv3 control specified by P1 to the current operation. Controls that already exist in the incoming request are not touched. The control has the criticality set to TRUE. |
modify.req.object |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern given by P2 in the target entry DN of the. Example: with P1: ou=sales and P2: ou=NewSales, an incoming target entry cn=richter,ou=sales,o=pqr is modified to cn=richter,ou=NewSales,o=pqr. |
modify.req.object |
add |
Attribute name. Example: cn. |
Assertion value. Example: Digger. |
NULL |
Adds the attribute specified by P1 to the incoming list of attribute values to be added in the target entry. If no incoming list exists, a new list is created containing the attribute from P1. |
modify.req.changes_add |
del |
Attribute name. Example: cn. |
Assertion value. Example: Digger. |
NULL |
Removes the given attribute value (P2) of the attribute specified by P1 from the incoming list of attribute values to be added in the target entry. If the value does not exist in the list, no action is performed. If the value to be removed is the only value of the attribute in the list, the entire list is removed. |
del |
Attribute name. Example:*cn*. |
NULL |
NULL |
Removes the attribute specified by P1 (including all of its values) from the incoming list of attribute values to be added in the target entry. If the attribute does not exist in the list, no action is performed. |
|
replace |
Old attribute name. Example:*cn*. |
New attribute name. Example: mycn. |
NULL |
Renames the attribute type specified by P1 with the new name specified in P2 in the incoming list of attributes to be added to the target entry. If the old name does not exist, no action is performed. The values of the attribute in the list are not affected. |
|
replace |
Attribute name. Example: member. |
Old string pattern |
New string |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr. By defining P1 as member and P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr. Multiple replaces within the same value are supported. The replace is made to all values of the same attribute specified by P1. If P1 is “*”, the replacement is made to all values for all existing attributes. |
|
clear |
NULL |
NULL |
NULL |
Removes all attributes and all values from the incoming list of attributes to be added in the target entry. The incoming lists for attributes to be deleted or replaced are not touched. |
|
add |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Adds the given attribute value (P2) to the attribute specified by P1 to the incoming list of attribute values to be deleted in the target entry. If no incoming list exists, a new list will be created containing the attribute from P1 |
|
modify.req.changes_delete |
del |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Removes the given attribute value specified by P2 for attribute P1 from the incoming list of attribute values to be deleted in the target entry. If the value does not exist in the list, no action is performed. If the value to be removed is the only value of the attribute in the list, the entire list will be removed. |
del |
Attribute name. Example: cn. |
NULL |
NULL |
Removes the attribute specified by P1 (including all its values) from the incoming list of attribute values to be deleted in the target entry. If the attribute does not exist in the list, no action is performed. |
|
replace |
Old attribute name. Example: cn. |
New attribute name. Example: mycn. |
NULL |
Renames the attribute type specified by P1 with the new name specified by P2 in the incoming list of attributes to be deleted to the target entry. If the old name does not exist, no action is performed. The values of the attribute in the list are not affected. |
|
_replace |
Attribute name. Example: member. |
Old string pattern. Example: sales. |
New string pattern. Example: support. |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr. By defining P1 as member and P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr. Multiple replaces within same value are supported. The replacement is made to all values of the same attribute specified by P1. If P1 is “*”, the replacement is made to all values for all existing attributes. |
|
clear |
NULL |
NULL |
NULL |
Removes all attributes and all values from the incoming list of attributes to be deleted in the target entry. The incoming lists for attributes to be added or replaced are not touched. Please note that in LDAPv3, a modification must have at least one change present (that is, an empty list is not allowed). |
|
add |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Adds the given attribute value (P2) to the incoming list of attribute values to be replaced in the target entry for attribute P1. If no incoming list exists, a new list is created containing the attribute from P1/P2. |
|
modify.req.changes_replace |
del |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Removes the given attribute value given by P2 from the incoming list of attribute values to be replaced in the target entry for attribute P1. If the value does not exist in the list, no action is performed. If the value to be replaced is the only value of the attribute in the list, the entire list is removed. |
del |
Attribute name. Example: cn. |
NULL |
NULL |
Removes the attribute given by P1 (including all its values) from the incoming list of attribute values to be replaced in the target entry. If the attribute does not exist in the list, no action is performed. |
|
replace |
Old attribute name. Example: cn. |
New attribute name. Example: mycn. |
NULL |
Renames the attribute type given by P1 with the new name given in P2 in the incoming list of attributes to be replaced to the target entry. If the old name does not exist, no action is performed. The values of the attribute in the list are not affected. |
|
replace |
Attribute name. Example: member. |
Old string pattern. Example: sales. |
New string pattern. Example: support. |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr. By defining P1 as member and P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr Multiple replaces within same value are supported. The replacement is made to all values of the same attribute specified by P1. If P1 is “*”, the replacement is made to all values for all existing attributes. |
|
clear |
NULL |
NULL |
NULL |
Removes all attributes and all values from the incoming list of attributes to be replaced in the target entry. The incoming lists for attributes to be added or deleted are not touched. |
|
add.req.entry |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the DN to be added. Example: with P1: ou=sales and P2: ou=NewSales, an incoming DN cn=richter,ou=sales,o=pqr will be modified to cn=richter,ou=NewSales,o=pqr. |
del |
Attribute name. Example: cn. |
NULL |
NULL |
Removes all values for the attribute (example: cn) specified by P1 from the list of incoming attributes to be added in the new entry. Note: This action may cause the add operation to fail if mandatory attributes are removed. |
|
add.req.attributes |
del |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Removes the attribute value specified by P2 from the incoming list of attribute values for the attribute given by P1 in the target entry. If the value does not exist in the list, no action is performed. |
replace |
Old attribute name. Example: road. |
New attribute name. Example: street. |
Renames an existing attribute whose name is given by P1 with the name given by P2 in the list of attributes to be added. |
||
_replace |
Attribute name. Example: member. |
Old string pattern. Example: sales. |
New string pattern. Example: support. |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr. By defining P1 as member and P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr. Multiple replaces within the same value are supported. The replacement is made to all values of the same attribute specified by P1. If P1 is “*”, the replacement is made to all values for all existing attributes. |
|
add |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Adds a new value (specified by P2) to the attribute specified by P1 in the list of attributes to be added. |
|
clear |
NULL |
NULL |
NULL |
Removes all attributes and all values from the incoming list of attributes to be added in the new target entry. |
|
delete.req.entry |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the entry-DN to be renamed/moved. Example: with P1: ou=sales and P2: ou=NewSales, an incoming DN cn=richter,ou=sales,o=pqr will be modified to cn=richter,ou=NewSales,o=pqr. |
modDN.req.entry |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the DN of an incoming ModifyDN request. |
modDN.req.newrdn |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the newrdn component of an incoming ModifyDN request. |
modDN.req.newsup |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the newsuperior component of an incoming ModifyDN request. |
compare.req.entry |
replace |
Old attribute name. Example: strasse |
New attribute name. Example: street. |
NULL |
Replaces the attribute type name for the attribute to be compared specified by P1 with the one specified by P2. |
compare.req.attr |
replace |
Attribute name. Example: member. |
Old string pattern. Example:*sales*. |
New string pattern. Example: suppose. |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr. By defining P1 as member and P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr Multiple replaces within same value are supported. The replacement is made to all values of the same attribute specified by P1. If P1 is “*, the replacement is made to all values for all existing attributes. |
Tokens for Actions on Results
The following table shows all allowed/supported tokens and actions for result rewriting. Currently only result rewriting for search operations is supported.
| Token Name | Action | P1 | P2 | P | Description |
|---|---|---|---|---|---|
search.res.objectName |
replace |
Old LDAP DN pattern |
New LDAP DN pattern |
NULL |
Replaces the pattern specified by P1 with the pattern specified by P2 in the resulting entry DN. Example: P1 is ou=sales and P2 is ou=NewSales; a resulting entry cn=richter,ou=sales,o=pqr appears as cn=richter,ou=NewSales,o=pqr in the client result. |
search.res.entry |
hide |
LDAP DN pattern |
NULL |
NULL |
Hides all resulting entries if their DN matches the pattern specified in P1. |
search.res.attributes |
del |
Attribute name. Example: cn. |
NULL |
NULL |
Removes the attribute (example: cn) specified by P1 from the result (including all values). |
del |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Removes a single value (example: cn=Digger) of the attribute specified by P1 from the result. If the removed value is the only value of the attribute, the entire attribute is removed. |
|
replace |
Old attribute name. Example: strasse. |
New attribute name. Example: street. |
NULL |
Renames an existing attribute whose name is specified by P1 with the name specified by P2 in the LDAP result. |
|
replace |
Attribute name. Example: member. |
Old string pattern. Example: sales. |
New string pattern. Example: support. |
Replaces the pattern from P2 in the existing value of the attribute specified by P1 with the pattern from P3. Example: Old attribute-value: member=cn=smith,ou=sales,o=pqr By defining P1 as member, P2 as ou=sales and P3 as ou=support, the new attribute value will be: member=cn=smith,ou=support,o=pqr. Multiple replaces within same value are supported. The replacement is made to all values of the same attribute specified by P1. If P1 is “*”, the replacement is made to all values for all existing attributes. |
|
add |
Attribute name. Example: cn. |
Attribute value. Example: Digger. |
NULL |
Adds a new value specified by P2 to the attribute specified by P1 to the result. |
|
clear |
Attribute name. Example: cn. |
NULL |
NULL |
Clears all existing values of the attribute specified by P1. This action is equal to search.res.attributes.del(attr,NULL). |
|
clear |
NULL |
NULL |
NULL |
Clears all existing values of all attributes. The effect is that no attributes are returned. |
|
showonly |
List of attribute names separated by a plus-sign + Example: tn+cn+description+sn Or an attribute-list name that refers to a previously defined list of attribute names. (See “The AttributeList Objet” for details.) The attribute list name is prefixed by a @ Example @ATTRLIST1 Must be not an empty string or NULL. |
NULL |
NULL |
Removes all attributes that are not contained in P1. |
| Please be careful not to define too many search result rules as they will be applied to every resulting entry, which might be a performance issue if huge results are retrieved. |
How the Rule Processing Sequence Affects Result Rewriting Rules
As mentioned in the ProxyRule object definition description in the “Configuration” chapter, multiple proxy rules are executed in the order in which they are defined in the DLP server configuration file, and multiple actions are executed in the order in which they’re defined in the rule.
For example, let’s assume that three rules R1, R2 and R3 have been defined in the configuration file: R1 is the first rule to be defined, R2 is the second, and R3 is the third. The DLP server checks the conditions for each rule in the same order as the rule definitions:
R1 → R2 → R3
Now let’s assume that R1 defines two actions: A11 and A12 R2 defines only one action: A21 and R3 defines three actions: A31, A32, and A33. If all three rule conditions – R1, R2 and R3 - match the running operation O, the DLP server modifies the incoming operation O(in) in the following sequence to the outgoing operation O(out):
O(in) →A11 →A12 →A21 →A31 →A32 →A33 → O(out)
As shown in this example, the DLP server executes the actions on the incoming operation in the same sequence as they are presented in the configuration file.
Now let’s consider what this execution sequence means for constructing result rewriting rules, since the same execution sequence applies: the request/result input for an action is always the request/result output of its preceding action. Suppose we have the following two rules:
R1:
C1: (&(opr.req.type=search)(search.req.baseObject=o=pqr))
A1: change base object to O=my-company in the running search
R2:
C2: (&(opr.req.type=search)(search.req.baseObject=o=pqr))
A2: add an attribute cn to the list of requested attributes in the running search
It’s clear that both conditions are identical and will match to an incoming search request with baseObject o=pqr. However, because R1 is executed before R2, the action A1 will change the baseObject of the incoming request from o=pqr to o=my-company. Therefore, when R2 is processed, the rule condition is no longer true and the action A2 will never be executed.
Handling Attribute Name Aliases in Rewriting Rules
LDAP attribute names can have aliases. For example, the attribute telephonenumber has the alias tn. If you intend to apply rewrite rules to attributes that have aliases, you may need to specify multiple actions in order to cover all possible versions of an attribute name; for example:
{
"object" : "ProxyRule",
"ruleType" : "ReqRewrite",
"name" : "Test 03",
"condition" : "opr.req.type=modify",
"actions" : [ "modify.req.changes_add.del(telephoneNumber,123,NULL)",
"modify.req.changes_add.del(tn,123,NULL)" ]
}
Using Virtual Names in Rewriting Actions on Search Results
When defining rewriting rules for search results, a special problem can occur. For example, suppose there is a single rule that rewrites the search result with an action like
search.res.attributes.replace(street,road)
This action changes the name of the attribute street in all resulting entries into a virtual new name road. Therefore, the client receives the name road instead of street which is (usually) not an attribute defined in the schema. Most clients will ignore this mismatch against the schema (or simply do not even read the schema) and just display the attribute with the new virtual name road like they would display the street attribute. As long as it is only about viewing, it is (mostly) not of too much relevance as long as the client is familiar with the new name. However, problems can occur if the received virtual attribute name is used by the client for a subsequent operation (for example, modify). If road will be used in a subsequent operation and if no further rule exists, the attribute road will be transmitted to the LDAP server, which will possibly return an error due to this unknown attribute (remember: the mapping is only known to the DLP server – not to the backend servers).
Consequently, if you intend for the rewritten attribute to be re-usable by the client in subsequent operations, you need to define additional rules to perform the corresponding conversion from client to server again (for example, road to street) in order for the operation to succeed in the backend servers, which are unaware that a rewrite has occurred in the DLP server.
To support the road to street re-conversion from our example in a subsequent modify operation, it may be necessary to add other rules with actions like
modify.req.changes_add.replace(road,street)
modify.req.changes_delete.replace(road,street)
modify.req.changes_replace.replace(road,street)
This will do the job for modify operations if the attribute is not a naming attribute (that is, an attribute that does not appear in DNs).
To exchange the virtual name road in all possible modification operations, similar rules for other operations like add, compare may be necessary in order to translate road into street again.
| These actions must be defined in the first rules if other actions are to be present, as actions are applied sequentially in the order in which they’re defined in a rule. |
Things get more complicated if the re-written attribute may also appear in DNs (as a type of an RDN that builds up the DN).
The chapter "Result-Rewriting Considerations" provides some additional guidance for administrators on how to maintain a consistent approach to the database in subsequent calls after result rewriting takes place.
Character Set Requirements in Rule Conditions and Actions
UTF-8 is the only character encoding allowed by LDAP.However, special Latin-1 characters like the German umlaut (ä, ö, ü) may need to be used in condition and action assignments, especially in DN strings.The DLP server can convert these Latin-1 characters to their UTF-8 representation for processing by LDAP.The JSONCodeSet key in the Defaults object definition indicates to the DLP server in which character set the proxy rules in the DLP server configuration file are encoded and thus whether or not they need to be converted.Make sure that all conditions and all actions in all ProxyRule objects you define in a DLP server configuration file use the same character encoding: Latin-1 or UTF-8. Do not mix character sets within a single DLP server configuration file.See the “Configuration” chapter for more information on the Defaults and ProxyRule objects.
Handling Special Characters in Rule Conditions and Actions
Both LDAP and JSON define characters that require special handling in certain cases.The proxy rule parameter syntax also defines special characters.When a condition assignment or an action parameter needs to contain one of these special characters, the character must be converted to its hex string representation and prefixed with the # character in the proxy rule definition.
LDAP RFC4514 requires escaping the following characters when they appear in DNs:
-
A space ( U+0020) or number sign (# U+0023) that occurs at the beginning of the string
-
A space ( U+0020) character that occurs at the end of the string
-
One of the characters ", +, ,, ;, <, >, or \ (U+0022, U+002B, U+002C, U+003B, U+003C, U+003E, or U+005C, respectively)
-
The null (U+0000) character
JSON RFC4627 requires the following characters to be escaped when they appear in property names or property values:
| Special Character | Escaped Output |
|---|---|
Quotation mark (") |
\" |
Backslash (\) |
\\ |
Slash (/) |
\/ |
Backspace |
\b |
Form feed |
\f |
New line |
\n |
Carriage return |
\r |
Horizontal tab |
\t |
The proxy rule condition rule and parameter syntax requires the following characters to be escaped:
-
Open parenthesis (
-
Close parenthesis )
-
Comma ,
When you find that a condition assignment or an action parameter needs to use one of these special LDAP, JSON or proxy rule syntax characters, you must use the character’s hex string representation and prefix it with the # character.
For example, let’s assume the value James, Bond (007), which contains the special characters “,”, “(“ and “)” is to be set as a parameter. The following hex string can be used as the parameter:
#4A616D65732C20426F6E64202830303729
J a m e s , B o n d ( 0 0 7 )
The hex string consists of the hex bytes of each character in text format (J=4A, a=61, m=6D, and so on). This is the same method that LDAP allows for representing DNs that contain special or binary characters.
If a value to be added as a parameter begins with a # but does not contain any special characters, the value itself must start with another #, for example, the value #Hello There# must be represented as ##Hello There#. This extra # prefix is only necessary if the first character is a #. If the # appears at any other position, the string remains unchanged.
The parameter represented by the hex string must still obey the code-set (Latin-1 or UTF-8) from the Default object’s JSONCodeSet setting. See the Default object description in the “Configuration” chapter and the chapter “Operations” for more details.