From 122d5b7329797dbb53df88dc9a8e9a628f874965 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Feb 09 2010 21:27:55 +0000 Subject: Check DN syntax in backend add, delete, modify and modrdn Back porting a bug fix from the subtree rename change (b5e653a844af60596f9bc6b16349ee902ddb51f5). --- diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index fa53e05..95a93cc 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -73,7 +73,7 @@ ldbm_back_add( Slapi_PBlock *pb ) struct ldbminfo *li; ldbm_instance *inst; char *dn = NULL; - Slapi_Entry *e; + Slapi_Entry *e = NULL; struct backentry *tombstoneentry = NULL; struct backentry *addingentry = NULL; struct backentry *parententry = NULL; @@ -189,6 +189,17 @@ ldbm_back_add( Slapi_PBlock *pb ) if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY)) { slapi_pblock_get( pb, SLAPI_ADD_TARGET, &dn ); + if (NULL == dn) + { + goto error_return; + } + ldap_result_code = slapi_dn_syntax_check(pb, dn, 1); + if (ldap_result_code) + { + ldap_result_code = LDAP_INVALID_DN_SYNTAX; + slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); + goto error_return; + } slapi_sdn_set_dn_byref(&sdn, dn); slapi_sdn_get_backend_parent(&sdn,&parentsdn,pb->pb_backend); /* Check if an entry with the intended DN already exists. */ @@ -196,6 +207,11 @@ ldbm_back_add( Slapi_PBlock *pb ) addr.dn = dn; addr.uniqueid = NULL; ldap_result_code= get_copy_of_entry(pb, &addr, &txn, SLAPI_ADD_EXISTING_DN_ENTRY, !is_replicated_operation); + if(ldap_result_code==LDAP_OPERATIONS_ERROR || + ldap_result_code==LDAP_INVALID_DN_SYNTAX) + { + goto error_return; + } } /* if we can find the parent by dn or uniqueid, and the operation has requested the parent then get it */ @@ -622,6 +638,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } if(is_resurect_operation) @@ -641,6 +659,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } retval = index_addordel_string(be,SLAPI_ATTR_UNIQUEID,slapi_entry_get_uniqueid(addingentry->ep_entry),addingentry->ep_id,BE_INDEX_DEL,&txn); @@ -658,6 +678,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } retval = index_addordel_string(be,SLAPI_ATTR_NSCP_ENTRYDN,slapi_sdn_get_ndn(&sdn),addingentry->ep_id,BE_INDEX_DEL,&txn); @@ -675,6 +697,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } } @@ -701,6 +725,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } if (parent_found) { @@ -721,6 +747,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } } @@ -746,6 +774,8 @@ ldbm_back_add( Slapi_PBlock *pb ) goto diskfull_return; } ldap_result_code= LDAP_OPERATIONS_ERROR; + retry_count = RETRY_TIMES; /* otherwise, the transaction may not + be aborted */ goto error_return; } } @@ -833,8 +863,10 @@ error_return: disk_full = 1; } - /* It is specifically OK to make this call even when no transaction was in progress */ - dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + /* It is safer not to abort when the transaction is not started. */ + if (retry_count > 0) { + dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + } diskfull_return: if (disk_full) diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c index 74d8de8..fdccc0f 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c @@ -49,7 +49,7 @@ int ldbm_back_delete( Slapi_PBlock *pb ) { backend *be; - ldbm_instance *inst; + ldbm_instance *inst = NULL; struct ldbminfo *li = NULL; struct backentry *e = NULL; struct backentry *tombstone = NULL; @@ -63,7 +63,7 @@ ldbm_back_delete( Slapi_PBlock *pb ) int disk_full = 0; int parent_found = 0; modify_context parent_modify_c = {0}; - int rc; + int rc = 0; int ldap_result_code= LDAP_SUCCESS; char *ldap_result_message= NULL; Slapi_DN sdn; @@ -99,6 +99,18 @@ ldbm_back_delete( Slapi_PBlock *pb ) slapi_log_error (SLAPI_LOG_TRACE, "ldbm_back_delete", "enter conn=%" NSPRIu64 " op=%d\n", pb->pb_conn->c_connid, operation->o_opid); } + if (NULL == addr) + { + goto error_return; + } + ldap_result_code = slapi_dn_syntax_check(pb, addr->dn, 1); + if (ldap_result_code) + { + ldap_result_code = LDAP_INVALID_DN_SYNTAX; + slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); + goto error_return; + } + is_fixup_operation = operation_is_flag_set(operation, OP_FLAG_REPL_FIXUP); is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV); delete_tombstone_entry = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY); @@ -163,6 +175,11 @@ ldbm_back_delete( Slapi_PBlock *pb ) */ ldap_result_code= get_copy_of_entry(pb, addr, &txn, SLAPI_DELETE_EXISTING_ENTRY, !is_replicated_operation); + if(ldap_result_code==LDAP_OPERATIONS_ERROR || + ldap_result_code==LDAP_INVALID_DN_SYNTAX) + { + goto error_return; + } slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); if(plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN)==-1) { diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c index 6883d09..9324c8d 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c @@ -185,7 +185,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) backend *be; ldbm_instance *inst; struct ldbminfo *li; - struct backentry *e, *ec = NULL; + struct backentry *e = NULL, *ec = NULL; Slapi_Entry *postentry = NULL; LDAPMod **mods; Slapi_Mods smods = {0}; @@ -219,6 +219,17 @@ ldbm_back_modify( Slapi_PBlock *pb ) is_ruv = operation_is_flag_set(operation, OP_FLAG_REPL_RUV); inst = (ldbm_instance *) be->be_instance_info; + if (NULL == addr) + { + goto error_return; + } + ldap_result_code = slapi_dn_syntax_check(pb, addr->dn, 1); + if (ldap_result_code) + { + ldap_result_code = LDAP_INVALID_DN_SYNTAX; + slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); + goto error_return; + } dblayer_txn_init(li,&txn); /* The dblock serializes writes to the database, @@ -507,8 +518,10 @@ error_return: if (disk_full) rc= return_on_disk_full(li); else if (ldap_result_code != LDAP_SUCCESS) { - /* It is specifically OK to make this call even when no transaction was in progress */ - dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + if (retry_count > 0) { + /* It is safer not to abort when the transaction is not started. */ + dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + } rc= SLAPI_FAIL_GENERAL; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c index ce4c879..1873478 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c @@ -80,11 +80,11 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) IDList *children= NULL; struct backentry **child_entries= NULL; struct backentry **child_entry_copies= NULL; - Slapi_DN dn_olddn; - Slapi_DN dn_newdn; - Slapi_DN dn_newrdn; - Slapi_DN dn_newsuperiordn; - Slapi_DN dn_parentdn; + Slapi_DN dn_olddn = {0}; + Slapi_DN dn_newdn = {0}; + Slapi_DN dn_newrdn = {0}; + Slapi_DN dn_newsuperiordn = {0}; + Slapi_DN dn_parentdn = {0}; int rc; int isroot; LDAPMod **mods; @@ -202,8 +202,21 @@ ldbm_back_modrdn( Slapi_PBlock *pb ) newdn= moddn_get_newdn(pb,&dn_olddn,&dn_newrdn,&dn_newsuperiordn); slapi_sdn_set_dn_passin(&dn_newdn,newdn); new_addr.dn = (char*)slapi_sdn_get_ndn (&dn_newdn); + /* check dn syntax on newdn */ + ldap_result_code = slapi_dn_syntax_check(pb, new_addr.dn, 1); + if (ldap_result_code) + { + ldap_result_code = LDAP_INVALID_DN_SYNTAX; + slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message); + goto error_return; + } new_addr.uniqueid = NULL; ldap_result_code= get_copy_of_entry(pb, &new_addr, &txn, SLAPI_MODRDN_EXISTING_ENTRY, 0); + if(ldap_result_code==LDAP_OPERATIONS_ERROR || + ldap_result_code==LDAP_INVALID_DN_SYNTAX) + { + goto error_return; + } } if(slapi_isbitset_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY)) { @@ -819,8 +832,10 @@ error_return: } else { - /* It is specifically OK to make this call even when no transaction was in progress */ - dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + /* It is safer not to abort when the transaction is not started. */ + if (retry_count > 0) { + dblayer_txn_abort(li,&txn); /* abort crashes in case disk full */ + } retval= SLAPI_FAIL_GENERAL; }