mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-07 07:30:57 -05:00
ITS#5408 part 3 - file path tweaks, sanity checks.
- Rename temporary filename patterns from "<rdn>.ldifXXXXX" to "<rdn>.XXXXX". - Add and start using ldif2dir_len() & co.
This commit is contained in:
parent
b00aa30d37
commit
ddc0613920
1 changed files with 38 additions and 13 deletions
|
|
@ -61,11 +61,10 @@ struct ldif_info {
|
|||
* Unsafe/translated characters in the filesystem.
|
||||
*
|
||||
* LDIF_UNSAFE_CHAR(c) returns true if the character c is not to be used
|
||||
* in relative filenames, except it should accept '\\' even if unsafe and
|
||||
* need not reject '{' and '}'. The value should be a constant expression.
|
||||
* in relative filenames, except it should accept '\\', '{' and '}' even
|
||||
* if unsafe. The value should be a constant expression.
|
||||
*
|
||||
* If '\\' is unsafe, #define LDIF_ESCAPE_CHAR as a safe character.
|
||||
*
|
||||
* If '{' and '}' are unsafe, #define IX_FSL/IX_FSR as safe characters.
|
||||
* (Not digits, '-' or '+'. IX_FSL == IX_FSR is allowed.)
|
||||
*
|
||||
|
|
@ -90,7 +89,7 @@ struct ldif_info {
|
|||
#else /* _WIN32 */
|
||||
|
||||
/* Windows version - Microsoft's list of unsafe characters, except '\\' */
|
||||
#define LDIF_ESCAPE_CHAR '^'
|
||||
#define LDIF_ESCAPE_CHAR '^' /* Not '\\' (unsafe on Windows) */
|
||||
#define LDIF_UNSAFE_CHAR(c) \
|
||||
((c) == '/' || (c) == ':' || \
|
||||
(c) == '<' || (c) == '>' || (c) == '"' || \
|
||||
|
|
@ -135,6 +134,18 @@ struct ldif_info {
|
|||
(!(LDIF_UNSAFE_CHAR(x) || (x) == '\\' || (x) == IX_DNL || (x) == IX_DNR) \
|
||||
&& (c) == (x))
|
||||
|
||||
/* Collect other "safe char" tests here, until someone needs a fix. */
|
||||
enum {
|
||||
safe_filenames = STRLENOF("" LDAP_DIRSEP "") == 1 && !(
|
||||
LDIF_UNSAFE_CHAR('-') || /* for "{-1}frontend" in bconfig.c */
|
||||
LDIF_UNSAFE_CHAR(LDIF_ESCAPE_CHAR) ||
|
||||
LDIF_UNSAFE_CHAR(IX_FSL) || LDIF_UNSAFE_CHAR(IX_FSR))
|
||||
};
|
||||
/* Sanity check: Try to force a compilation error if !safe_filenames */
|
||||
typedef struct {
|
||||
int assert_safe_filenames : safe_filenames ? 2 : -2;
|
||||
} assert_safe_filenames[safe_filenames ? 2 : -2];
|
||||
|
||||
|
||||
#define ENTRY_BUFF_INCREMENT 500
|
||||
|
||||
|
|
@ -159,6 +170,10 @@ static ConfigOCs ldifocs[] = {
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
* Handle file/directory names.
|
||||
*/
|
||||
|
||||
/* Set *res = LDIF filename path for the normalized DN */
|
||||
static void
|
||||
dn2path( BackendDB *be, struct berval *dn, struct berval *res )
|
||||
|
|
@ -218,12 +233,19 @@ dn2path( BackendDB *be, struct berval *dn, struct berval *res )
|
|||
assert( res->bv_len <= len );
|
||||
}
|
||||
|
||||
/* .ldif entry filename length <-> subtree dirname length. */
|
||||
#define ldif2dir_len(bv) ((bv).bv_len -= STRLENOF(LDIF))
|
||||
#define dir2ldif_len(bv) ((bv).bv_len += STRLENOF(LDIF))
|
||||
/* .ldif entry filename <-> subtree dirname, both with dirname length. */
|
||||
#define ldif2dir_name(bv) ((bv).bv_val[(bv).bv_len] = '\0')
|
||||
#define dir2ldif_name(bv) ((bv).bv_val[(bv).bv_len] = LDIF_FILETYPE_SEP)
|
||||
|
||||
/* Make temporary filename pattern for mkstemp() based on dnpath. */
|
||||
static char *
|
||||
ldif_tempname( const struct berval *dnpath )
|
||||
{
|
||||
static const char suffix[] = "XXXXXX";
|
||||
ber_len_t len = dnpath->bv_len;
|
||||
static const char suffix[] = ".XXXXXX";
|
||||
ber_len_t len = dnpath->bv_len - STRLENOF( LDIF );
|
||||
char *name = SLAP_MALLOC( len + sizeof( suffix ) );
|
||||
|
||||
if ( name != NULL ) {
|
||||
|
|
@ -1096,7 +1118,6 @@ ldif_back_delete( Operation *op, SlapReply *rs )
|
|||
struct ldif_info *li = (struct ldif_info *) op->o_bd->be_private;
|
||||
struct berval path;
|
||||
int rc = LDAP_SUCCESS;
|
||||
int res = 0;
|
||||
|
||||
if ( BER_BVISEMPTY( &op->o_csn )) {
|
||||
struct berval csn;
|
||||
|
|
@ -1110,10 +1131,9 @@ ldif_back_delete( Operation *op, SlapReply *rs )
|
|||
ldap_pvt_thread_rdwr_wlock(&li->li_rdwr);
|
||||
|
||||
dn2path( op->o_bd, &op->o_req_ndn, &path );
|
||||
path.bv_val[path.bv_len - STRLENOF(LDIF)] = '\0';
|
||||
res = rmdir(path.bv_val);
|
||||
path.bv_val[path.bv_len - STRLENOF(LDIF)] = LDIF_FILETYPE_SEP;
|
||||
if ( res ) {
|
||||
ldif2dir_len( path );
|
||||
ldif2dir_name( path );
|
||||
if ( rmdir( path.bv_val ) < 0 ) {
|
||||
switch ( errno ) {
|
||||
case ENOTEMPTY:
|
||||
rc = LDAP_NOT_ALLOWED_ON_NONLEAF;
|
||||
|
|
@ -1129,8 +1149,8 @@ ldif_back_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
res = unlink(path.bv_val);
|
||||
if ( res == -1 ) {
|
||||
dir2ldif_name( path );
|
||||
if ( unlink( path.bv_val ) < 0 ) {
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
if ( errno != ENOENT ) {
|
||||
rc = LDAP_OTHER;
|
||||
|
|
@ -1139,6 +1159,11 @@ ldif_back_delete( Operation *op, SlapReply *rs )
|
|||
}
|
||||
}
|
||||
|
||||
if ( rc == LDAP_OTHER ) {
|
||||
Debug( LDAP_DEBUG_ANY, "ldif_back_delete: %s \"%s\": %s\n",
|
||||
"cannot delete", path.bv_val, STRERROR( errno ) );
|
||||
}
|
||||
|
||||
SLAP_FREE(path.bv_val);
|
||||
ldap_pvt_thread_rdwr_wunlock(&li->li_rdwr);
|
||||
rs->sr_err = rc;
|
||||
|
|
|
|||
Loading…
Reference in a new issue