mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-12 15:10:31 +08:00
allow memory ownership specification when using (session- wide) variables
This commit is contained in:
parent
43f5b50319
commit
e9314574aa
@ -74,6 +74,30 @@
|
||||
#define REWRITE_REGEXEC_STOP 0x0002
|
||||
#define REWRITE_REGEXEC_UNWILLING 0x0004
|
||||
|
||||
/*
|
||||
* Rewrite variable flags
|
||||
* REWRITE_VAR_INSERT insert mode (default) when adding
|
||||
* a variable; if not set during value
|
||||
* update, the variable is not inserted
|
||||
* if not present
|
||||
* REWRITE_VAR_UPDATE update mode (default) when updating
|
||||
* a variable; if not set during insert,
|
||||
* the value is not updated if the
|
||||
* variable already exists
|
||||
* REWRITE_VAR_COPY_NAME copy the variable name; if not set,
|
||||
* the name is not copied; be sure the
|
||||
* referenced string is available for
|
||||
* the entire life scope of the variable.
|
||||
* REWRITE_VAR_COPY_VALUE copy the variable value; if not set,
|
||||
* the value is not copied; be sure the
|
||||
* referenced string is available for
|
||||
* the entire life scope of the variable.
|
||||
*/
|
||||
#define REWRITE_VAR_INSERT 0x0001
|
||||
#define REWRITE_VAR_UPDATE 0x0002
|
||||
#define REWRITE_VAR_COPY_NAME 0x0004
|
||||
#define REWRITE_VAR_COPY_VALUE 0x0008
|
||||
|
||||
/*
|
||||
* Rewrite info
|
||||
*/
|
||||
@ -177,13 +201,18 @@ rewrite_session_init(
|
||||
* Defines and inits a variable with session scope
|
||||
*/
|
||||
LDAP_REWRITE_F (int)
|
||||
rewrite_session_var_set(
|
||||
rewrite_session_var_set_f(
|
||||
struct rewrite_info *info,
|
||||
const void *cookie,
|
||||
const char *name,
|
||||
const char *value
|
||||
const char *value,
|
||||
int flags
|
||||
);
|
||||
|
||||
#define rewrite_session_var_set(info, cookie, name, value) \
|
||||
rewrite_session_var_set_f((info), (cookie), (name), (value), \
|
||||
REWRITE_VAR_INSERT|REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
|
||||
|
||||
/*
|
||||
* Deletes a session
|
||||
*/
|
||||
|
@ -248,6 +248,7 @@ struct rewrite_session {
|
||||
*/
|
||||
struct rewrite_var {
|
||||
char *lv_name;
|
||||
int lv_flags;
|
||||
struct berval lv_value;
|
||||
};
|
||||
|
||||
@ -459,11 +460,12 @@ rewrite_session_find(
|
||||
* Defines and inits a variable with session scope
|
||||
*/
|
||||
LDAP_REWRITE_F (int)
|
||||
rewrite_session_var_set(
|
||||
rewrite_session_var_set_f(
|
||||
struct rewrite_info *info,
|
||||
const void *cookie,
|
||||
const char *name,
|
||||
const char *value
|
||||
const char *value,
|
||||
int flags
|
||||
);
|
||||
|
||||
/*
|
||||
@ -508,27 +510,46 @@ rewrite_var_find(
|
||||
const char *name
|
||||
);
|
||||
|
||||
/*
|
||||
* Replaces the value of a variable
|
||||
*/
|
||||
LDAP_REWRITE_F (int)
|
||||
rewrite_var_replace(
|
||||
struct rewrite_var *var,
|
||||
const char *value,
|
||||
int flags
|
||||
);
|
||||
|
||||
/*
|
||||
* Inserts a newly created var
|
||||
*/
|
||||
LDAP_REWRITE_F (struct rewrite_var *)
|
||||
rewrite_var_insert(
|
||||
rewrite_var_insert_f(
|
||||
Avlnode **tree,
|
||||
const char *name,
|
||||
const char *value
|
||||
const char *value,
|
||||
int flags
|
||||
);
|
||||
|
||||
#define rewrite_var_insert(tree, name, value) \
|
||||
rewrite_var_insert_f((tree), (name), (value), \
|
||||
REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE)
|
||||
|
||||
/*
|
||||
* Sets/inserts a var
|
||||
*/
|
||||
LDAP_REWRITE_F (struct rewrite_var *)
|
||||
rewrite_var_set(
|
||||
rewrite_var_set_f(
|
||||
Avlnode **tree,
|
||||
const char *name,
|
||||
const char *value,
|
||||
int insert
|
||||
int flags
|
||||
);
|
||||
|
||||
#define rewrite_var_set(tree, name, value, insert) \
|
||||
rewrite_var_set_f((tree), (name), (value), \
|
||||
REWRITE_VAR_UPDATE|REWRITE_VAR_COPY_NAME|REWRITE_VAR_COPY_VALUE|((insert)? REWRITE_VAR_INSERT : 0))
|
||||
|
||||
/*
|
||||
* Deletes a var tree
|
||||
*/
|
||||
|
@ -185,11 +185,12 @@ rewrite_session_return(
|
||||
* Defines and inits a var with session scope
|
||||
*/
|
||||
int
|
||||
rewrite_session_var_set(
|
||||
rewrite_session_var_set_f(
|
||||
struct rewrite_info *info,
|
||||
const void *cookie,
|
||||
const char *name,
|
||||
const char *value
|
||||
const char *value,
|
||||
int flags
|
||||
)
|
||||
{
|
||||
struct rewrite_session *session;
|
||||
@ -212,11 +213,11 @@ rewrite_session_var_set(
|
||||
var = rewrite_var_find( session->ls_vars, name );
|
||||
if ( var != NULL ) {
|
||||
assert( var->lv_value.bv_val != NULL );
|
||||
free( var->lv_value.bv_val );
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
var->lv_value.bv_len = strlen( value );
|
||||
|
||||
(void)rewrite_var_replace( var, value, flags );
|
||||
|
||||
} else {
|
||||
var = rewrite_var_insert( &session->ls_vars, name, value );
|
||||
var = rewrite_var_insert_f( &session->ls_vars, name, value, flags );
|
||||
if ( var == NULL ) {
|
||||
#ifdef USE_REWRITE_LDAP_PVT_THREADS
|
||||
ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
|
||||
|
@ -65,6 +65,39 @@ rewrite_var_dup(
|
||||
return ( strcasecmp( v1->lv_name, v2->lv_name ) == 0 ? -1 : 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a var
|
||||
*/
|
||||
static void
|
||||
rewrite_var_free(
|
||||
void *v_var
|
||||
)
|
||||
{
|
||||
struct rewrite_var *var = v_var;
|
||||
assert( var != NULL );
|
||||
|
||||
assert( var->lv_name != NULL );
|
||||
assert( var->lv_value.bv_val != NULL );
|
||||
|
||||
if ( var->lv_flags & REWRITE_VAR_COPY_NAME )
|
||||
free( var->lv_name );
|
||||
if ( var->lv_flags & REWRITE_VAR_COPY_VALUE )
|
||||
free( var->lv_value.bv_val );
|
||||
free( var );
|
||||
}
|
||||
|
||||
/*
|
||||
* Deletes a var tree
|
||||
*/
|
||||
int
|
||||
rewrite_var_delete(
|
||||
Avlnode *tree
|
||||
)
|
||||
{
|
||||
avl_free( tree, rewrite_var_free );
|
||||
return REWRITE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds a var
|
||||
*/
|
||||
@ -83,51 +116,112 @@ rewrite_var_find(
|
||||
( caddr_t )&var, rewrite_var_cmp );
|
||||
}
|
||||
|
||||
int
|
||||
rewrite_var_replace(
|
||||
struct rewrite_var *var,
|
||||
const char *value,
|
||||
int flags
|
||||
)
|
||||
{
|
||||
ber_len_t len = strlen( value );
|
||||
|
||||
if ( var->lv_flags & REWRITE_VAR_COPY_VALUE ) {
|
||||
if ( flags & REWRITE_VAR_COPY_VALUE ) {
|
||||
if ( len <= var->lv_value.bv_len ) {
|
||||
AC_MEMCPY(var->lv_value.bv_val, value, len + 1);
|
||||
|
||||
} else {
|
||||
free( var->lv_value.bv_val );
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
}
|
||||
|
||||
} else {
|
||||
free( var->lv_value.bv_val );
|
||||
var->lv_value.bv_val = (char *)value;
|
||||
var->lv_flags &= ~REWRITE_VAR_COPY_VALUE;
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( flags & REWRITE_VAR_COPY_VALUE ) {
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
var->lv_flags |= REWRITE_VAR_COPY_VALUE;
|
||||
|
||||
} else {
|
||||
var->lv_value.bv_val = (char *)value;
|
||||
}
|
||||
}
|
||||
|
||||
var->lv_value.bv_len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts a newly created var
|
||||
*/
|
||||
struct rewrite_var *
|
||||
rewrite_var_insert(
|
||||
rewrite_var_insert_f(
|
||||
Avlnode **tree,
|
||||
const char *name,
|
||||
const char *value
|
||||
const char *value,
|
||||
int flags
|
||||
)
|
||||
{
|
||||
struct rewrite_var *var;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
assert( tree != NULL );
|
||||
assert( name != NULL );
|
||||
assert( value != NULL );
|
||||
|
||||
var = calloc( sizeof( struct rewrite_var ), 1 );
|
||||
if ( var == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
memset( var, 0, sizeof( struct rewrite_var ) );
|
||||
var->lv_name = strdup( name );
|
||||
if ( var->lv_name == NULL ) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
if ( var->lv_value.bv_val == NULL ) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
var->lv_value.bv_len = strlen( value );
|
||||
rc = avl_insert( tree, ( caddr_t )var,
|
||||
rewrite_var_cmp, rewrite_var_dup );
|
||||
if ( rc != 0 ) {
|
||||
var = rewrite_var_find( *tree, name );
|
||||
if ( var != NULL ) {
|
||||
if ( flags & REWRITE_VAR_UPDATE ) {
|
||||
(void)rewrite_var_replace( var, value, flags );
|
||||
goto cleanup;
|
||||
}
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
var = calloc( sizeof( struct rewrite_var ), 1 );
|
||||
if ( var == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( var, 0, sizeof( struct rewrite_var ) );
|
||||
|
||||
if ( flags & REWRITE_VAR_COPY_NAME ) {
|
||||
var->lv_name = strdup( name );
|
||||
if ( var->lv_name == NULL ) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
var->lv_flags |= REWRITE_VAR_COPY_NAME;
|
||||
|
||||
} else {
|
||||
var->lv_name = (char *)name;
|
||||
}
|
||||
|
||||
if ( flags & REWRITE_VAR_COPY_VALUE ) {
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
if ( var->lv_value.bv_val == NULL ) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
var->lv_flags |= REWRITE_VAR_COPY_VALUE;
|
||||
|
||||
} else {
|
||||
var->lv_value.bv_val = (char *)value;
|
||||
}
|
||||
var->lv_value.bv_len = strlen( value );
|
||||
rc = avl_insert( tree, ( caddr_t )var,
|
||||
rewrite_var_cmp, rewrite_var_dup );
|
||||
|
||||
cleanup:;
|
||||
if ( rc != 0 ) {
|
||||
free( var->lv_name );
|
||||
free( var->lv_value.bv_val );
|
||||
free( var );
|
||||
if ( rc != 0 && var ) {
|
||||
avl_delete( tree, ( caddr_t )var, rewrite_var_cmp );
|
||||
rewrite_var_free( var );
|
||||
var = NULL;
|
||||
}
|
||||
|
||||
@ -138,11 +232,11 @@ cleanup:;
|
||||
* Sets/inserts a var
|
||||
*/
|
||||
struct rewrite_var *
|
||||
rewrite_var_set(
|
||||
rewrite_var_set_f(
|
||||
Avlnode **tree,
|
||||
const char *name,
|
||||
const char *value,
|
||||
int insert
|
||||
int flags
|
||||
)
|
||||
{
|
||||
struct rewrite_var *var;
|
||||
@ -153,50 +247,19 @@ rewrite_var_set(
|
||||
|
||||
var = rewrite_var_find( *tree, name );
|
||||
if ( var == NULL ) {
|
||||
if ( insert ) {
|
||||
return rewrite_var_insert( tree, name, value );
|
||||
if ( flags & REWRITE_VAR_INSERT ) {
|
||||
return rewrite_var_insert_f( tree, name, value, flags );
|
||||
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
assert( var->lv_value.bv_val != NULL );
|
||||
|
||||
free( var->lv_value.bv_val );
|
||||
var->lv_value.bv_val = strdup( value );
|
||||
var->lv_value.bv_len = strlen( value );
|
||||
(void)rewrite_var_replace( var, value, flags );
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees a var
|
||||
*/
|
||||
static void
|
||||
rewrite_var_free(
|
||||
void *v_var
|
||||
)
|
||||
{
|
||||
struct rewrite_var *var = v_var;
|
||||
assert( var != NULL );
|
||||
|
||||
assert( var->lv_name != NULL );
|
||||
assert( var->lv_value.bv_val != NULL );
|
||||
|
||||
free( var->lv_name );
|
||||
free( var->lv_value.bv_val );
|
||||
free( var );
|
||||
}
|
||||
|
||||
/*
|
||||
* Deletes a var tree
|
||||
*/
|
||||
int
|
||||
rewrite_var_delete(
|
||||
Avlnode *tree
|
||||
)
|
||||
{
|
||||
avl_free( tree, rewrite_var_free );
|
||||
return REWRITE_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user