/* * Callers should have already allocated *gerstr to hold at least * "entryLevelRights: adnvxxx\n". */ unsigned long _ger_get_entry_rights ( Slapi_PBlock *gerpb, Slapi_Entry *e, const char *subjectndn, char **gerstr, size_t *gerstrsize, size_t *gerstrcap, char **errbuf ) { unsigned long entryrights = 0; Slapi_RDN *rdn = NULL; char *rdntype = NULL; char *rdnvalue = NULL; _append_gerstr(gerstr, gerstrsize, gerstrcap, "entryLevelRights: ", NULL); slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_get_entry_rights - SLAPI_ACL_READ\n" ); if (acl_access_allowed(gerpb, e, "*", NULL, SLAPI_ACL_READ) == LDAP_SUCCESS) { /* v - view e */ entryrights |= SLAPI_ACL_READ; _append_gerstr(gerstr, gerstrsize, gerstrcap, "v", NULL); } slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_get_entry_rights - SLAPI_ACL_ADD\n" ); if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_ADD) == LDAP_SUCCESS) { /* a - add child entry below e */ entryrights |= SLAPI_ACL_ADD; _append_gerstr(gerstr, gerstrsize, gerstrcap, "a", NULL); } slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_get_entry_rights - SLAPI_ACL_DELETE\n" ); if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_DELETE) == LDAP_SUCCESS) { /* d - delete e */ entryrights |= SLAPI_ACL_DELETE; _append_gerstr(gerstr, gerstrsize, gerstrcap, "d", NULL); } if (config_get_moddn_aci()) { /* The server enforces the new MODDN aci right. * So the status 'n' is set if this right is granted. * Opposed to the legacy mode where this flag is set if * WRITE was granted on rdn attrbibute */ if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) { slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_get_entry_rights - SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn(e)); /* n - rename e */ entryrights |= SLAPI_ACL_MODDN; _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); } } else { /* * Some limitation/simplification applied here: * - The modrdn right requires the rights to delete the old rdn and * the new one. However we have no knowledge of what the new rdn * is going to be. * - In multi-valued RDN case, we check the right on * the first rdn type only for now. */ rdn = slapi_rdn_new_dn(slapi_entry_get_ndn(e)); slapi_rdn_get_first(rdn, &rdntype, &rdnvalue); if (NULL != rdntype) { slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_get_entry_rights - SLAPI_ACL_WRITE_DEL & _ADD %s\n", rdntype); if (acl_access_allowed(gerpb, e, rdntype, NULL, ACLPB_SLAPI_ACL_WRITE_DEL) == LDAP_SUCCESS && acl_access_allowed(gerpb, e, rdntype, NULL, ACLPB_SLAPI_ACL_WRITE_ADD) == LDAP_SUCCESS) { /* n - rename e */ entryrights |= SLAPI_ACL_WRITE; _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL); } } slapi_rdn_free(&rdn); } if ( entryrights == 0 ) { _append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL); } _append_gerstr(gerstr, gerstrsize, gerstrcap, "\n", NULL); return entryrights; }
Slapi_RDN *slapi_rdn_new_sdn( const Slapi_DN *sdn ) { return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn ) ); }
Slapi_RDN *slapi_rdn_new_rdn( const Slapi_RDN *fromrdn ) { return slapi_rdn_new_dn( fromrdn->bv.bv_val ); }
static int urp_add_resolve_parententry (Slapi_PBlock *pb, char *sessionid, Slapi_Entry *entry, Slapi_Entry *parententry, CSN *opcsn) { Slapi_DN *parentdn = NULL; Slapi_RDN *add_rdn = NULL; char *newdn = NULL; int ldap_rc; int rc = 0; Slapi_DN *sdn = NULL; if( is_suffix_entry (pb, entry, &parentdn) ) { /* It's OK for the suffix entry's parent to be absent */ rc= 0; PROFILE_POINT; /* Add Conflict; Suffix Entry */ goto bailout; } /* The entry is not a suffix. */ if(parententry==NULL) /* The parent entry was not found. */ { /* Create a glue entry to stand in for the absent parent */ slapi_operation_parameters *op_params; slapi_pblock_get( pb, SLAPI_OPERATION_PARAMETERS, &op_params ); ldap_rc = create_glue_entry (pb, sessionid, parentdn, op_params->p.p_add.parentuniqueid, opcsn); if ( LDAP_SUCCESS == ldap_rc ) { /* The backend code should now search for the parent again. */ rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY); rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY); PROFILE_POINT; /* Add Conflict; Orphaned Entry; Glue Parent */ } else { /* * Error. The parent can't be created as a glue entry. * This will cause replication divergence and will * require admin intercession */ ldap_rc= LDAP_OPERATIONS_ERROR; slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_rc); rc= -1; /* Abort this Operation */ PROFILE_POINT; /* Add Conflict; Orphaned Entry; Impossible to create parent; Refuse Change. */ } goto bailout; } if(is_tombstone_entry(parententry)) /* The parent is a tombstone */ { /* The parent entry must be resurected from the dead. */ ldap_rc = tombstone_to_glue (pb, sessionid, parententry, parentdn, REASON_RESURRECT_ENTRY, opcsn); if ( ldap_rc != LDAP_SUCCESS ) { ldap_rc= LDAP_OPERATIONS_ERROR; slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_rc); rc = -1; /* Abort the operation */ } else { /* The backend add code should now search for the parent again. */ rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY); rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_PARENT_ENTRY); } PROFILE_POINT; /* Add Conflict; Orphaned Entry; Parent Was Tombstone */ goto bailout; } /* The parent is healthy */ /* Now we need to check that the parent has the correct DN */ if (slapi_sdn_isparent(slapi_entry_get_sdn(parententry), slapi_entry_get_sdn(entry))) { rc= 0; /* OK, Add the entry */ PROFILE_POINT; /* Add Conflict; Parent Exists */ goto bailout; } /* * Parent entry doesn't have a DN parent to the entry. * This can happen if parententry was renamed due to * conflict and the child entry was created before * replication occured. See defect 530942. * We need to rename the entry to be child of its parent. */ add_rdn = slapi_rdn_new_dn(slapi_entry_get_dn_const (entry)); newdn = slapi_dn_plus_rdn(slapi_entry_get_dn_const (parententry), slapi_rdn_get_rdn(add_rdn)); slapi_entry_set_normdn ( entry, newdn ); /* slapi_pblock_get(pb, SLAPI_ADD_TARGET, &dn); */ slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(entry)); slapi_pblock_set(pb, SLAPI_ADD_TARGET_SDN, sdn); slapi_log_error ( slapi_log_urp, sessionid, "Parent was renamed. Renamed the child to %s\n", newdn ); rc= slapi_setbit_int(rc,SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY); PROFILE_POINT; /* Add Conflict; Parent Renamed; Rename Operation Entry */ bailout: if (parentdn) slapi_sdn_free(&parentdn); slapi_rdn_free(&add_rdn); return rc; }