int update_pw_retry ( Slapi_PBlock *pb ) { Slapi_Entry *e; int retry_cnt=0; time_t reset_time; time_t cur_time; char *cur_time_str = NULL; char *retryCountResetTime; int passwordRetryCount; int rc = 0; /* get the entry */ e = get_entry ( pb, NULL ); if ( e == NULL ) { return ( 1 ); } cur_time = current_time(); /* check if the retry count can be reset. */ retryCountResetTime= slapi_entry_attr_get_charptr(e, "retryCountResetTime"); if(retryCountResetTime!=NULL) { reset_time = parse_genTime (retryCountResetTime); slapi_ch_free((void **) &retryCountResetTime ); cur_time_str = format_genTime ( cur_time ); if ( difftime ( parse_genTime( cur_time_str ), reset_time) >= 0 ) { /* set passwordRetryCount to 1 */ /* reset retryCountResetTime */ rc = set_retry_cnt_and_time ( pb, 1, cur_time ); slapi_ch_free((void **) &cur_time_str ); slapi_entry_free( e ); return ( rc ); /* success */ } else { slapi_ch_free((void **) &cur_time_str ); } } else { /* initialize passwordRetryCount and retryCountResetTime */ rc = set_retry_cnt_and_time ( pb, 1, cur_time ); slapi_entry_free( e ); return ( rc ); /* success */ } passwordRetryCount = slapi_entry_attr_get_int(e, "passwordRetryCount"); if (passwordRetryCount >= 0) { retry_cnt = passwordRetryCount + 1; if ( retry_cnt == 1 ) { /* set retryCountResetTime */ rc = set_retry_cnt_and_time ( pb, retry_cnt, cur_time ); } else { /* set passwordRetryCount to retry_cnt */ rc = set_retry_cnt ( pb, retry_cnt ); } } slapi_entry_free( e ); return rc; /* success */ }
/* Creates global config structure from config entry at plugin startup */ int acct_policy_load_config_startup( Slapi_PBlock* pb, void* plugin_id ) { acctPluginCfg *newcfg; Slapi_Entry *config_entry = NULL; Slapi_DN *config_sdn = NULL; int rc; /* Retrieve the config entry */ config_sdn = slapi_sdn_new_normdn_byref( PLUGIN_CONFIG_DN ); rc = slapi_search_internal_get_entry( config_sdn, NULL, &config_entry, plugin_id); slapi_sdn_free( &config_sdn ); if( rc != LDAP_SUCCESS || config_entry == NULL ) { slapi_log_err(SLAPI_LOG_ERR, PLUGIN_NAME, "acct_policy_load_config_startup - Failed to retrieve configuration entry %s: %d\n", PLUGIN_CONFIG_DN, rc ); return( -1 ); } config_wr_lock(); free_config(); newcfg = get_config(); rc = acct_policy_entry2config( config_entry, newcfg ); config_unlock(); slapi_entry_free( config_entry ); return( rc ); }
/* * If an entry is deleted or renamed, a new winner may be * chosen from its naming competitors. * The entry with the smallest dncsn restores its original DN. */ static int urp_naming_conflict_removal ( Slapi_PBlock *pb, char *sessionid, CSN *opcsn, const char *optype ) { Slapi_Entry *min_naming_conflict_entry; Slapi_RDN *oldrdn, *newrdn; const char *oldrdnstr, *newrdnstr; int op_result; /* * Backend op has set SLAPI_URP_NAMING_COLLISION_DN to the basedn. */ min_naming_conflict_entry = urp_get_min_naming_conflict_entry (pb, sessionid, opcsn); if (min_naming_conflict_entry == NULL) { return 0; } /* Step 1: Restore the entry's original DN */ oldrdn = slapi_rdn_new_sdn(slapi_entry_get_sdn_const(min_naming_conflict_entry)); oldrdnstr = slapi_rdn_get_rdn ( oldrdn ); /* newrdnstr is the old rdn of the entry minus the nsuniqueid part */ newrdn = slapi_rdn_new_rdn ( oldrdn ); slapi_rdn_remove_attr (newrdn, SLAPI_ATTR_UNIQUEID ); newrdnstr = slapi_rdn_get_rdn ( newrdn ); /* * Set OP_FLAG_ACTION_INVOKE_FOR_REPLOP since this operation * is done after DB lock was released. The backend modrdn * will acquire the DB lock if it sees this flag. */ op_result = urp_fixup_rename_entry((const Slapi_Entry *)min_naming_conflict_entry, newrdnstr, OP_FLAG_ACTION_INVOKE_FOR_REPLOP); if ( op_result != LDAP_SUCCESS ) { slapi_log_error (slapi_log_urp, sessionid, "Failed to restore RDN of %s, err=%d\n", oldrdnstr, op_result); goto bailout; } slapi_log_error (slapi_log_urp, sessionid, "Naming conflict removed by %s. RDN of %s was restored\n", optype, oldrdnstr); /* Step2: Remove ATTR_NSDS5_REPLCONFLICT from the winning entry */ /* * A fixup op will not invoke urp_modrdn_operation(). Even it does, * urp_modrdn_operation() will do nothing because of the same CSN. */ op_result = del_replconflict_attr (min_naming_conflict_entry, opcsn, OP_FLAG_ACTION_INVOKE_FOR_REPLOP); if (op_result != LDAP_SUCCESS) { slapi_log_error(SLAPI_LOG_REPL, sessionid, "Failed to remove nsds5ReplConflict for %s, err=%d\n", newrdnstr, op_result); } bailout: slapi_entry_free(min_naming_conflict_entry); slapi_rdn_free(&oldrdn); slapi_rdn_free(&newrdn); return op_result; }
static int sync_feature_allowed (Slapi_PBlock *pb) { int isroot = 0; int ldapcode = LDAP_SUCCESS; slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); if ( !isroot) { char *dn; Slapi_Entry *feature = NULL; /* Fetch the feature entry and see if the requestor is allowed access. */ dn = slapi_ch_smprintf("dn: oid=%s,cn=features,cn=config", LDAP_CONTROL_SYNC); if ((feature = slapi_str2entry(dn,0)) != NULL) { char *dummy_attr = "1.1"; ldapcode = slapi_access_allowed(pb, feature, dummy_attr, NULL, SLAPI_ACL_READ); } /* If the feature entry does not exist, deny use of the control. Only * the root DN will be allowed to use the control in this case. */ if ((feature == NULL) || (ldapcode != LDAP_SUCCESS)) { ldapcode = LDAP_INSUFFICIENT_ACCESS; } slapi_ch_free((void **)&dn); slapi_entry_free(feature); } return(ldapcode); }
static void freeConfigEntry( Slapi_Entry **e ) { if ( (e != NULL) && (*e != NULL) ) { slapi_entry_free( *e ); *e = NULL; } }
/* * Check if User Private Groups are enabled in given IPA domain * Returns: 0 - UPG are enabled * 1 - UPG are disabled * -1 - some sort of error */ static int ipa_winsync_upg_enabled(const Slapi_DN *ds_subtree) { int ret = -1; int rc; char * dn = NULL; Slapi_Entry *entry = NULL; Slapi_Backend *be; const Slapi_DN *ds_suffix = NULL; Slapi_DN *sdn = NULL; const char *attrs_list[] = {IPA_WINSYNC_UPG_DEF_ATTR, 0}; char * value = NULL; /* find ancestor base DN */ be = slapi_be_select(ds_subtree); ds_suffix = slapi_be_getsuffix(be, 0); if (ds_suffix == NULL) { LOG_FATAL("Invalid DS subtree [%s]\n", slapi_sdn_get_dn(ds_subtree)); goto done; } dn = slapi_ch_smprintf(IPA_WINSYNC_UPG_DEF_DN, slapi_sdn_get_dn(ds_suffix)); if (!dn) { LOG_OOM(); goto done; } sdn = slapi_sdn_new_dn_byref(dn); rc = slapi_search_internal_get_entry(sdn, (char **) attrs_list, &entry, ipa_winsync_get_plugin_identity()); if (rc) { LOG("failed to retrieve UPG definition (%s) with rc %d\n", dn, rc); goto done; } value = slapi_entry_attr_get_charptr(entry, IPA_WINSYNC_UPG_DEF_ATTR); if (!value) { LOG("failed to read %s from UPG definition (%s)\n", IPA_WINSYNC_UPG_DEF_ATTR, dn); goto done; } if (strstr(value, IPA_WINSYNC_UPG_DEF_DISABLED) == NULL) { ret = 0; } else { ret = 1; } done: slapi_ch_free_string(&dn); slapi_sdn_free(&sdn); slapi_ch_free_string(&value); slapi_entry_free(entry); return ret; }
static int slapi_int_search_entry_callback( Slapi_Entry *entry, void *callback_data ) { int nentries = 0, i = 0; Slapi_Entry **head = NULL, **tp; Slapi_PBlock *pb = (Slapi_PBlock *)callback_data; PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_SEARCH ); entry = slapi_entry_dup( entry ); if ( entry == NULL ) { return LDAP_NO_MEMORY; } slapi_pblock_get( pb, SLAPI_NENTRIES, &nentries ); slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head ); i = nentries + 1; if ( nentries == 0 ) { tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) ); if ( tp == NULL ) { slapi_entry_free( entry ); return LDAP_NO_MEMORY; } tp[0] = entry; } else { tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head, sizeof(Slapi_Entry *) * ( i + 1 ) ); if ( tp == NULL ) { slapi_entry_free( entry ); return LDAP_NO_MEMORY; } tp[i - 1] = entry; } tp[i] = NULL; slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp ); slapi_pblock_set( pb, SLAPI_NENTRIES, (void *)&i ); return LDAP_SUCCESS; }
/* this is passin - windows_private owns the pointer, not a copy */ void windows_private_set_raw_entry(const Repl_Agmt *ra, Slapi_Entry *e) { Dirsync_Private *dp; LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_set_raw_entry\n" ); dp = (Dirsync_Private *) agmt_get_priv(ra); PR_ASSERT (dp); /* If the keep raw entry flag is set, just free the passed * in entry and leave the current raw entry in place. */ if (windows_private_get_keep_raw_entry(ra)) { slapi_entry_free(e); } else { slapi_entry_free(dp->raw_entry); dp->raw_entry = e; } LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_set_raw_entry\n" ); }
static void sync_free_update_nodes (Sync_UpdateNode **updates, int count) { int i; for (i=0; i<count;i++) { if ((*updates)[i].upd_uuid) slapi_ch_free((void **)&((*updates)[i].upd_uuid)); if ((*updates)[i].upd_e) slapi_entry_free((*updates)[i].upd_e); } slapi_ch_free((void **)updates); }
/* * Free a persistent search node (and everything it holds). */ static void pe_ch_free( PSEQNode **pe ) { if ( pe != NULL && *pe != NULL ) { if ( (*pe)->pe_entry != NULL ) { slapi_entry_free( (*pe)->pe_entry ); (*pe)->pe_entry = NULL; } if ( (*pe)->pe_ctrls[0] != NULL ) { ldap_control_free( (*pe)->pe_ctrls[0] ); (*pe)->pe_ctrls[0] = NULL; } slapi_ch_free( (void **)pe ); } }
/* destroy per-domain config object */ void ipa_winsync_config_destroy_domain( void *cbdata, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree ) { IPA_WinSync_Domain_Config *iwdc = (IPA_WinSync_Domain_Config *)cbdata; slapi_entry_free(iwdc->domain_e); iwdc->domain_e = NULL; slapi_ch_free_string(&iwdc->realm_name); slapi_ch_free_string(&iwdc->homedir_prefix); slapi_ch_free_string(&iwdc->login_shell); slapi_ch_free_string(&iwdc->inactivated_group_dn); slapi_ch_free_string(&iwdc->activated_group_dn); slapi_ch_free((void **)&iwdc); return; }
/* This is new style API to issue internal add operation. pblock should contain the following data (can be set via call to slapi_add_internal_set_pb): SLAPI_TARGET_SDN set to sdn of the new entry SLAPI_CONTROLS_ARG set to request controls if present SLAPI_ADD_ENTRY set to Slapi_Entry to add Beware: The entry is consumed. */ int slapi_add_internal_pb (Slapi_PBlock *pb) { if (pb == NULL) return -1; if (!allow_operation (pb)) { /* free the entry as it's expected to be consumed */ Slapi_Entry *e; slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e); slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); slapi_entry_free(e); slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, "This plugin is not configured to access operation target data", 0, NULL ); return 0; } return add_internal_pb (pb); }
void windows_agreement_delete(Repl_Agmt *ra) { Dirsync_Private *dp = (Dirsync_Private *) agmt_get_priv(ra); LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_private_delete\n" ); PR_ASSERT(dp != NULL); winsync_plugin_call_destroy_agmt_cb(ra, dp->directory_subtree, dp->windows_subtree); slapi_sdn_free(&dp->directory_subtree); slapi_sdn_free(&dp->windows_subtree); slapi_filter_free(dp->directory_filter, 1); slapi_filter_free(dp->deleted_filter, 1); slapi_entry_free(dp->raw_entry); dp->raw_entry = NULL; dp->api_cookie = NULL; slapi_ch_free((void **)dp); LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_private_delete\n" ); }
static char * derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, MyStrBuf *pam_id, char *map_ident_attr, int *locked) { Slapi_Entry *entry = NULL; char *attrs[] = { NULL, NULL }; attrs[0] = map_ident_attr; int rc = slapi_search_internal_get_entry((Slapi_DN *)bindsdn, attrs, &entry, pam_passthruauth_get_plugin_identity()); if (rc != LDAP_SUCCESS) { slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, "Could not find BIND dn %s (error %d - %s)\n", slapi_sdn_get_ndn(bindsdn), rc, ldap_err2string(rc)); init_my_str_buf(pam_id, NULL); } else if (NULL == entry) { slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, "Could not find entry for BIND dn %s\n", slapi_sdn_get_ndn(bindsdn)); init_my_str_buf(pam_id, NULL); } else if (slapi_check_account_lock( pb, entry, 0, 0, 0 ) == 1) { slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, "Account %s inactivated.\n", slapi_sdn_get_ndn(bindsdn)); init_my_str_buf(pam_id, NULL); *locked = 1; } else { char *val = slapi_entry_attr_get_charptr(entry, map_ident_attr); init_my_str_buf(pam_id, val); slapi_ch_free_string(&val); } slapi_entry_free(entry); return pam_id->str; }
/* * memberof_apply_config() * * Apply the pending changes in the e entry to our config struct. * memberof_validate_config() must have already been called. */ int memberof_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg) { Slapi_Entry *config_entry = NULL; Slapi_DN *config_sdn = NULL; char **groupattrs = NULL; char *memberof_attr = NULL; char *filter_str = NULL; int num_groupattrs = 0; int groupattr_name_len = 0; char *allBackends = NULL; char **entryScopes = NULL; char **entryScopeExcludeSubtrees = NULL; char *sharedcfg = NULL; char *skip_nested = NULL; char *auto_add_oc = NULL; int num_vals = 0; *returncode = LDAP_SUCCESS; /* * Check if this is a shared config entry */ sharedcfg = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA); if(sharedcfg){ if((config_sdn = slapi_sdn_new_dn_byval(sharedcfg))){ slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, memberof_get_plugin_id()); if(config_entry){ /* Set the entry to be the shared config entry. Validation was done in preop */ e = config_entry; } else { /* This should of been checked in preop validation */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "memberof_apply_config - Failed to locate shared config entry (%s)", sharedcfg); slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM,"%s\n",returntext); *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } } } /* * Apply the config settings */ groupattrs = slapi_entry_attr_get_charray(e, MEMBEROF_GROUP_ATTR); memberof_attr = slapi_entry_attr_get_charptr(e, MEMBEROF_ATTR); allBackends = slapi_entry_attr_get_charptr(e, MEMBEROF_BACKEND_ATTR); skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR); auto_add_oc = slapi_entry_attr_get_charptr(e, MEMBEROF_AUTO_ADD_OC); /* * We want to be sure we don't change the config in the middle of * a memberOf operation, so we obtain an exclusive lock here */ memberof_wlock_config(); if (groupattrs) { int i = 0; slapi_ch_array_free(theConfig.groupattrs); theConfig.groupattrs = groupattrs; groupattrs = NULL; /* config now owns memory */ /* * We allocate a list of Slapi_Attr using the groupattrs for * convenience in our memberOf comparison functions */ for (i = 0; theConfig.group_slapiattrs && theConfig.group_slapiattrs[i]; i++) { slapi_attr_free(&theConfig.group_slapiattrs[i]); } /* Count the number of groupattrs. */ for (num_groupattrs = 0; theConfig.groupattrs && theConfig.groupattrs[num_groupattrs]; num_groupattrs++) { /* * Add up the total length of all attribute names. We need * to know this for building the group check filter later. */ groupattr_name_len += strlen(theConfig.groupattrs[num_groupattrs]); } /* Realloc the list of Slapi_Attr if necessary. */ if (i < num_groupattrs) { theConfig.group_slapiattrs = (Slapi_Attr **)slapi_ch_realloc((char *)theConfig.group_slapiattrs, sizeof(Slapi_Attr *) * (num_groupattrs + 1)); } /* Build the new list */ for (i = 0; theConfig.groupattrs[i]; i++) { theConfig.group_slapiattrs[i] = slapi_attr_new(); slapi_attr_init(theConfig.group_slapiattrs[i], theConfig.groupattrs[i]); } /* Terminate the list. */ theConfig.group_slapiattrs[i] = NULL; /* The filter is based off of the groupattr, so we update it here too. */ slapi_filter_free(theConfig.group_filter, 1); if (num_groupattrs > 1) { int bytes_out = 0; int filter_str_len = groupattr_name_len + (num_groupattrs * 4) + 4; /* Allocate enough space for the filter */ filter_str = slapi_ch_malloc(filter_str_len); /* Add beginning of filter. */ bytes_out = snprintf(filter_str, filter_str_len - bytes_out, "(|"); /* Add filter section for each groupattr. */ for (i = 0; theConfig.groupattrs[i]; i++) { bytes_out += snprintf(filter_str + bytes_out, filter_str_len - bytes_out, "(%s=*)", theConfig.groupattrs[i]); } /* Add end of filter. */ snprintf(filter_str + bytes_out, filter_str_len - bytes_out, ")"); } else { filter_str = slapi_ch_smprintf("(%s=*)", theConfig.groupattrs[0]); } /* * Log an error if we were unable to build the group filter for some * reason. If this happens, the memberOf plugin will not be able to * check if an entry is a group, causing it to not catch changes. This * shouldn't happen, but there may be some garbage configuration that * could trigger this. */ if ((theConfig.group_filter = slapi_str2filter(filter_str)) == NULL) { slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_apply_config - Unable to create the group check filter. The memberOf " "plug-in will not operate on changes to groups. Please check " "your %s configuration settings. (filter: %s)\n", MEMBEROF_GROUP_ATTR, filter_str ); } slapi_ch_free_string(&filter_str); } if (memberof_attr) { slapi_ch_free_string(&theConfig.memberof_attr); theConfig.memberof_attr = memberof_attr; memberof_attr = NULL; /* config now owns memory */ } if (skip_nested){ if(strcasecmp(skip_nested,"on") == 0){ theConfig.skip_nested = 1; } else { theConfig.skip_nested = 0; } } if (allBackends) { if(strcasecmp(allBackends,"on")==0){ theConfig.allBackends = 1; } else { theConfig.allBackends = 0; } } else { theConfig.allBackends = 0; } theConfig.auto_add_oc = auto_add_oc; /* * Check and process the entry scopes */ memberof_free_scope(theConfig.entryScopes, &theConfig.entryScopeCount); entryScopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); if(entryScopes){ int i = 0; /* Validation has already been performed in preop, just build the DN's */ theConfig.entryScopes = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); for (i = 0;i < num_vals; i++){ theConfig.entryScopes[i] = slapi_sdn_new_dn_passin(entryScopes[i]); } theConfig.entryScopeCount = num_vals; /* shortcut for config copy */ } /* * Check and process the entry exclude scopes */ memberof_free_scope(theConfig.entryScopeExcludeSubtrees, &theConfig.entryExcludeScopeCount); entryScopeExcludeSubtrees = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); if(entryScopeExcludeSubtrees){ int i = 0; /* Validation has already been performed in preop, just build the DN's */ theConfig.entryScopeExcludeSubtrees = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); for (i = 0;i < num_vals; i++){ theConfig.entryScopeExcludeSubtrees[i] = slapi_sdn_new_dn_passin(entryScopeExcludeSubtrees[i]); } theConfig.entryExcludeScopeCount = num_vals; /* shortcut for config copy */ } /* release the lock */ memberof_unlock_config(); done: slapi_sdn_free(&config_sdn); slapi_entry_free(config_entry); slapi_ch_array_free(groupattrs); slapi_ch_free_string(&sharedcfg); slapi_ch_free_string(&memberof_attr); slapi_ch_free_string(&allBackends); slapi_ch_free_string(&skip_nested); slapi_ch_free((void **)&entryScopes); slapi_ch_free((void **)&entryScopeExcludeSubtrees); if (*returncode != LDAP_SUCCESS) { return SLAPI_DSE_CALLBACK_ERROR; } else { return SLAPI_DSE_CALLBACK_OK; } }
void do_compare( Slapi_PBlock *pb ) { BerElement *ber = pb->pb_op->o_ber; char *rawdn = NULL; const char *dn = NULL; struct ava ava = {0}; Slapi_Backend *be = NULL; int err; Slapi_DN sdn; Slapi_Entry *referral = NULL; char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; slapi_log_err(SLAPI_LOG_TRACE, "do_compare", "=>\n"); /* count the compare request */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsCompareOps); /* have to init this here so we can "done" it below if we short circuit */ slapi_sdn_init(&sdn); /* * Parse the compare request. It looks like this: * * CompareRequest := [APPLICATION 14] SEQUENCE { * entry DistinguishedName, * ava SEQUENCE { * type AttributeType, * value AttributeValue * } * } */ if ( ber_scanf( ber, "{a{ao}}", &rawdn, &ava.ava_type, &ava.ava_value ) == LBER_ERROR ) { slapi_log_err(SLAPI_LOG_ERR, "do_compare", "ber_scanf failed (op=Compare; params=DN,Type,Value)\n"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL ); goto free_and_return; } /* Check if we should be performing strict validation. */ if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ err = slapi_dn_syntax_check(pb, rawdn, 1); if (err) { /* syntax check failed */ op_shared_log_error_access(pb, "CMP", rawdn?rawdn:"", "strict: invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free((void **) &rawdn); return; } } slapi_sdn_init_dn_passin(&sdn, rawdn); dn = slapi_sdn_get_dn(&sdn); if (rawdn && (strlen(rawdn) > 0) && (NULL == dn)) { /* normalization failed */ op_shared_log_error_access(pb, "CMP", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_sdn_done(&sdn); return; } /* * in LDAPv3 there can be optional control extensions on * the end of an LDAPMessage. we need to read them in and * pass them to the backend. */ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) { send_ldap_result( pb, err, NULL, NULL, 0, NULL ); goto free_and_return; } /* target spec is used to decide which plugins are applicable for the operation */ operation_set_target_spec (pb->pb_op, &sdn); slapi_log_err(SLAPI_LOG_ARGS, "do_compare: dn (%s) attr (%s)\n", rawdn, ava.ava_type, 0 ); slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d CMP dn=\"%s\" attr=\"%s\"\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, ava.ava_type ); /* * We could be serving multiple database backends. Select the * appropriate one. */ if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf, sizeof(errorbuf))) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, errorbuf, 0, NULL); be = NULL; goto free_and_return; } if (referral) { int managedsait; slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); if (managedsait) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot compare referral", 0, NULL); slapi_entry_free(referral); goto free_and_return; } send_referrals_from_entry(pb,referral); slapi_entry_free(referral); goto free_and_return; } if ( be->be_compare != NULL ) { int isroot; slapi_pblock_set( pb, SLAPI_BACKEND, be ); isroot = pb->pb_op->o_isroot; slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &isroot ); /* EXCEPTION: compare target does not allocate memory. */ /* target never be modified by plugins. */ slapi_pblock_set( pb, SLAPI_COMPARE_TARGET_SDN, (void*)&sdn ); slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, ava.ava_type); slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, &ava.ava_value ); /* * call the pre-compare plugins. if they succeed, call * the backend compare function. then call the * post-compare plugins. */ if ( plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_COMPARE_FN ) == 0 ) { int rc; slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database ); set_db_default_result_handlers(pb); rc = (*be->be_compare)( pb ); slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &rc ); plugin_call_plugins( pb, SLAPI_PLUGIN_POST_COMPARE_FN ); } } else { send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL ); } free_and_return:; if (be) slapi_be_Unlock(be); slapi_sdn_done(&sdn); ava_done( &ava ); }
int slapi_add_internal_pb( Slapi_PBlock *pb ) { SlapReply *rs; Slapi_Entry *entry_orig = NULL; OpExtraDB oex; int rc; if ( pb == NULL ) { return -1; } PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD ); rs = pb->pb_rs; entry_orig = pb->pb_op->ora_e; pb->pb_op->ora_e = NULL; /* * The caller can specify a new entry, or a target DN and set * of modifications, but not both. */ if ( entry_orig != NULL ) { if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) { rs->sr_err = LDAP_PARAM_ERROR; goto cleanup; } assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */ ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name ); ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname ); } else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) { rs->sr_err = LDAP_PARAM_ERROR; goto cleanup; } pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) ); ber_dupbv( &pb->pb_op->ora_e->e_name, &pb->pb_op->o_req_dn ); ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn ); if ( entry_orig != NULL ) { assert( pb->pb_op->ora_modlist == NULL ); rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); if ( rs->sr_err != LDAP_SUCCESS ) { goto cleanup; } } else { assert( pb->pb_op->ora_modlist != NULL ); } rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL ); if ( rs->sr_err != LDAP_SUCCESS ) { goto cleanup; } /* Duplicate the values, because we may call slapi_entry_free() */ rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e, 1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) ); if ( rs->sr_err != LDAP_SUCCESS ) { goto cleanup; } oex.oe.oe_key = (void *)do_add; oex.oe_db = NULL; LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next); rc = slapi_int_func_internal_pb( pb, op_add ); LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next); if ( !rc ) { if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) { BackendDB *bd = pb->pb_op->o_bd; pb->pb_op->o_bd = oex.oe_db; be_entry_release_w( pb->pb_op, pb->pb_op->ora_e ); pb->pb_op->ora_e = NULL; pb->pb_op->o_bd = bd; } } cleanup: if ( pb->pb_op->ora_e != NULL ) { slapi_entry_free( pb->pb_op->ora_e ); pb->pb_op->ora_e = NULL; } if ( entry_orig != NULL ) { pb->pb_op->ora_e = entry_orig; slap_mods_free( pb->pb_op->ora_modlist, 1 ); pb->pb_op->ora_modlist = NULL; } return 0; }
/* Given an entry, provide the account policy in effect for that entry. Returns non-0 if function fails. If account policy comes back NULL, it's not an error; the entry is simply not covered by a policy. */ int get_acctpolicy( Slapi_PBlock *pb, Slapi_Entry *target_entry, void *plugin_id, acctPolicy **policy ) { Slapi_DN *sdn = NULL; Slapi_Entry *policy_entry = NULL; Slapi_Attr *attr; Slapi_Value *sval = NULL; int ldrc; char *attr_name; char *policy_dn = NULL; acctPluginCfg *cfg; int rc = 0; if( policy == NULL ) { /* Bad parameter */ return( -1 ); } *policy = NULL; config_rd_lock(); cfg = get_config(); /* Return success and NULL policy */ policy_dn = get_attr_string_val( target_entry, cfg->spec_attr_name ); if( policy_dn == NULL ) { slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME, "get_acctpolicy - \"%s\" is not governed by an account inactivity " "policy subentry\n", slapi_entry_get_ndn( target_entry ) ); if (cfg->inactivitylimit != ULONG_MAX) { goto dopolicy; } slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME, "get_acctpolicy - \"%s\" is not governed by an account inactivity " "global policy\n", slapi_entry_get_ndn( target_entry ) ); config_unlock(); return rc; } sdn = slapi_sdn_new_dn_byref( policy_dn ); ldrc = slapi_search_internal_get_entry( sdn, NULL, &policy_entry, plugin_id ); slapi_sdn_free( &sdn ); /* There should be a policy but it can't be retrieved; fatal error */ if( policy_entry == NULL ) { if( ldrc != LDAP_NO_SUCH_OBJECT ) { slapi_log_err(SLAPI_LOG_ERR, PLUGIN_NAME, "get_acctpolicy - Error retrieving policy entry \"%s\": %d\n", policy_dn, ldrc ); } else { slapi_log_err(SLAPI_LOG_PLUGIN, PLUGIN_NAME, "get_acctpolicy - Policy entry \"%s\" is missing: %d\n", policy_dn, ldrc ); } rc = -1; goto done; } dopolicy: *policy = (acctPolicy *)slapi_ch_calloc( 1, sizeof( acctPolicy ) ); if ( !policy_entry ) { /* global policy */ (*policy)->inactivitylimit = cfg->inactivitylimit; goto done; } for( slapi_entry_first_attr( policy_entry, &attr ); attr != NULL; slapi_entry_next_attr( policy_entry, attr, &attr ) ) { slapi_attr_get_type(attr, &attr_name); if( !strcasecmp( attr_name, cfg->limit_attr_name ) ) { if( slapi_attr_first_value( attr, &sval ) == 0 ) { (*policy)->inactivitylimit = slapi_value_get_ulong( sval ); } } } done: config_unlock(); slapi_ch_free_string( &policy_dn ); slapi_entry_free( policy_entry ); return( rc ); }
static struct ipapwd_krbcfg *ipapwd_getConfig(void) { krb5_error_code krberr; struct ipapwd_krbcfg *config = NULL; krb5_keyblock *kmkey = NULL; Slapi_Entry *realm_entry = NULL; Slapi_Entry *config_entry = NULL; Slapi_Attr *a; Slapi_Value *v; BerElement *be = NULL; ber_tag_t tag, tvno; ber_int_t ttype; const struct berval *bval; struct berval *mkey = NULL; char **encsalts; char **tmparray; char *tmpstr; int i, ret; config = calloc(1, sizeof(struct ipapwd_krbcfg)); if (!config) { LOG_OOM(); goto free_and_error; } kmkey = calloc(1, sizeof(krb5_keyblock)); if (!kmkey) { LOG_OOM(); goto free_and_error; } config->kmkey = kmkey; krberr = krb5_init_context(&config->krbctx); if (krberr) { LOG_FATAL("krb5_init_context failed\n"); goto free_and_error; } ret = krb5_get_default_realm(config->krbctx, &config->realm); if (ret) { LOG_FATAL("Failed to get default realm?!\n"); goto free_and_error; } /* get the Realm Container entry */ ret = ipapwd_getEntry(ipa_realm_dn, &realm_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No realm Entry?\n"); goto free_and_error; } /*** get the Kerberos Master Key ***/ ret = slapi_entry_attr_find(realm_entry, "krbMKey", &a); if (ret == -1) { LOG_FATAL("No master key??\n"); goto free_and_error; } /* there should be only one value here */ ret = slapi_attr_first_value(a, &v); if (ret == -1) { LOG_FATAL("No master key??\n"); goto free_and_error; } bval = slapi_value_get_berval(v); if (!bval) { LOG_FATAL("Error retrieving master key berval\n"); goto free_and_error; } be = ber_init(discard_const(bval)); if (!be) { LOG_FATAL("ber_init() failed!\n"); goto free_and_error; } tag = ber_scanf(be, "{i{iO}}", &tvno, &ttype, &mkey); if (tag == LBER_ERROR) { LOG_FATAL("Bad Master key encoding ?!\n"); goto free_and_error; } config->mkvno = tvno; kmkey->magic = KV5M_KEYBLOCK; kmkey->enctype = ttype; kmkey->length = mkey->bv_len; kmkey->contents = malloc(mkey->bv_len); if (!kmkey->contents) { LOG_OOM(); goto free_and_error; } memcpy(kmkey->contents, mkey->bv_val, mkey->bv_len); ber_bvfree(mkey); ber_free(be, 1); mkey = NULL; be = NULL; /*** get the Supported Enc/Salt types ***/ encsalts = slapi_entry_attr_get_charray(realm_entry, "krbSupportedEncSaltTypes"); if (encsalts) { for (i = 0; encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, (const char * const *)encsalts, i, &config->supp_encsalts, &config->num_supp_encsalts); slapi_ch_array_free(encsalts); } else { LOG("No configured salt types use defaults\n"); for (i = 0; ipapwd_def_encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, ipapwd_def_encsalts, i, &config->supp_encsalts, &config->num_supp_encsalts); } if (ret) { LOG_FATAL("Can't get Supported EncSalt Types\n"); goto free_and_error; } /*** get the Preferred Enc/Salt types ***/ encsalts = slapi_entry_attr_get_charray(realm_entry, "krbDefaultEncSaltTypes"); if (encsalts) { for (i = 0; encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, (const char * const *)encsalts, i, &config->pref_encsalts, &config->num_pref_encsalts); slapi_ch_array_free(encsalts); } else { LOG("No configured salt types use defaults\n"); for (i = 0; ipapwd_def_encsalts[i]; i++) /* count */ ; ret = parse_bval_key_salt_tuples(config->krbctx, ipapwd_def_encsalts, i, &config->pref_encsalts, &config->num_pref_encsalts); } if (ret) { LOG_FATAL("Can't get Preferred EncSalt Types\n"); goto free_and_error; } slapi_entry_free(realm_entry); /* get the Realm Container entry */ ret = ipapwd_getEntry(ipa_pwd_config_dn, &config_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No config Entry? Impossible!\n"); goto free_and_error; } config->passsync_mgrs = slapi_entry_attr_get_charray(config_entry, "passSyncManagersDNs"); /* now add Directory Manager, it is always added by default */ tmpstr = slapi_ch_strdup("cn=Directory Manager"); slapi_ch_array_add(&config->passsync_mgrs, tmpstr); if (config->passsync_mgrs == NULL) { LOG_OOM(); goto free_and_error; } for (i = 0; config->passsync_mgrs[i]; i++) /* count */ ; config->num_passsync_mgrs = i; slapi_entry_free(config_entry); /* get the ipa etc/ipaConfig entry */ config->allow_nt_hash = false; ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL); if (ret != LDAP_SUCCESS) { LOG_FATAL("No config Entry?\n"); goto free_and_error; } else { tmparray = slapi_entry_attr_get_charray(config_entry, "ipaConfigString"); for (i = 0; tmparray && tmparray[i]; i++) { if (strcasecmp(tmparray[i], "AllowNThash") == 0) { config->allow_nt_hash = true; continue; } } if (tmparray) slapi_ch_array_free(tmparray); } slapi_entry_free(config_entry); return config; free_and_error: if (mkey) ber_bvfree(mkey); if (be) ber_free(be, 1); if (kmkey) { free(kmkey->contents); free(kmkey); } if (config) { if (config->krbctx) { if (config->realm) krb5_free_default_realm(config->krbctx, config->realm); krb5_free_context(config->krbctx); } free(config->pref_encsalts); free(config->supp_encsalts); slapi_ch_array_free(config->passsync_mgrs); free(config); } slapi_entry_free(config_entry); slapi_entry_free(realm_entry); return NULL; }
/* * op_shared_rename() -- common frontend code for modDN operations. * * Beware: this function resets the following pblock elements that were * set by the caller: * * SLAPI_MODRDN_TARGET_SDN * SLAPI_MODRDN_NEWRDN * SLAPI_MODRDN_NEWSUPERIOR_SDN */ static void op_shared_rename(Slapi_PBlock *pb, int passin_args) { char *dn, *newrdn, *newdn = NULL; const char *newsuperior; char **rdns; int deloldrdn; Slapi_Backend *be = NULL; Slapi_DN *origsdn = NULL; Slapi_Mods smods; int internal_op, repl_op, lastmod; Slapi_Operation *operation; Slapi_Entry *referral; char errorbuf[BUFSIZ]; int err; char *proxydn = NULL; char *proxystr = NULL; int proxy_err = LDAP_SUCCESS; char *errtext = NULL; Slapi_DN *sdn = NULL; Slapi_DN *newsuperiorsdn = NULL; slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &dn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn); slapi_pblock_get(pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn); slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op); slapi_pblock_get (pb, SLAPI_OPERATION, &operation); slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &origsdn); internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL); /* * If ownership has not been passed to this function, we replace the * string input fields within the pblock with strdup'd copies. Why? * Because some pre- and post-op plugins may change them, and the * convention is that plugins should place a malloc'd string in the * pblock. Therefore, we need to be able to retrieve and free them * later. But the callers of the internal modrdn calls are promised * that we will not free these parameters... so if passin_args is * zero, we need to make copies. * * In the case of SLAPI_MODRDN_TARGET_SDN and SLAPI_MODRDN_NEWSUPERIOR_SDN, * we replace the existing values with normalized values (because plugins * expect these DNs to be normalized). */ if (NULL == origsdn) { sdn = slapi_sdn_new_dn_byval(dn); slapi_pblock_set(pb, SLAPI_MODRDN_TARGET_SDN, sdn); } if (passin_args) { if (NULL == sdn) { /* origsdn is not NULL, so use it. */ sdn = origsdn; } } else { if (NULL == sdn) { sdn = slapi_sdn_dup(origsdn); } newrdn = slapi_ch_strdup(newrdn); newsuperiorsdn = slapi_sdn_dup(newsuperiorsdn); slapi_pblock_set(pb, SLAPI_MODRDN_TARGET_SDN, sdn); slapi_pblock_set(pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn); slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, newsuperiorsdn); } /* normdn = slapi_sdn_get_dn(sdn); */ newsuperior = slapi_sdn_get_dn(newsuperiorsdn); /* get the proxy auth dn if the proxy auth control is present */ proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext); /* * first, log the operation to the access log, * then check rdn and newsuperior, * and - if applicable - log reason of any error to the errors log */ if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) { if (proxydn) { proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); } if ( !internal_op ) { slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, dn, newrdn ? newrdn : "(null)", newsuperior ? newsuperior : "(null)", proxystr ? proxystr : ""); } else { slapi_log_access(LDAP_DEBUG_ARGS, "conn=%s op=%d MODRDN dn=\"%s\" newrdn=\"%s\" newsuperior=\"%s\"%s\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, dn, newrdn ? newrdn : "(null)", newsuperior ? newsuperior : "(null)", proxystr ? proxystr : ""); } } /* If we encountered an error parsing the proxy control, return an error * to the client. We do this here to ensure that we log the operation first. */ if (proxy_err != LDAP_SUCCESS) { send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL); goto free_and_return_nolock; } /* check that the rdn is formatted correctly */ if ((rdns = slapi_ldap_explode_rdn(newrdn, 0)) == NULL) { if ( !internal_op ) { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%" NSPRIu64 " op=%d MODRDN invalid new RDN (\"%s\")\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, (NULL == newrdn) ? "(null)" : newrdn); } else { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%s op=%d MODRDN invalid new RDN (\"%s\")\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, (NULL == newrdn) ? "(null)" : newrdn); } send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid RDN", 0, NULL); goto free_and_return_nolock; } else { slapi_ldap_value_free(rdns); } /* check if created attributes are used in the new RDN */ /* check_rdn_for_created_attrs ignores the cases */ if (check_rdn_for_created_attrs((const char *)newrdn)) { send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid attribute in RDN", 0, NULL); goto free_and_return_nolock; } /* check that the dn is formatted correctly */ err = slapi_dn_syntax_check(pb, newsuperior, 1); if (err) { LDAPDebug0Args(LDAP_DEBUG_ARGS, "Syntax check of newSuperior failed\n"); if (!internal_op) { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%" NSPRIu64 " op=%d MODRDN invalid new superior (\"%s\")", pb->pb_conn->c_connid, pb->pb_op->o_opid, newsuperior ? newsuperior : "(null)"); } else { slapi_log_error(SLAPI_LOG_ARGS, NULL, "conn=%s op=%d MODRDN invalid new superior (\"%s\")", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, newsuperior ? newsuperior : "(null)"); } send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "newSuperior does not look like a DN", 0, NULL); goto free_and_return_nolock; } if (newsuperior != NULL) { LDAPDebug(LDAP_DEBUG_ARGS, "do_moddn: newsuperior (%s)\n", newsuperior, 0, 0); } /* target spec is used to decide which plugins are applicable for the operation */ operation_set_target_spec (pb->pb_op, sdn); /* * Construct the new DN (code sdn from backend * and modified to handle newsuperior) */ newdn = slapi_moddn_get_newdn(sdn, newrdn, newsuperior); /* * We could be serving multiple database backends. Select the * appropriate one, or send a referral to our "referral server" * if we don't hold it. */ /* slapi_mapping_tree_select_and_check ignores the case of newdn * which is generated using newrdn above. */ if ((err = slapi_mapping_tree_select_and_check(pb, newdn, &be, &referral, errorbuf)) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, errorbuf, 0, NULL); goto free_and_return_nolock; } if (referral) { int managedsait; slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); if (managedsait) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot update referral", 0, NULL); slapi_entry_free(referral); goto free_and_return; } send_referrals_from_entry(pb,referral); slapi_entry_free(referral); goto free_and_return; } slapi_pblock_set(pb, SLAPI_BACKEND, be); /* can get lastmod only after backend is selected */ slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod); /* if it is a replicated operation - leave lastmod attributes alone */ slapi_mods_init (&smods, 2); if (!repl_op && lastmod) { modify_update_last_modified_attr(pb, &smods); slapi_pblock_set(pb, SLAPI_MODIFY_MODS, (void*)slapi_mods_get_ldapmods_passout(&smods)); } else { slapi_mods_done (&smods); } /* * call the pre-modrdn plugins. if they succeed, call * the backend modrdn function. then call the * post-modrdn plugins. */ if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN : SLAPI_PLUGIN_PRE_MODRDN_FN) == 0) { int rc= LDAP_OPERATIONS_ERROR; slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); set_db_default_result_handlers(pb); if (be->be_modrdn != NULL) { if ((rc = (*be->be_modrdn)(pb)) == 0) { Slapi_Entry *pse; Slapi_Entry *ecopy; /* we don't perform acl check for internal operations */ /* dont update aci store for remote acis */ if ((!internal_op) && (!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))) plugin_call_acl_mods_update (pb, SLAPI_OPERATION_MODRDN); if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT)) write_audit_log_entry(pb); /* Record the operation in the audit log */ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy); /* GGOODREPL persistent search system needs the changenumber, oops. */ do_ps_service(pse, ecopy, LDAP_CHANGETYPE_MODDN, 0); } } else { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL); } slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc); plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN : SLAPI_PLUGIN_POST_MODRDN_FN); } free_and_return: if (be) slapi_be_Unlock(be); free_and_return_nolock: { /* Free up everything left in the PBlock */ Slapi_Entry *pse; Slapi_Entry *ecopy; LDAPMod **mods; char *s; if (passin_args) { if (NULL == origsdn) { slapi_sdn_free(&sdn); } } else { slapi_pblock_get(pb, SLAPI_MODRDN_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); /* get newrdn to free the string */ slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &newrdn); slapi_ch_free_string(&newrdn); slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &newsuperiorsdn); slapi_sdn_free(&newsuperiorsdn); } slapi_ch_free_string(&newdn); slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy); slapi_entry_free(ecopy); slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); slapi_entry_free(pse); slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &mods ); ldap_mods_free( mods, 1 ); slapi_ch_free_string(&proxydn); slapi_ch_free_string(&proxystr); slapi_pblock_get(pb, SLAPI_URP_NAMING_COLLISION_DN, &s); slapi_ch_free((void **)&s); } }
/* create the default indexes separately * (because when we're creating a new backend while the server is running, * the DSE needs to be pre-seeded first.) */ int ldbm_instance_create_default_indexes(backend *be) { Slapi_Entry *e; ldbm_instance *inst = (ldbm_instance *)be->be_instance_info; /* write the dse file only on the final index */ int flags = LDBM_INSTANCE_CONFIG_DONT_WRITE; /* * Always index (entrydn or entryrdn), parentid, objectclass, * subordinatecount, copiedFrom, and aci, * since they are used by some searches, replication and the * ACL routines. */ if (entryrdn_get_switch()) { /* subtree-rename: on */ e = ldbm_instance_init_config_entry(LDBM_ENTRYRDN_STR,"subtree", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); } else { e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); } e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry("objectclass","eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry("aci","pres", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); #if 0 /* don't need copiedfrom */ e = ldbm_instance_init_config_entry("copiedfrom","pres",0 ,0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); #endif e = ldbm_instance_init_config_entry(LDBM_NUMSUBORDINATES_STR,"pres", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); e = ldbm_instance_init_config_entry(SLAPI_ATTR_UNIQUEID,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* For MMR, we need this attribute (to replace use of dncomp in delete). */ e = ldbm_instance_init_config_entry(ATTR_NSDS5_REPLCONFLICT,"eq", "pres", 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* write the dse file only on the final index */ e = ldbm_instance_init_config_entry(SLAPI_ATTR_NSCP_ENTRYDN,"eq", 0, 0, 0); ldbm_instance_config_add_index_entry(inst, e, flags); slapi_entry_free(e); /* ldbm_instance_config_add_index_entry(inst, 2, argv); */ e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT,"none", 0, 0, 0); attr_index_config( be, "ldbm index init", 0, e, 1, 0 ); slapi_entry_free(e); if (!entryrdn_get_noancestorid()) { /* * ancestorid is special, there is actually no such attr type * but we still want to use the attr index file APIs. */ e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR,"eq", 0, 0, 0); attr_index_config( be, "ldbm index init", 0, e, 1, 0 ); slapi_entry_free(e); } return 0; }
/* This function is called to process operation that come over external connections */ void do_add( Slapi_PBlock *pb ) { Slapi_Operation *operation; BerElement *ber; char *last; ber_len_t len = LBER_ERROR; ber_tag_t tag; Slapi_Entry *e = NULL; int err; int rc; PRBool searchsubentry=PR_TRUE; slapi_log_err(SLAPI_LOG_TRACE, "do_add", "==>\n"); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); ber = operation->o_ber; /* count the add request */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsAddEntryOps); /* * Parse the add request. It looks like this: * * AddRequest := [APPLICATION 14] SEQUENCE { * name DistinguishedName, * attrs SEQUENCE OF SEQUENCE { * type AttributeType, * values SET OF AttributeValue * } * } */ /* get the name */ { char *rawdn = NULL; Slapi_DN mysdn; if ( ber_scanf( ber, "{a", &rawdn ) == LBER_ERROR ) { slapi_ch_free_string(&rawdn); slapi_log_err(SLAPI_LOG_ERR, "do_add", "ber_scanf failed (op=Add; params=DN)\n"); op_shared_log_error_access (pb, "ADD", "???", "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); return; } /* Check if we should be performing strict validation. */ if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ rc = slapi_dn_syntax_check(pb, rawdn, 1); if (rc) { /* syntax check failed */ op_shared_log_error_access(pb, "ADD", rawdn?rawdn:"", "strict: invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free_string(&rawdn); return; } } slapi_sdn_init_dn_passin(&mysdn, rawdn); if (rawdn && (strlen(rawdn) > 0) && (NULL == slapi_sdn_get_dn(&mysdn))) { /* normalization failed */ op_shared_log_error_access(pb, "ADD", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_sdn_done(&mysdn); return; } e = slapi_entry_alloc(); /* Responsibility for DN is passed to the Entry. */ slapi_entry_init_ext(e, &mysdn, NULL); slapi_sdn_done(&mysdn); } slapi_log_err(SLAPI_LOG_ARGS, "do_add", "dn (%s)\n", (char *)slapi_entry_get_dn_const(e)); /* get the attrs */ for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET; tag = ber_next_element( ber, &len, last ) ) { char *type = NULL, *normtype = NULL; struct berval **vals = NULL; len = -1; /* reset - not used in loop */ if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); slapi_ch_free_string(&type); ber_bvecfree( vals ); goto free_and_return; } if ( vals == NULL ) { slapi_log_err(SLAPI_LOG_ERR, "do_add - no values for type %s\n", type, 0, 0 ); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "null value"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, NULL, 0, NULL ); slapi_ch_free_string(&type); goto free_and_return; } normtype = slapi_attr_syntax_normalize(type); if ( !normtype || !*normtype ) { char ebuf[SLAPI_DSE_RETURNTEXT_SIZE]; rc = LDAP_INVALID_SYNTAX; slapi_create_errormsg(ebuf, sizeof(ebuf), "invalid type '%s'", type); op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), ebuf); send_ldap_result( pb, rc, NULL, ebuf, 0, NULL ); slapi_ch_free_string(&type); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } slapi_ch_free_string(&type); /* for now we just ignore attributes that client is not allowed to modify so not to break existing clients */ if (op_shared_is_allowed_attr (normtype, pb->pb_conn->c_isreplication_session)){ if (( rc = slapi_entry_add_values( e, normtype, vals )) != LDAP_SUCCESS ) { slapi_log_access( LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\", add values for type %s failed\n", pb->pb_conn->c_connid, operation->o_opid, slapi_entry_get_dn_const(e), normtype ); send_ldap_result( pb, rc, NULL, NULL, 0, NULL ); slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); goto free_and_return; } /* if this is uniqueid attribute, set uniqueid field of the entry */ if (strcasecmp (normtype, SLAPI_ATTR_UNIQUEID) == 0) { e->e_uniqueid = slapi_ch_strdup (vals[0]->bv_val); } if(searchsubentry) searchsubentry=check_oc_subentry(e,vals,normtype); } slapi_ch_free( (void**)&normtype ); ber_bvecfree( vals ); } /* Ensure that created attributes are not used in the RDN. */ if (check_rdn_for_created_attrs(e)) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn(slapi_entry_get_sdn_const(e)), "invalid DN"); send_ldap_result( pb, LDAP_INVALID_DN_SYNTAX, NULL, "illegal attribute in RDN", 0, NULL ); goto free_and_return; } /* len, is ber_len_t, which is uint. Can't be -1. May be better to remove (len != 0) check */ if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "decoding error", 0, NULL ); goto free_and_return; } /* * in LDAPv3 there can be optional control extensions on * the end of an LDAPMessage. we need to read them in and * pass them to the backend. */ if ( (err = get_ldapmessage_controls( pb, ber, NULL )) != 0 ) { op_shared_log_error_access (pb, "ADD", slapi_sdn_get_dn (slapi_entry_get_sdn_const(e)), "failed to decode LDAP controls"); send_ldap_result( pb, err, NULL, NULL, 0, NULL ); goto free_and_return; } slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &operation->o_isroot ); slapi_pblock_set( pb, SLAPI_ADD_ENTRY, e ); if (pb->pb_conn->c_flags & CONN_FLAG_IMPORT) { /* this add is actually part of a bulk import -- punt */ handle_fast_add(pb, e); } else { op_shared_add ( pb ); } /* make sure that we don't free entry if it is successfully added */ e = NULL; free_and_return:; if (e) slapi_entry_free (e); }
static void handle_fast_add(Slapi_PBlock *pb, Slapi_Entry *entry) { Slapi_Backend *be; Slapi_Operation *operation; int ret; be = pb->pb_conn->c_bi_backend; if ((be == NULL) || (be->be_wire_import == NULL)) { /* can this even happen? */ slapi_log_err(SLAPI_LOG_ERR, "handle_fast_add", "Backend not supported\n"); send_ldap_result(pb, LDAP_NOT_SUPPORTED, NULL, NULL, 0, NULL); return; } /* ensure that the RDN values are present as attribute values */ if ((ret = slapi_entry_add_rdn_values(entry)) != LDAP_SUCCESS) { send_ldap_result(pb, ret, NULL, "failed to add RDN values", 0, NULL); return; } /* schema check */ slapi_pblock_get(pb, SLAPI_OPERATION, &operation); if (operation_is_flag_set(operation, OP_FLAG_ACTION_SCHEMA_CHECK) && (slapi_entry_schema_check(pb, entry) != 0)) { char *errtext; slapi_log_err(SLAPI_LOG_TRACE, "handle_fast_add", "Entry failed schema check\n"); slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &errtext); send_ldap_result(pb, LDAP_OBJECT_CLASS_VIOLATION, NULL, errtext, 0, NULL); slapi_entry_free(entry); return; } /* syntax check */ if (slapi_entry_syntax_check(pb, entry, 0) != 0) { char *errtext; slapi_log_err(SLAPI_LOG_TRACE, "handle_fast_add", "Entry failed syntax check\n"); slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &errtext); send_ldap_result(pb, LDAP_INVALID_SYNTAX, NULL, errtext, 0, NULL); slapi_entry_free(entry); return; } /* Check if the entry being added is a Tombstone. Could be if we are * doing a replica init. */ if (slapi_entry_attr_hasvalue(entry, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_VALUE_TOMBSTONE)) { entry->e_flags |= SLAPI_ENTRY_FLAG_TOMBSTONE; } slapi_pblock_set(pb, SLAPI_BACKEND, be); slapi_pblock_set(pb, SLAPI_BULK_IMPORT_ENTRY, entry); ret = SLAPI_BI_STATE_ADD; slapi_pblock_set(pb, SLAPI_BULK_IMPORT_STATE, &ret); ret = (*be->be_wire_import)(pb); if (ret != 0) { slapi_log_err(SLAPI_LOG_ERR, "handle_fast_add", "wire import: Error during import (%d)\n", ret); send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); /* It's our responsibility to free the entry if * be_wire_import doesn't succeed. */ slapi_entry_free(entry); /* turn off fast replica init -- import is now aborted */ pb->pb_conn->c_bi_backend = NULL; pb->pb_conn->c_flags &= ~CONN_FLAG_IMPORT; return; } send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL); return; }
static int ipa_winsync_apply_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg) { PRBool flatten = PR_TRUE; char *realm_filter = NULL; char *realm_attr = NULL; char *new_entry_filter = NULL; char *new_user_oc_attr = NULL; /* don't care about groups for now */ char *homedir_prefix_attr = NULL; char *login_shell_attr = NULL; char *default_group_attr = NULL; char *default_group_filter = NULL; char *acct_disable = NULL; int acct_disable_int; char *inactivated_filter = NULL; char *activated_filter = NULL; char **attrsvals = NULL; int ii; Slapi_Attr *testattr = NULL; PRBool forceSync = PR_FALSE; *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */ /* get flatten value */ if (!slapi_entry_attr_find(e, IPA_WINSYNC_USER_FLATTEN, &testattr) && (NULL != testattr)) { flatten = slapi_entry_attr_get_bool(e, IPA_WINSYNC_USER_FLATTEN); } /* get realm filter */ if (!(realm_filter = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_REALM_FILTER_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_REALM_FILTER_ATTR); goto done3; } /* get realm attr */ if (!(realm_attr = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_REALM_ATTR_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_REALM_ATTR_ATTR); goto done3; } /* get new_entry_filter */ if (!(new_entry_filter = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_NEW_ENTRY_FILTER_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_NEW_ENTRY_FILTER_ATTR); goto done3; } /* get new_user_oc_attr */ if (!(new_user_oc_attr = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_NEW_USER_OC_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_NEW_USER_OC_ATTR); goto done3; } /* get homedir_prefix_attr */ if (!(homedir_prefix_attr = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_HOMEDIR_PREFIX_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_HOMEDIR_PREFIX_ATTR); goto done3; } /* get login_shell_attr */ login_shell_attr = slapi_entry_attr_get_charptr(e, IPA_WINSYNC_LOGIN_SHELL_ATTR); if (!login_shell_attr) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Warning: no value given for %s", IPA_WINSYNC_LOGIN_SHELL_ATTR); } /* get default_group_attr */ if (!(default_group_attr = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_DEFAULTGROUP_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_DEFAULTGROUP_ATTR); goto done3; } /* get default_group_filter */ if (!(default_group_filter = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_DEFAULTGROUP_FILTER_ATTR))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_DEFAULTGROUP_FILTER_ATTR); goto done3; } /* get the list of attributes & values */ /* get new_user_oc_attr */ if (!(attrsvals = slapi_entry_attr_get_charray( e, IPA_WINSYNC_NEW_USER_ATTRS_VALS))) { LOG("Info: no default attributes and values given in [%s]\n", IPA_WINSYNC_NEW_USER_ATTRS_VALS); } /* get acct disable sync value */ if (!(acct_disable = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_ACCT_DISABLE))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value given for %s", IPA_WINSYNC_ACCT_DISABLE); goto done3; } acct_disable_int = parse_acct_disable(acct_disable); if (ACCT_DISABLE_INVALID == acct_disable_int) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: invalid value [%s] given for [%s] - valid " "values are " IPA_WINSYNC_ACCT_DISABLE_NONE ", " IPA_WINSYNC_ACCT_DISABLE_TO_AD ", " IPA_WINSYNC_ACCT_DISABLE_TO_DS ", or " IPA_WINSYNC_ACCT_DISABLE_BOTH, acct_disable, IPA_WINSYNC_ACCT_DISABLE); goto done3; } if (acct_disable_int != ACCT_DISABLE_NONE) { /* get inactivated group filter */ if (!(inactivated_filter = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_INACTIVATED_FILTER))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "No value given for %s - required for account " "disable sync, ignoring", IPA_WINSYNC_INACTIVATED_FILTER); } /* get activated group filter */ if (!(activated_filter = slapi_entry_attr_get_charptr( e, IPA_WINSYNC_ACTIVATED_FILTER))) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "No value given for %s - required for account " "disable sync, ignoring", IPA_WINSYNC_ACTIVATED_FILTER); } } /* get forceSync value */ if (!slapi_entry_attr_find(e, IPA_WINSYNC_FORCE_SYNC, &testattr) && (NULL != testattr)) { forceSync = slapi_entry_attr_get_bool(e, IPA_WINSYNC_FORCE_SYNC); } /* if we got here, we have valid values for everything set the config entry */ slapi_lock_mutex(theConfig.lock); slapi_entry_free(theConfig.config_e); theConfig.config_e = slapi_entry_alloc(); slapi_entry_init(theConfig.config_e, slapi_ch_strdup(""), NULL); /* format of *attrsvals is "attrname value" */ /* attrname <space> value */ /* value may contain spaces - attrname is everything up to the first space - value is everything after the first space */ for (ii = 0; attrsvals && attrsvals[ii]; ++ii) { int rc; Slapi_Value *sva[2]; Slapi_Value *sv = NULL; char *val = strchr(attrsvals[ii], ' '); if (!val || !*(val+1)) { /* incorrect format or no value */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: no value or incorrect value given for [%s] " "value [%s] index [%d] - correct format is attrname SPACE value", IPA_WINSYNC_NEW_USER_ATTRS_VALS, attrsvals[ii], ii); goto done3; } *val++ = '\0'; /* separate attr from val */ sv = slapi_value_new_string(val); sva[0] = sv; sva[1] = NULL; if ((rc = slapi_entry_add_values_sv(theConfig.config_e, attrsvals[ii], sva)) && (rc != LDAP_SUCCESS)) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Error: could not add value [%s] for attribute name " "[%s] - ldap error [%d: %s]", val, attrsvals[ii], rc, ldap_err2string(rc)); slapi_entry_free(theConfig.config_e); theConfig.config_e = NULL; slapi_value_free(&sv); goto done3; } slapi_value_free(&sv); } /* all of the attrs and vals have been set - set the other values */ slapi_ch_free_string(&theConfig.realm_filter); theConfig.realm_filter = realm_filter; realm_filter = NULL; slapi_ch_free_string(&theConfig.realm_attr); theConfig.realm_attr = realm_attr; realm_attr = NULL; slapi_ch_free_string(&theConfig.new_entry_filter); theConfig.new_entry_filter = new_entry_filter; new_entry_filter = NULL; slapi_ch_free_string(&theConfig.new_user_oc_attr); theConfig.new_user_oc_attr = new_user_oc_attr; new_user_oc_attr = NULL; slapi_ch_free_string(&theConfig.homedir_prefix_attr); theConfig.homedir_prefix_attr = homedir_prefix_attr; homedir_prefix_attr = NULL; if (login_shell_attr) { slapi_ch_free_string(&theConfig.login_shell_attr); theConfig.login_shell_attr = login_shell_attr; login_shell_attr = NULL; } slapi_ch_free_string(&theConfig.default_group_attr); theConfig.default_group_attr = default_group_attr; default_group_attr = NULL; slapi_ch_free_string(&theConfig.default_group_filter); theConfig.default_group_filter = default_group_filter; default_group_filter = NULL; theConfig.flatten = flatten; theConfig.acct_disable = parse_acct_disable(acct_disable); slapi_ch_free_string(&theConfig.inactivated_filter); theConfig.inactivated_filter = inactivated_filter; inactivated_filter = NULL; slapi_ch_free_string(&theConfig.activated_filter); theConfig.activated_filter = activated_filter; activated_filter = NULL; theConfig.forceSync = forceSync; /* success */ *returncode = LDAP_SUCCESS; done3: slapi_unlock_mutex(theConfig.lock); slapi_ch_free_string(&realm_filter); slapi_ch_free_string(&realm_attr); slapi_ch_free_string(&new_entry_filter); slapi_ch_free_string(&new_user_oc_attr); slapi_ch_free_string(&homedir_prefix_attr); slapi_ch_free_string(&login_shell_attr); slapi_ch_free_string(&default_group_attr); slapi_ch_free_string(&default_group_filter); slapi_ch_array_free(attrsvals); attrsvals = NULL; slapi_ch_free_string(&acct_disable); slapi_ch_free_string(&inactivated_filter); slapi_ch_free_string(&activated_filter); if (*returncode != LDAP_SUCCESS) { return SLAPI_DSE_CALLBACK_ERROR; } else { return SLAPI_DSE_CALLBACK_OK; } }
/* Code shared between regular and internal add operation */ static void op_shared_add (Slapi_PBlock *pb) { Slapi_Operation *operation; Slapi_Entry *e, *pse; Slapi_Backend *be = NULL; int err; int internal_op, repl_op, legacy_op, lastmod; char *pwdtype = NULL; Slapi_Attr *attr = NULL; Slapi_Entry *referral; char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE]; struct slapdplugin *p = NULL; char *proxydn = NULL; char *proxystr = NULL; int proxy_err = LDAP_SUCCESS; char *errtext = NULL; Slapi_DN *sdn = NULL; passwdPolicy *pwpolicy; slapi_pblock_get (pb, SLAPI_OPERATION, &operation); slapi_pblock_get (pb, SLAPI_ADD_ENTRY, &e); slapi_pblock_get (pb, SLAPI_IS_REPLICATED_OPERATION, &repl_op); slapi_pblock_get (pb, SLAPI_IS_LEGACY_REPLICATED_OPERATION, &legacy_op); internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL); pwpolicy = new_passwdPolicy(pb, slapi_entry_get_dn(e)); /* target spec is used to decide which plugins are applicable for the operation */ operation_set_target_spec (operation, slapi_entry_get_sdn (e)); if ((err = slapi_entry_add_rdn_values(e)) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, "failed to add RDN values", 0, NULL); goto done; } /* get the proxy auth dn if the proxy auth control is present */ proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext); if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) { if (proxydn) { proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); } if ( !internal_op ) { slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d ADD dn=\"%s\"%s\n", pb->pb_conn->c_connid, operation->o_opid, slapi_entry_get_dn_const(e), proxystr ? proxystr : ""); } else { slapi_log_access(LDAP_DEBUG_ARGS, "conn=%s op=%d ADD dn=\"%s\"\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, slapi_entry_get_dn_const(e)); } } /* If we encountered an error parsing the proxy control, return an error * to the client. We do this here to ensure that we log the operation first. */ if (proxy_err != LDAP_SUCCESS) { send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL); goto done; } /* * We could be serving multiple database backends. Select the * appropriate one. */ if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf, sizeof(errorbuf))) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, errorbuf, 0, NULL); be = NULL; goto done; } if (referral) { int managedsait; slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); if (managedsait) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot update referral", 0, NULL); slapi_entry_free(referral); goto done; } slapi_pblock_set(pb, SLAPI_TARGET_SDN, (void*)operation_get_target_spec (operation)); send_referrals_from_entry(pb,referral); slapi_entry_free(referral); goto done; } if (!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA)) { Slapi_Value **unhashed_password_vals = NULL; Slapi_Value **present_values = NULL; /* Setting unhashed password to the entry extension. */ if (repl_op) { /* replicated add ==> get unhashed pw from entry, if any. * set it to the extension */ slapi_entry_attr_find(e, PSEUDO_ATTR_UNHASHEDUSERPASSWORD, &attr); if (attr) { present_values = attr_get_present_values(attr); valuearray_add_valuearray(&unhashed_password_vals, present_values, 0); #if !defined(USE_OLD_UNHASHED) /* and remove it from the entry. */ slapi_entry_attr_delete(e, PSEUDO_ATTR_UNHASHEDUSERPASSWORD); #endif } } else { /* ordinary add ==> * get unhashed pw from userpassword before encrypting it */ /* look for user password attribute */ slapi_entry_attr_find(e, SLAPI_USERPWD_ATTR, &attr); if (attr) { Slapi_Value **vals = NULL; /* Set the backend in the pblock. * The slapi_access_allowed function * needs this set to work properly. */ slapi_pblock_set(pb, SLAPI_BACKEND, slapi_be_select(slapi_entry_get_sdn_const(e))); /* Check ACI before checking password syntax */ if ((err = slapi_access_allowed(pb, e, SLAPI_USERPWD_ATTR, NULL, SLAPI_ACL_ADD)) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, "Insufficient 'add' privilege to the " "'userPassword' attribute", 0, NULL); goto done; } /* * Check password syntax, unless this is a pwd admin/rootDN */ present_values = attr_get_present_values(attr); if (!pw_is_pwp_admin(pb, pwpolicy) && check_pw_syntax(pb, slapi_entry_get_sdn_const(e), present_values, NULL, e, 0) != 0) { /* error result is sent from check_pw_syntax */ goto done; } /* pw syntax is valid */ valuearray_add_valuearray(&unhashed_password_vals, present_values, 0); valuearray_add_valuearray(&vals, present_values, 0); pw_encodevals_ext(pb, slapi_entry_get_sdn (e), vals); add_password_attrs(pb, operation, e); slapi_entry_attr_replace_sv(e, SLAPI_USERPWD_ATTR, vals); valuearray_free(&vals); #if defined(USE_OLD_UNHASHED) /* Add the unhashed password pseudo-attribute to the entry */ pwdtype = slapi_attr_syntax_normalize(PSEUDO_ATTR_UNHASHEDUSERPASSWORD); slapi_entry_add_values_sv(e, pwdtype, unhashed_password_vals); #endif } } if (unhashed_password_vals && (SLAPD_UNHASHED_PW_OFF != config_get_unhashed_pw_switch())) { /* unhashed_password_vals is consumed if successful. */ err = slapi_pw_set_entry_ext(e, unhashed_password_vals, SLAPI_EXT_SET_ADD); if (err) { valuearray_free(&unhashed_password_vals); } } #if defined(THISISTEST) { /* test code to retrieve an unhashed pw from the entry extention & * PSEUDO_ATTR_UNHASHEDUSERPASSWORD attribute */ char *test_str = slapi_get_first_clear_text_pw(e); if (test_str) { slapi_log_err(SLAPI_LOG_ERR, "Value from extension: %s\n", test_str); slapi_ch_free_string(&test_str); } #if defined(USE_OLD_UNHASHED) test_str = slapi_entry_attr_get_charptr(e, PSEUDO_ATTR_UNHASHEDUSERPASSWORD); if (test_str) { slapi_log_err(SLAPI_LOG_ERR, "Value from attr: %s\n", test_str); slapi_ch_free_string(&test_str); } #endif /* USE_OLD_UNHASHED */ } #endif /* THISISTEST */ /* look for multiple backend local credentials or replication local credentials */ for ( p = get_plugin_list(PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME); p != NULL && !repl_op; p = p->plg_next ) { char *L_attr = NULL; int i=0; /* Get the appropriate decoding function */ for ( L_attr = p->plg_argv[i]; i<p->plg_argc; L_attr = p->plg_argv[++i]) { /* look for multiple backend local credentials or replication local credentials */ char *L_normalized = slapi_attr_syntax_normalize(L_attr); slapi_entry_attr_find(e, L_normalized, &attr); if (attr) { Slapi_Value **present_values = NULL; Slapi_Value **vals = NULL; present_values= attr_get_present_values(attr); valuearray_add_valuearray(&vals, present_values, 0); pw_rever_encode(vals, L_normalized); slapi_entry_attr_replace_sv(e, L_normalized, vals); valuearray_free(&vals); } if (L_normalized) slapi_ch_free ((void**)&L_normalized); } } } slapi_pblock_set(pb, SLAPI_BACKEND, be); if (!repl_op) { /* can get lastmod only after backend is selected */ slapi_pblock_get(pb, SLAPI_BE_LASTMOD, &lastmod); if (lastmod && add_created_attrs(pb, e) != 0) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot insert computed attributes", 0, NULL); goto done; } /* expand objectClass values to reflect the inheritance hierarchy */ slapi_schema_expand_objectclasses( e ); } /* uniqueid needs to be generated for entries added during legacy replication */ if (legacy_op){ if (add_uniqueid(e) != UID_SUCCESS) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot insert computed attributes", 0, NULL); goto done; } } /* * call the pre-add plugins. if they succeed, call * the backend add function. then call the post-add * plugins. */ sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(e)); slapi_pblock_set(pb, SLAPI_ADD_TARGET_SDN, (void *)sdn); if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN : SLAPI_PLUGIN_PRE_ADD_FN) == SLAPI_PLUGIN_SUCCESS) { int rc; Slapi_Entry *ec; Slapi_DN *add_target_sdn = NULL; Slapi_Entry *save_e = NULL; slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); set_db_default_result_handlers(pb); /* because be_add frees the entry */ ec = slapi_entry_dup(e); add_target_sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(ec)); slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); slapi_pblock_set(pb, SLAPI_ADD_TARGET_SDN, add_target_sdn); if (be->be_add != NULL) { rc = (*be->be_add)(pb); /* backend may change this if errors and not consumed */ slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &save_e); slapi_pblock_set(pb, SLAPI_ADD_ENTRY, ec); if (rc == 0) { /* acl is not enabled for internal operations */ /* don't update aci store for remote acis */ if ((!internal_op) && (!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))) { plugin_call_acl_mods_update (pb, SLAPI_OPERATION_ADD); } if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT)) { write_audit_log_entry(pb); /* Record the operation in the audit log */ } slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); do_ps_service(pse, NULL, LDAP_CHANGETYPE_ADD, 0); /* * If be_add succeeded, then e is consumed except the resurrect case. * If it is resurrect, the corresponding tombstone entry is resurrected * and put into the cache. * Otherwise, we set e to NULL to prevent freeing it ourselves. */ if (operation_is_flag_set(operation,OP_FLAG_RESURECT_ENTRY) && save_e) { e = save_e; } else { e = NULL; } } else { /* PR_ASSERT(!save_e); save_e is supposed to be freed in the backend. */ e = save_e; if (rc == SLAPI_FAIL_DISKFULL) { operation_out_of_disk_space(); goto done; } /* If the disk is full we don't want to make it worse ... */ if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT)) { write_auditfail_log_entry(pb); /* Record the operation in the audit log */ } } } else { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL); } slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc); plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_ADD_FN : SLAPI_PLUGIN_POST_ADD_FN); slapi_entry_free(ec); } slapi_pblock_get(pb, SLAPI_ADD_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); done: if (be) slapi_be_Unlock(be); slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &pse); slapi_entry_free(pse); slapi_ch_free((void **)&operation->o_params.p.p_add.parentuniqueid); slapi_entry_free(e); slapi_pblock_set(pb, SLAPI_ADD_ENTRY, NULL); slapi_ch_free((void**)&pwdtype); slapi_ch_free_string(&proxydn); slapi_ch_free_string(&proxystr); }
/* Extract just the configuration information we need for bootstrapping purposes 1) set up error logging 2) disable syntax checking 3) load the syntax plugins etc. */ int slapd_bootstrap_config(const char *configdir) { char configfile[MAXPATHLEN+1]; PRFileInfo prfinfo; int rc = 0; /* Fail */ int done = 0; PRInt32 nr = 0; PRFileDesc *prfd = 0; char *buf = 0; char *lastp = 0; char *entrystr = 0; if (NULL == configdir) { slapi_log_error(SLAPI_LOG_FATAL, "startup", "Passed null config directory\n"); return rc; /* Fail */ } PR_snprintf(configfile, sizeof(configfile), "%s/%s", configdir, CONFIG_FILENAME); if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS ) { /* the "real" file does not exist; see if there is a tmpfile */ char tmpfile[MAXPATHLEN+1]; slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s does not exist\n", configfile); PR_snprintf(tmpfile, sizeof(tmpfile), "%s/%s.tmp", configdir, CONFIG_FILENAME); if ( PR_GetFileInfo( tmpfile, &prfinfo ) == PR_SUCCESS ) { rc = PR_Rename(tmpfile, configfile); if (rc == PR_SUCCESS) { slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s was restored from backup %s\n", configfile, tmpfile); } else { slapi_log_error(SLAPI_LOG_FATAL, "config", "The configuration file %s was not restored from backup %s, error %d\n", configfile, tmpfile, rc); return rc; /* Fail */ } } else { slapi_log_error(SLAPI_LOG_FATAL, "config", "The backup configuration file %s does not exist, either.\n", tmpfile); return rc; /* Fail */ } } if ( (rc = PR_GetFileInfo( configfile, &prfinfo )) != PR_SUCCESS ) { PRErrorCode prerr = PR_GetError(); slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be accessed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", configfile, prerr, slapd_pr_strerror(prerr)); return rc; } else if (( prfd = PR_Open( configfile, PR_RDONLY, SLAPD_DEFAULT_FILE_MODE )) == NULL ) { PRErrorCode prerr = PR_GetError(); slapi_log_error(SLAPI_LOG_FATAL, "config", "The given config file %s could not be opened for reading, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", configfile, prerr, slapd_pr_strerror(prerr)); return rc; /* Fail */ } else { /* read the entire file into core */ buf = slapi_ch_malloc( prfinfo.size + 1 ); if (( nr = slapi_read_buffer( prfd, buf, prfinfo.size )) < 0 ) { slapi_log_error(SLAPI_LOG_FATAL, "config", "Could only read %d of %d bytes from config file %s\n", nr, prfinfo.size, configfile); rc = 0; /* Fail */ done= 1; } (void)PR_Close(prfd); buf[ nr ] = '\0'; if(!done) { char workpath[MAXPATHLEN+1]; char loglevel[BUFSIZ]; char maxdescriptors[BUFSIZ]; char val[BUFSIZ]; char _localuser[BUFSIZ]; char logenabled[BUFSIZ]; char schemacheck[BUFSIZ]; char syntaxcheck[BUFSIZ]; char syntaxlogging[BUFSIZ]; char plugintracking[BUFSIZ]; char dn_validate_strict[BUFSIZ]; Slapi_DN plug_dn; workpath[0] = loglevel[0] = maxdescriptors[0] = '\0'; val[0] = logenabled[0] = schemacheck[0] = syntaxcheck[0] = '\0'; syntaxlogging[0] = _localuser[0] = '\0'; plugintracking [0] = dn_validate_strict[0] = '\0'; /* Convert LDIF to entry structures */ slapi_sdn_init_ndn_byref(&plug_dn, PLUGIN_BASE_DN); while ((entrystr = dse_read_next_entry(buf, &lastp)) != NULL) { char errorbuf[BUFSIZ]; /* * XXXmcs: it would be better to also pass * SLAPI_STR2ENTRY_REMOVEDUPVALS in the flags, but * duplicate value checking requires that the syntax * and schema subsystems be initialized... and they * are not yet. */ Slapi_Entry *e = slapi_str2entry(entrystr, SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF); if (e == NULL) { LDAPDebug(LDAP_DEBUG_ANY, "The entry [%s] in the configfile %s was empty or could not be parsed\n", entrystr, configfile, 0); continue; } /* increase file descriptors */ #if !defined(_WIN32) && !defined(AIX) if (!maxdescriptors[0] && entry_has_attr_and_value(e, CONFIG_MAXDESCRIPTORS_ATTRIBUTE, maxdescriptors, sizeof(maxdescriptors))) { if (config_set_maxdescriptors( CONFIG_MAXDESCRIPTORS_ATTRIBUTE, maxdescriptors, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_MAXDESCRIPTORS_ATTRIBUTE, errorbuf); } } #endif /* !defined(_WIN32) && !defined(AIX) */ /* see if we need to enable error logging */ if (!logenabled[0] && entry_has_attr_and_value(e, CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, logenabled, sizeof(logenabled))) { if (log_set_logging( CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, logenabled, SLAPD_ERROR_LOG, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ERRORLOG_LOGGING_ENABLED_ATTRIBUTE, errorbuf); } } #ifndef _WIN32 /* set the local user name; needed to set up error log */ if (!_localuser[0] && entry_has_attr_and_value(e, CONFIG_LOCALUSER_ATTRIBUTE, _localuser, sizeof(_localuser))) { if (config_set_localuser(CONFIG_LOCALUSER_ATTRIBUTE, _localuser, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LOCALUSER_ATTRIBUTE, errorbuf); } } #endif /* set the log file name */ workpath[0] = '\0'; if (!workpath[0] && entry_has_attr_and_value(e, CONFIG_ERRORLOG_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_errorlog(CONFIG_ERRORLOG_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_ERRORLOG_ATTRIBUTE, errorbuf); } } /* set the error log level */ if (!loglevel[0] && entry_has_attr_and_value(e, CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, sizeof(loglevel))) { if (should_detach || !config_get_errorlog_level()) { /* -d wasn't on command line */ if (config_set_errorlog_level(CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LOGLEVEL_ATTRIBUTE, errorbuf); } } else { LDAPDebug(LDAP_DEBUG_ANY, "%s: ignoring %s (since -d %d was given on " "the command line)\n", CONFIG_LOGLEVEL_ATTRIBUTE, loglevel, config_get_errorlog_level()); } } /* set the cert dir; needed in slapd_nss_init */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_CERTDIR_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_certdir(CONFIG_CERTDIR_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_CERTDIR_ATTRIBUTE, errorbuf); } } /* set the sasl path; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_SASLPATH_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_saslpath(CONFIG_SASLPATH_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_SASLPATH_ATTRIBUTE, errorbuf); } } #if defined(ENABLE_LDAPI) /* set the ldapi file path; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_LDAPI_FILENAME_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_ldapi_filename(CONFIG_LDAPI_FILENAME_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LDAPI_FILENAME_ATTRIBUTE, errorbuf); } } /* set the ldapi switch; needed in main */ workpath[0] = '\0'; if (entry_has_attr_and_value(e, CONFIG_LDAPI_SWITCH_ATTRIBUTE, workpath, sizeof(workpath))) { if (config_set_ldapi_switch(CONFIG_LDAPI_SWITCH_ATTRIBUTE, workpath, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s. \n", configfile, CONFIG_LDAPI_SWITCH_ATTRIBUTE, errorbuf); } } #endif /* see if the entry is a child of the plugin base dn */ if (slapi_sdn_isparent(&plug_dn, slapi_entry_get_sdn_const(e))) { if (entry_has_attr_and_value(e, "objectclass", "nsSlapdPlugin", 0) && (entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "syntax", 0) || entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "matchingrule", 0))) { /* add the syntax/matching scheme rule plugin */ if (plugin_setup(e, 0, 0, 1)) { LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0); rc = 0; slapi_sdn_done(&plug_dn); goto bail; } } } /* see if the entry is a grand child of the plugin base dn */ if (slapi_sdn_isgrandparent(&plug_dn, slapi_entry_get_sdn_const(e))) { if (entry_has_attr_and_value(e, "objectclass", "nsSlapdPlugin", 0) && ( entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "pwdstoragescheme", 0) || entry_has_attr_and_value(e, ATTR_PLUGIN_TYPE, "reverpwdstoragescheme", 0) ) ) { /* add the pwd storage scheme rule plugin */ if (plugin_setup(e, 0, 0, 1)) { LDAPDebug(LDAP_DEBUG_ANY, "The plugin entry [%s] in the configfile %s was invalid\n", slapi_entry_get_dn(e), configfile, 0); rc = 0; slapi_sdn_done(&plug_dn); goto bail; } } } /* see if we need to disable schema checking */ if (!schemacheck[0] && entry_has_attr_and_value(e, CONFIG_SCHEMACHECK_ATTRIBUTE, schemacheck, sizeof(schemacheck))) { if (config_set_schemacheck(CONFIG_SCHEMACHECK_ATTRIBUTE, schemacheck, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SCHEMACHECK_ATTRIBUTE, errorbuf); } } /* see if we need to enable plugin binddn tracking */ if (!plugintracking[0] && entry_has_attr_and_value(e, CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, plugintracking, sizeof(plugintracking))) { if (config_set_plugin_tracking(CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, plugintracking, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, errorbuf); } } /* see if we need to enable syntax checking */ if (!syntaxcheck[0] && entry_has_attr_and_value(e, CONFIG_SYNTAXCHECK_ATTRIBUTE, syntaxcheck, sizeof(syntaxcheck))) { if (config_set_syntaxcheck(CONFIG_SYNTAXCHECK_ATTRIBUTE, syntaxcheck, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SYNTAXCHECK_ATTRIBUTE, errorbuf); } } /* see if we need to enable syntax warnings */ if (!syntaxlogging[0] && entry_has_attr_and_value(e, CONFIG_SYNTAXLOGGING_ATTRIBUTE, syntaxlogging, sizeof(syntaxlogging))) { if (config_set_syntaxlogging(CONFIG_SYNTAXLOGGING_ATTRIBUTE, syntaxlogging, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SYNTAXLOGGING_ATTRIBUTE, errorbuf); } } /* see if we need to enable strict dn validation */ if (!dn_validate_strict[0] && entry_has_attr_and_value(e, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, dn_validate_strict, sizeof(dn_validate_strict))) { if (config_set_dn_validate_strict(CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, dn_validate_strict, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_DN_VALIDATE_STRICT_ATTRIBUTE, errorbuf); } } /* see if we need to expect quoted schema values */ if (entry_has_attr_and_value(e, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, val, sizeof(val))) { if (config_set_enquote_sup_oc( CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to maintain case in AT and OC names */ if (entry_has_attr_and_value(e, CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val, sizeof(val))) { if (config_set_return_exact_case( CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_RETURN_EXACT_CASE_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we should allow attr. name exceptions, e.g. '_'s */ if (entry_has_attr_and_value(e, CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, val, sizeof(val))) { if (config_set_attrname_exceptions( CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to maintain schema compatibility with 4.x */ if (entry_has_attr_and_value(e, CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val, sizeof(val))) { if (config_set_ds4_compatible_schema( CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_DS4_COMPATIBLE_SCHEMA_ATTRIBUTE, errorbuf); } val[0] = 0; } /* see if we need to allow trailing spaces in OC and AT names */ if (entry_has_attr_and_value(e, CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val, sizeof(val))) { if (config_set_schema_ignore_trailing_spaces( CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_SCHEMA_IGNORE_TRAILING_SPACES, errorbuf); } val[0] = 0; } /* rfc1274-rewrite */ if (entry_has_attr_and_value(e, CONFIG_REWRITE_RFC1274_ATTRIBUTE, val, sizeof(val))) { if (config_set_rewrite_rfc1274( CONFIG_REWRITE_RFC1274_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_REWRITE_RFC1274_ATTRIBUTE, errorbuf); } val[0] = 0; } /* what is our localhost name */ if (entry_has_attr_and_value(e, CONFIG_LOCALHOST_ATTRIBUTE, val, sizeof(val))) { if (config_set_localhost( CONFIG_LOCALHOST_ATTRIBUTE, val, errorbuf, CONFIG_APPLY) != LDAP_SUCCESS) { LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile, CONFIG_LOCALHOST_ATTRIBUTE, errorbuf); } val[0] = 0; } if (e) slapi_entry_free(e); } /* kexcoff: initialize rootpwstoragescheme and pw_storagescheme * if not explicilty set in the config file */ if ( config_set_storagescheme() ) { /* default scheme plugin not loaded */ slapi_log_error(SLAPI_LOG_FATAL, "startup", "The default password storage scheme SSHA could not be read or was not found in the file %s. It is mandatory.\n", configfile); exit (1); } else { slapi_sdn_done(&plug_dn); rc= 1; /* OK */ } } slapi_ch_free_string(&buf); } bail: slapi_ch_free_string(&buf); return rc; }
static void op_shared_delete (Slapi_PBlock *pb) { char *rawdn = NULL; const char *dn = NULL; Slapi_Backend *be = NULL; int internal_op; Slapi_DN *sdn = NULL; Slapi_Operation *operation; Slapi_Entry *referral; Slapi_Entry *ecopy = NULL; char errorbuf[BUFSIZ]; int err; char *proxydn = NULL; char *proxystr = NULL; int proxy_err = LDAP_SUCCESS; char *errtext = NULL; slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &rawdn); slapi_pblock_get(pb, SLAPI_OPERATION, &operation); internal_op= operation_is_flag_set(operation, OP_FLAG_INTERNAL); sdn = slapi_sdn_new_dn_byval(rawdn); dn = slapi_sdn_get_dn(sdn); slapi_pblock_set(pb, SLAPI_DELETE_TARGET_SDN, (void*)sdn); if (rawdn && (strlen(rawdn) > 0) && (NULL == dn)) { /* normalization failed */ op_shared_log_error_access(pb, "DEL", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); goto free_and_return; } /* target spec is used to decide which plugins are applicable for the operation */ operation_set_target_spec (operation, sdn); /* get the proxy auth dn if the proxy auth control is present */ proxy_err = proxyauth_get_dn(pb, &proxydn, &errtext); if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_ACCESS)) { if (proxydn) { proxystr = slapi_ch_smprintf(" authzid=\"%s\"", proxydn); } if (!internal_op ) { slapi_log_access(LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " op=%d DEL dn=\"%s\"%s\n", pb->pb_conn->c_connid, pb->pb_op->o_opid, slapi_sdn_get_dn(sdn), proxystr ? proxystr: ""); } else { slapi_log_access(LDAP_DEBUG_ARGS, "conn=%s op=%d DEL dn=\"%s\"%s\n", LOG_INTERNAL_OP_CON_ID, LOG_INTERNAL_OP_OP_ID, slapi_sdn_get_dn(sdn), proxystr ? proxystr: ""); } } /* If we encountered an error parsing the proxy control, return an error * to the client. We do this here to ensure that we log the operation first. */ if (proxy_err != LDAP_SUCCESS) { send_ldap_result(pb, proxy_err, NULL, errtext, 0, NULL); goto free_and_return; } /* * We could be serving multiple database backends. Select the * appropriate one. */ if ((err = slapi_mapping_tree_select(pb, &be, &referral, errorbuf)) != LDAP_SUCCESS) { send_ldap_result(pb, err, NULL, errorbuf, 0, NULL); be = NULL; goto free_and_return; } if (referral) { int managedsait; slapi_pblock_get(pb, SLAPI_MANAGEDSAIT, &managedsait); if (managedsait) { send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "cannot delete referral", 0, NULL); slapi_entry_free(referral); goto free_and_return; } send_referrals_from_entry(pb,referral); slapi_entry_free(referral); goto free_and_return; } slapi_pblock_set(pb, SLAPI_BACKEND, be); /* * call the pre-delete plugins. if they succeed, call * the backend delete function. then call the * post-delete plugins. */ if (plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN : SLAPI_PLUGIN_PRE_DELETE_FN) == 0) { int rc; slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database); set_db_default_result_handlers(pb); if (be->be_delete != NULL) { if ((rc = (*be->be_delete)(pb)) == 0) { /* we don't perform acl check for internal operations */ /* Dont update aci store for remote acis */ if ((!internal_op) && (!slapi_be_is_flag_set(be,SLAPI_BE_FLAG_REMOTE_DATA))) plugin_call_acl_mods_update (pb, SLAPI_OPERATION_DELETE); if (operation_is_flag_set(operation,OP_FLAG_ACTION_LOG_AUDIT)) write_audit_log_entry(pb); /* Record the operation in the audit log */ slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &ecopy); do_ps_service(ecopy, NULL, LDAP_CHANGETYPE_DELETE, 0); } else { if (rc == SLAPI_FAIL_DISKFULL) { operation_out_of_disk_space(); goto free_and_return; } } } slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &rc); plugin_call_plugins(pb, internal_op ? SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN : SLAPI_PLUGIN_POST_DELETE_FN); } free_and_return: if (be) { slapi_be_Unlock(be); } { char *coldn = NULL; Slapi_Entry *epre = NULL, *eparent = NULL; slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &epre); slapi_pblock_get(pb, SLAPI_DELETE_GLUE_PARENT_ENTRY, &eparent); slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, NULL); slapi_pblock_set(pb, SLAPI_DELETE_GLUE_PARENT_ENTRY, NULL); if (epre == eparent) { eparent = NULL; } slapi_entry_free(epre); slapi_entry_free(eparent); slapi_pblock_get(pb, SLAPI_URP_NAMING_COLLISION_DN, &coldn); slapi_ch_free_string(&coldn); } slapi_pblock_get(pb, SLAPI_DELETE_TARGET_SDN, &sdn); slapi_sdn_free(&sdn); slapi_ch_free_string(&proxydn); slapi_ch_free_string(&proxystr); }
/* * Check if we are modifying the config, or changing the shared config entry */ int memberof_shared_config_validate(Slapi_PBlock *pb) { Slapi_Entry *e = 0; Slapi_Entry *resulting_e = 0; Slapi_Entry *config_entry = NULL; Slapi_DN *sdn = NULL; Slapi_DN *config_sdn = NULL; Slapi_Mods *smods = 0; Slapi_Mod *smod = NULL, *nextmod = NULL; LDAPMod **mods = NULL; char returntext[SLAPI_DSE_RETURNTEXT_SIZE]; char *configarea_dn = NULL; int ret = SLAPI_PLUGIN_SUCCESS; slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn); if (slapi_sdn_compare(sdn, memberof_get_plugin_area()) == 0 || slapi_sdn_compare(sdn, memberof_get_config_area()) == 0) { slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e); if(e){ /* * Create a copy of the entry and apply the * mods to create the resulting entry. */ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); smods = slapi_mods_new(); slapi_mods_init_byref(smods, mods); resulting_e = slapi_entry_dup(e); if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS)) { /* we don't care about this, the update is invalid and will be caught later */ goto bail; } if (slapi_sdn_compare(sdn, memberof_get_plugin_area())){ /* * This entry is a plugin config area entry, validate it. */ if( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) { ret = LDAP_UNWILLING_TO_PERFORM; } } else { /* * This is the memberOf plugin entry, check if we are adding/replacing the * plugin config area. */ nextmod = slapi_mod_new(); for (smod = slapi_mods_get_first_smod(smods, nextmod); smod != NULL; smod = slapi_mods_get_next_smod(smods, nextmod) ) { if ( PL_strcasecmp(SLAPI_PLUGIN_SHARED_CONFIG_AREA, slapi_mod_get_type(smod)) == 0 ) { /* * Okay, we are modifying the plugin config area, we only care about * adds and replaces. */ if(SLAPI_IS_MOD_REPLACE(slapi_mod_get_operation(smod)) || SLAPI_IS_MOD_ADD(slapi_mod_get_operation(smod))) { struct berval *bv = NULL; int rc = 0; bv = slapi_mod_get_first_value(smod); configarea_dn = slapi_ch_strdup(bv->bv_val); if(configarea_dn){ /* Check the DN syntax */ rc = slapi_dn_syntax_check(pb, configarea_dn, 1); if (rc) { /* syntax check failed */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s does not contain a valid DN (%s)", SLAPI_PLUGIN_SHARED_CONFIG_AREA, configarea_dn); ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } /* Check if the plugin config area entry exists */ if((config_sdn = slapi_sdn_new_dn_byval(configarea_dn))){ rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, memberof_get_plugin_id()); if(config_entry){ int err = 0; /* * Validate the settings from the new config area. */ if ( memberof_validate_config(pb, NULL, config_entry, &err, returntext,0) == SLAPI_DSE_CALLBACK_ERROR ) { ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } } else { /* The config area does not exist */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Unable to locate shared config entry (%s) error %d", slapi_sdn_get_dn(memberof_get_config_area()), rc); ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } } } slapi_ch_free_string(&configarea_dn); slapi_sdn_free(&config_sdn); } } } } } else { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Unable to locate shared config entry (%s)", slapi_sdn_get_dn(memberof_get_config_area())); ret = LDAP_UNWILLING_TO_PERFORM; } } bail: if (ret){ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, returntext); slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate - %s/n", returntext); } slapi_sdn_free(&config_sdn); if(nextmod) slapi_mod_free(&nextmod); slapi_mods_free(&smods); slapi_entry_free(resulting_e); slapi_entry_free(config_entry); slapi_ch_free_string(&configarea_dn); return ret; }
/* * Perform the agreement/domain specific configuration. * IPA stores its configuration in the tree. We use the * ds_subtree to search for the domain/realm specific * configuration entries. */ void ipa_winsync_config_refresh_domain( void *cbdata, const Slapi_DN *ds_subtree, const Slapi_DN *ad_subtree ) { IPA_WinSync_Domain_Config *iwdc = (IPA_WinSync_Domain_Config *)cbdata; Slapi_DN *config_dn = slapi_sdn_dup(ds_subtree); char *realm_filter = NULL; char *realm_attr = NULL; char *new_entry_filter = NULL; char *new_user_oc_attr = NULL; /* don't care about groups for now */ char *homedir_prefix_attr = NULL; char *login_shell_attr = NULL; char *default_group_attr = NULL; char *default_group_filter = NULL; char *default_group_name = NULL; char *real_group_filter = NULL; char *default_gid = NULL; Slapi_ValueSet *new_user_objclasses = NULL; /* don't care about groups for now */ int loopdone = 0; int search_scope = LDAP_SCOPE_SUBTREE; int ret = LDAP_SUCCESS; int acct_disable; char *inactivated_filter = NULL; char *activated_filter = NULL; char *inactivated_group_dn = NULL; char *activated_group_dn = NULL; int upg = -1; slapi_lock_mutex(theConfig.lock); realm_filter = slapi_ch_strdup(theConfig.realm_filter); realm_attr = slapi_ch_strdup(theConfig.realm_attr); new_entry_filter = slapi_ch_strdup(theConfig.new_entry_filter); new_user_oc_attr = slapi_ch_strdup(theConfig.new_user_oc_attr); homedir_prefix_attr = slapi_ch_strdup(theConfig.homedir_prefix_attr); if (theConfig.login_shell_attr) { login_shell_attr = slapi_ch_strdup(theConfig.login_shell_attr); } default_group_attr = slapi_ch_strdup(theConfig.default_group_attr); default_group_filter = slapi_ch_strdup(theConfig.default_group_filter); acct_disable = theConfig.acct_disable; if (acct_disable != ACCT_DISABLE_NONE) { if (theConfig.inactivated_filter) { inactivated_filter = slapi_ch_strdup(theConfig.inactivated_filter); } if (theConfig.activated_filter) { activated_filter = slapi_ch_strdup(theConfig.activated_filter); } } slapi_unlock_mutex(theConfig.lock); /* starting at ds_subtree, search for the entry containing the Kerberos realm to use */ slapi_ch_free_string(&iwdc->realm_name); while(!loopdone && !slapi_sdn_isempty(config_dn)) { ret = internal_find_entry_get_attr_val(config_dn, search_scope, realm_filter, realm_attr, NULL, &iwdc->realm_name); if ((0 == ret) && iwdc->realm_name) { loopdone = 1; } else if ((LDAP_NO_SUCH_OBJECT == ret) && !iwdc->realm_name) { /* try again */ Slapi_DN *parent_dn = slapi_sdn_new(); slapi_sdn_get_parent(config_dn, parent_dn); slapi_sdn_free(&config_dn); config_dn = parent_dn; } else { /* error */ goto out; } } if (!iwdc->realm_name) { /* error - could not find the IPA config entry with the realm name */ LOG_FATAL("Error: could not find the entry containing the realm name " "[%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), realm_filter, realm_attr); goto out; } /* look for the entry containing the default objectclasses to add to new entries */ ret = internal_find_entry_get_attr_val(config_dn, search_scope, new_entry_filter, new_user_oc_attr, &new_user_objclasses, NULL); if (!new_user_objclasses) { /* error - could not find the entry containing list of objectclasses */ LOG_FATAL("Error: could not find the entry containing the new user objectclass list " "[%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), new_entry_filter, new_user_oc_attr); goto out; } /* get the home directory prefix value */ /* note - this is in the same entry as the new entry template, so use the same filter */ slapi_ch_free_string(&iwdc->homedir_prefix); ret = internal_find_entry_get_attr_val(config_dn, search_scope, new_entry_filter, homedir_prefix_attr, NULL, &iwdc->homedir_prefix); if (!iwdc->homedir_prefix) { /* error - could not find the home dir prefix */ LOG_FATAL("Error: could not find the entry containing the home directory prefix " "[%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), new_entry_filter, homedir_prefix_attr); goto out; } /* get the login shell value */ /* note - this is in the same entry as the new entry template, so use the same filter */ slapi_ch_free_string(&iwdc->login_shell); if (login_shell_attr) { ret = internal_find_entry_get_attr_val(config_dn, search_scope, new_entry_filter, login_shell_attr, NULL, &iwdc->login_shell); if (!iwdc->login_shell) { LOG("Warning: could not find the entry containing the login shell " "attribute [%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), new_entry_filter, login_shell_attr); } } if (!iwdc->login_shell) { /* could not find the login shell or was not configured */ LOG("Warning: no login shell configured!"); } /* find the default group - the entry above contains the group name, but we need the gidNumber for posixAccount - so first find the entry and attr value which has the group name, then lookup the group number from the group name */ ret = internal_find_entry_get_attr_val(config_dn, search_scope, new_entry_filter, default_group_attr, NULL, &default_group_name); if (!default_group_name) { /* error - could not find the default group name */ LOG_FATAL("Error: could not find the entry containing the default group name " "[%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), new_entry_filter, default_group_attr); goto out; } /* check if User Private Groups are enabled */ upg = ipa_winsync_upg_enabled(ds_subtree); /* next, find the group whose name is default_group_name - construct the filter based on the filter attribute value - assumes the group name is stored in the cn attribute value, and the gidNumber in the gidNumber attribute value */ real_group_filter = slapi_ch_smprintf("(&(cn=%s)%s)", default_group_name, default_group_filter); ret = internal_find_entry_get_attr_val(config_dn, search_scope, real_group_filter, "gidNumber", NULL, &default_gid); if (!default_gid) { /* error - could not find the default gidNumber This is not a fatal error if User Private Groups (UPG) are enabled. */ if (upg) { LOG_FATAL("Error: could not find the entry containing the default gidNumber " "UPG [%d] ds subtree [%s] filter [%s] attr [%s]\n", ret, slapi_sdn_get_dn(ds_subtree), new_entry_filter, "gidNumber"); goto out; } else { ret = LDAP_SUCCESS; } } /* If we are syncing account disable, we need to find the groups used to denote active and inactive users e.g. dn: cn=inactivated,cn=account inactivation,cn=accounts,$SUFFIX dn: cn=Activated,cn=Account Inactivation,cn=accounts,$SUFFIX */ if (acct_disable != ACCT_DISABLE_NONE) { if (inactivated_filter) { ret = internal_find_entry_get_attr_val(config_dn, search_scope, inactivated_filter, "dn", NULL, &inactivated_group_dn); if (!inactivated_group_dn) { /* error - could not find the inactivated group dn */ LOG("Could not find the DN of the inactivated users group " "[%d] ds subtree [%s] filter [%s]. Ignoring\n", ret, slapi_sdn_get_dn(ds_subtree), inactivated_filter); goto out; } } if (activated_filter) { ret = internal_find_entry_get_attr_val(config_dn, search_scope, activated_filter, "dn", NULL, &activated_group_dn); if (!activated_group_dn) { /* error - could not find the activated group dn */ LOG("Could not find the DN of the activated users group " "[%d] ds subtree [%s] filter [%s]. Ignoring\n", ret, slapi_sdn_get_dn(ds_subtree), activated_filter); goto out; } } } /* ok, we have our values */ /* first, clear out the old domain config */ slapi_entry_free(iwdc->domain_e); iwdc->domain_e = NULL; /* next, copy the global attr config */ slapi_lock_mutex(theConfig.lock); iwdc->domain_e = slapi_entry_dup(theConfig.config_e); slapi_unlock_mutex(theConfig.lock); /* set the objectclasses in the domain_e */ slapi_entry_attr_delete(iwdc->domain_e, "objectclass"); /* this copies new_user_objclasses */ slapi_entry_add_valueset(iwdc->domain_e, "objectclass", new_user_objclasses); /* When UPG is disabled, set the default gid number */ if (upg && default_gid) { slapi_entry_attr_set_charptr(iwdc->domain_e, "gidNumber", default_gid); } slapi_ch_free_string(&iwdc->inactivated_group_dn); iwdc->inactivated_group_dn = inactivated_group_dn; inactivated_group_dn = NULL; slapi_ch_free_string(&iwdc->activated_group_dn); iwdc->activated_group_dn = activated_group_dn; activated_group_dn = NULL; out: slapi_valueset_free(new_user_objclasses); slapi_sdn_free(&config_dn); slapi_ch_free_string(&realm_filter); slapi_ch_free_string(&realm_attr); slapi_ch_free_string(&new_entry_filter); slapi_ch_free_string(&new_user_oc_attr); slapi_ch_free_string(&homedir_prefix_attr); slapi_ch_free_string(&login_shell_attr); slapi_ch_free_string(&default_group_attr); slapi_ch_free_string(&default_group_filter); slapi_ch_free_string(&default_group_name); slapi_ch_free_string(&real_group_filter); slapi_ch_free_string(&default_gid); slapi_ch_free_string(&inactivated_filter); slapi_ch_free_string(&inactivated_group_dn); slapi_ch_free_string(&activated_filter); slapi_ch_free_string(&activated_group_dn); if (LDAP_SUCCESS != ret) { slapi_ch_free_string(&iwdc->realm_name); slapi_ch_free_string(&iwdc->homedir_prefix); slapi_ch_free_string(&iwdc->login_shell); slapi_entry_free(iwdc->domain_e); iwdc->domain_e = NULL; } return; }
/* * memberof_validate_config() * * Validate the pending changes in the e entry. */ int memberof_validate_config (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg) { Slapi_Attr *memberof_attr = NULL; Slapi_Attr *group_attr = NULL; Slapi_DN *config_sdn = NULL; Slapi_DN **include_dn = NULL; Slapi_DN **exclude_dn = NULL; char *syntaxoid = NULL; char *config_dn = NULL; char *skip_nested = NULL; char *auto_add_oc = NULL; char **entry_scopes = NULL; char **entry_exclude_scopes = NULL; int not_dn_syntax = 0; int num_vals = 0; *returncode = LDAP_UNWILLING_TO_PERFORM; /* be pessimistic */ /* Make sure both the group attr and the memberOf attr * config atributes are supplied. We don't care about &attr * here, but slapi_entry_attr_find() requires us to pass it. */ if (!slapi_entry_attr_find(e, MEMBEROF_GROUP_ATTR, &group_attr) && !slapi_entry_attr_find(e, MEMBEROF_ATTR, &memberof_attr)) { Slapi_Attr *test_attr = NULL; Slapi_Value *value = NULL; int hint = 0; /* Loop through each group attribute to see if the syntax is correct. */ hint = slapi_attr_first_value(group_attr, &value); while (value && (not_dn_syntax == 0)) { /* We need to create an attribute to find the syntax. */ test_attr = slapi_attr_new(); slapi_attr_init(test_attr, slapi_value_get_string(value)); /* Get the syntax OID and see if it's the Distinguished Name or * Name and Optional UID syntax. */ slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid ); not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID) & strcmp(syntaxoid, NAME_OPT_UID_SYNTAX_OID); slapi_ch_free_string(&syntaxoid); /* Print an error if the current attribute is not using the Distinguished * Name syntax, otherwise get the next group attribute. */ if (not_dn_syntax) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s configuration attribute must be set to " "an attribute defined to use either the Distinguished " "Name or Name and Optional UID syntax. (illegal value: %s)", slapi_value_get_string(value), MEMBEROF_GROUP_ATTR); } else { hint = slapi_attr_next_value(group_attr, hint, &value); } /* Free the group attribute. */ slapi_attr_free(&test_attr); } if (not_dn_syntax == 0) { /* Check the syntax of the memberof attribute. */ slapi_attr_first_value(memberof_attr, &value); test_attr = slapi_attr_new(); slapi_attr_init(test_attr, slapi_value_get_string(value)); slapi_attr_get_syntax_oid_copy(test_attr, &syntaxoid ); not_dn_syntax = strcmp(syntaxoid, DN_SYNTAX_OID); slapi_ch_free_string(&syntaxoid); slapi_attr_free(&test_attr); if (not_dn_syntax) { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s configuration attribute must be set to " "an attribute defined to use the Distinguished " "Name syntax. (illegal value: %s)", slapi_value_get_string(value), MEMBEROF_ATTR); goto done; } else { *returncode = LDAP_SUCCESS; } } } else { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s and %s configuration attributes must be provided", MEMBEROF_GROUP_ATTR, MEMBEROF_ATTR); goto done; } if ((skip_nested = slapi_entry_attr_get_charptr(e, MEMBEROF_SKIP_NESTED_ATTR))){ if(strcasecmp(skip_nested, "on") != 0 && strcasecmp(skip_nested, "off") != 0){ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s configuration attribute must be set to " "\"on\" or \"off\". (illegal value: %s)", MEMBEROF_SKIP_NESTED_ATTR, skip_nested); goto done; } } if ((auto_add_oc = slapi_entry_attr_get_charptr(e, MEMBEROF_AUTO_ADD_OC))){ char *sup = NULL; /* Check if the objectclass exists by looking for its superior oc */ if((sup = slapi_schema_get_superior_name(auto_add_oc)) == NULL){ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s configuration attribute must be set to " "to an existing objectclass (unknown: %s)", MEMBEROF_AUTO_ADD_OC, auto_add_oc); *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } else { slapi_ch_free_string(&sup); } } if ((config_dn = slapi_entry_attr_get_charptr(e, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){ /* Now check the shared config attribute, validate it now */ Slapi_Entry *e = NULL; int rc = 0; rc = slapi_dn_syntax_check(pb, config_dn, 1); if (rc) { /* syntax check failed */ slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_validate_config - " "%s does not contain a valid DN (%s)\n", SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn); *returncode = LDAP_INVALID_DN_SYNTAX; goto done; } config_sdn = slapi_sdn_new_dn_byval(config_dn); slapi_search_internal_get_entry(config_sdn, NULL, &e, memberof_get_plugin_id()); if(e){ slapi_entry_free(e); *returncode = LDAP_SUCCESS; } else { /* config area does not exist! */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "The %s configuration attribute points to an entry that " "can not be found. (%s)", SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_dn); *returncode = LDAP_UNWILLING_TO_PERFORM; } } /* * Check the entry scopes */ entry_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_ATTR, &num_vals); if(entry_scopes){ int i = 0; /* Validate the syntax before we create our DN array */ for (i = 0;i < num_vals; i++){ if(slapi_dn_syntax_check(pb, entry_scopes[i], 1)){ /* invalid dn syntax */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s: Invalid DN (%s) for include suffix.", MEMBEROF_PLUGIN_SUBSYSTEM, entry_scopes[i]); slapi_ch_array_free(entry_scopes); entry_scopes = NULL; theConfig.entryScopeCount = 0; *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } } /* Now create our SDN array for conflict checking */ include_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *), num_vals+1); for (i = 0;i < num_vals; i++){ include_dn[i] = slapi_sdn_new_dn_passin(entry_scopes[i]); } } /* * Check and process the entry exclude scopes */ entry_exclude_scopes = slapi_entry_attr_get_charray_ext(e, MEMBEROF_ENTRY_SCOPE_EXCLUDE_SUBTREE, &num_vals); if(entry_exclude_scopes){ int i = 0; /* Validate the syntax before we create our DN array */ for (i = 0;i < num_vals; i++){ if(slapi_dn_syntax_check(pb, entry_exclude_scopes[i], 1)){ /* invalid dn syntax */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s: Invalid DN (%s) for exclude suffix.", MEMBEROF_PLUGIN_SUBSYSTEM, entry_exclude_scopes[i]); slapi_ch_array_free(entry_exclude_scopes); entry_exclude_scopes = NULL; *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } } /* Now create our SDN array for conflict checking */ exclude_dn = (Slapi_DN **)slapi_ch_calloc(sizeof(Slapi_DN *),num_vals+1); for (i = 0;i < num_vals; i++){ exclude_dn[i] = slapi_sdn_new_dn_passin(entry_exclude_scopes[i]); } } /* * Need to do conflict checking */ if(include_dn && exclude_dn){ /* * Make sure we haven't mixed the same suffix, and there are no * conflicts between the includes and excludes */ int i = 0; while(include_dn[i]){ int x = 0; while(exclude_dn[x]){ if(slapi_sdn_compare(include_dn[i], exclude_dn[x] ) == 0) { /* we have a conflict */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s: include suffix (%s) is also listed as an exclude suffix list", MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i])); *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } x++; } i++; } /* Check for parent/child conflicts */ i = 0; while(include_dn[i]){ int x = 0; while(exclude_dn[x]){ if(slapi_sdn_issuffix(include_dn[i], exclude_dn[x])) { /* we have a conflict */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s: include suffix (%s) is a child of the exclude suffix(%s)", MEMBEROF_PLUGIN_SUBSYSTEM, slapi_sdn_get_dn(include_dn[i]), slapi_sdn_get_dn(exclude_dn[i])); *returncode = LDAP_UNWILLING_TO_PERFORM; goto done; } x++; } i++; } } done: memberof_free_scope(exclude_dn, &num_vals); memberof_free_scope(include_dn, &num_vals); slapi_ch_free((void**)&entry_scopes); slapi_ch_free((void**)&entry_exclude_scopes); slapi_sdn_free(&config_sdn); slapi_ch_free_string(&config_dn); slapi_ch_free_string(&skip_nested); slapi_ch_free_string(&auto_add_oc); if (*returncode != LDAP_SUCCESS) { return SLAPI_DSE_CALLBACK_ERROR; } else { return SLAPI_DSE_CALLBACK_OK; } }