int value_dn_normalize_value(Slapi_Value *value) { Slapi_DN *sdn = NULL; int rc = 0; if (NULL == value) { return rc; } sdn = slapi_sdn_new_dn_passin(value->bv.bv_val); if (slapi_sdn_get_dn(sdn)) { value->bv.bv_val = slapi_ch_strdup(slapi_sdn_get_dn(sdn)); value->bv.bv_len = slapi_sdn_get_ndn_len(sdn); slapi_sdn_free(&sdn); slapi_value_set_flags(value, SLAPI_ATTR_FLAG_NORMALIZED_CES); } else { rc = 1; slapi_ch_free((void **)&sdn); /* free just Slapi_DN */ } return rc; }
static int _ger_g_permission_granted ( Slapi_PBlock *pb, Slapi_Entry *e, const char *subjectdn, char **errbuf ) { char *proxydn = NULL; Slapi_DN *requestor_sdn, *entry_sdn; char *errtext = NULL; int isroot; int rc; /* * Theorically, we should check if the entry has "g" * permission granted to the requestor. If granted, * allows the effective rights on that entry and its * attributes within the entry to be returned for * ANY subject. * * "G" permission granting has not been implemented yet, * the current release assumes that "g" permission be * granted to root and owner of any entry. */ /* * The requestor may be either the bind dn or a proxy dn */ if ((proxyauth_get_dn( pb, &proxydn, &errtext ) == LDAP_SUCCESS) && ( proxydn != NULL )) { requestor_sdn = slapi_sdn_new_dn_passin ( proxydn ); } else { slapi_ch_free_string(&proxydn); /* this could still have been set - free it */ requestor_sdn = &(pb->pb_op->o_sdn); } if ( slapi_sdn_get_dn (requestor_sdn) == NULL ) { slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_g_permission_granted - Anonymous has no g permission\n" ); rc = LDAP_INSUFFICIENT_ACCESS; goto bailout; } isroot = slapi_dn_isroot ( slapi_sdn_get_dn (requestor_sdn) ); if ( isroot ) { /* Root has "g" permission on any entry */ rc = LDAP_SUCCESS; goto bailout; } entry_sdn = slapi_entry_get_sdn ( e ); if ( entry_sdn == NULL || slapi_sdn_get_dn (entry_sdn) == NULL ) { rc = LDAP_SUCCESS; goto bailout; } if ( slapi_sdn_compare ( requestor_sdn, entry_sdn ) == 0 ) { /* Owner has "g" permission on his own entry */ rc = LDAP_SUCCESS; goto bailout; } /* if the requestor and the subject user are identical, let's grant it */ if ( strcasecmp ( slapi_sdn_get_ndn(requestor_sdn), subjectdn ) == 0) { /* Requestor should see his own permission rights on any entry */ rc = LDAP_SUCCESS; goto bailout; } aclutil_str_append ( errbuf, "get-effective-rights: requestor has no g permission on the entry" ); slapi_log_err(SLAPI_LOG_ACL, plugin_name, "_ger_g_permission_granted - %s\n", *errbuf); rc = LDAP_INSUFFICIENT_ACCESS; bailout: if ( proxydn ) { /* The ownership of proxydn has passed to requestor_sdn */ slapi_sdn_free ( &requestor_sdn ); } return rc; }
/* This function is called to process operation that come over external connections */ void do_modrdn( Slapi_PBlock *pb ) { Slapi_Operation *operation; BerElement *ber; char *rawdn = NULL, *rawnewsuperior = NULL; const char *dn = NULL, *newsuperior = NULL; char *newrdn = NULL; int err = 0, deloldrdn = 0; ber_len_t len = 0; char *newdn = NULL; char *parent = NULL; Slapi_DN sdn; Slapi_DN snewdn; Slapi_DN *snewsuperior = NULL; LDAPDebug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 ); /* count the modrdn request */ slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsModifyRDNOps); slapi_pblock_get( pb, SLAPI_OPERATION, &operation); ber = operation->o_ber; slapi_sdn_init(&sdn); slapi_sdn_init(&snewdn); /* * Parse the modrdn request. It looks like this: * * ModifyRDNRequest := SEQUENCE { * entry DistinguishedName, * newrdn RelativeDistinguishedName, * deleteoldrdn BOOLEAN, * newSuperior [0] LDAPDN OPTIONAL -- v3 only * } */ if (ber_scanf(ber, "{aab", &rawdn, &newrdn, &deloldrdn) == LBER_ERROR) { LDAPDebug( LDAP_DEBUG_ANY, "ber_scanf failed (op=ModRDN; params=DN,newRDN,deleteOldRDN)\n", 0, 0, 0 ); op_shared_log_error_access (pb, "MODRDN", "???", "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "unable to decode DN, newRDN, or deleteOldRDN parameters", 0, NULL ); goto free_and_return; } if ( ber_peek_tag( ber, &len ) == LDAP_TAG_NEWSUPERIOR ) { /* This "len" is not used... */ if ( pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) { LDAPDebug( LDAP_DEBUG_ANY, "got newSuperior in LDAPv2 modrdn op\n", 0, 0, 0 ); op_shared_log_error_access (pb, "MODRDN", rawdn?rawdn:"", "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "received newSuperior in LDAPv2 modrdn", 0, NULL ); slapi_ch_free_string( &rawdn ); slapi_ch_free_string( &newrdn ); goto free_and_return; } if ( ber_scanf( ber, "a", &rawnewsuperior ) == LBER_ERROR ) { LDAPDebug( LDAP_DEBUG_ANY, "ber_scanf failed (op=ModRDN; params=newSuperior)\n", 0, 0, 0 ); op_shared_log_error_access (pb, "MODRDN", rawdn, "decoding error"); send_ldap_result( pb, LDAP_PROTOCOL_ERROR, NULL, "unable to decode newSuperior parameter", 0, NULL ); slapi_ch_free_string( &rawdn ); slapi_ch_free_string( &newrdn ); 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, "MODRDN", rawdn?rawdn:"", "strict: invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free_string( &rawdn ); slapi_ch_free_string( &newrdn ); slapi_ch_free_string( &rawnewsuperior ); goto free_and_return; } /* check that the new rdn is formatted correctly */ err = slapi_dn_syntax_check(pb, newrdn, 1); if (err) { /* syntax check failed */ op_shared_log_error_access(pb, "MODRDN", newrdn?newrdn:"", "strict: invalid new rdn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid new rdn", 0, NULL); slapi_ch_free_string( &rawdn ); slapi_ch_free_string( &newrdn ); slapi_ch_free_string( &rawnewsuperior ); goto free_and_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, "MODRDN", rawdn, "invalid dn"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid dn", 0, NULL); slapi_ch_free_string( &newrdn ); slapi_ch_free_string( &rawnewsuperior ); goto free_and_return; } if (rawnewsuperior) { if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ err = slapi_dn_syntax_check(pb, rawnewsuperior, 1); if (err) { /* syntax check failed */ op_shared_log_error_access(pb, "MODRDN", rawnewsuperior, "strict: invalid new superior"); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid new superior", 0, NULL); slapi_ch_free_string( &rawnewsuperior ); goto free_and_return; } } snewsuperior = slapi_sdn_new_dn_passin(rawnewsuperior); newsuperior = slapi_sdn_get_dn(snewsuperior); } /* * If newsuperior is myself or my descendent, the modrdn should fail. * Note: need to check the case newrdn is given, and newsuperior * uses the newrdn, as well. */ parent = slapi_dn_parent(slapi_sdn_get_ndn(&sdn)); newdn = slapi_ch_smprintf("%s,%s", newrdn, parent); /* slapi_sdn_init_normdn_passin expects normalized but NOT * decapitalized dn */ slapi_sdn_init_dn_passin(&snewdn, newdn); if (0 == slapi_sdn_compare(&sdn, snewsuperior) || 0 == slapi_sdn_compare(&snewdn, snewsuperior)) { op_shared_log_error_access(pb, "MODRDN", newsuperior, "new superior is identical to the entry dn"); send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "new superior is identical to the entry dn", 0, NULL); goto free_and_return; } if (slapi_sdn_issuffix(snewsuperior, &sdn) || slapi_sdn_issuffix(snewsuperior, &snewdn)) { /* E.g., * newsuperior: ou=sub,ou=people,dc=example,dc=com * dn: ou=people,dc=example,dc=com */ op_shared_log_error_access(pb, "MODRDN", newsuperior, "new superior is descendent of the entry"); send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "new superior is descendent of the entry", 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, "MODRDN", dn, "failed to decode LDAP controls"); send_ldap_result( pb, err, NULL, NULL, 0, NULL ); goto free_and_return; } LDAPDebug( LDAP_DEBUG_ARGS, "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", dn, newrdn, deloldrdn ); slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot ); /* dn, newrdn and newsuperior are all normalized */ slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, (void *)slapi_sdn_get_udn(&sdn) ); 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, (void *)snewsuperior ); slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, &deloldrdn ); op_shared_rename(pb, 0 /* do not pass in ownership of string arguments */ ); free_and_return: slapi_sdn_done(&sdn); slapi_ch_free_string(&newrdn); slapi_sdn_free(&snewsuperior); slapi_sdn_done(&snewdn); slapi_ch_free_string(&parent); return; }
/* * 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; } }
/* * 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; } }
static void extop_handle_import_start(Slapi_PBlock *pb, char *extoid, struct berval *extval) { char *orig = NULL; const char *suffix = NULL; Slapi_DN *sdn = NULL; Slapi_Backend *be = NULL; struct berval bv; int ret; if (extval == NULL || extval->bv_val == NULL) { slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "no data supplied\n"); send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "no data supplied", 0, NULL); return; } orig = slapi_ch_malloc(extval->bv_len+1); strncpy(orig, extval->bv_val, extval->bv_len); orig[extval->bv_len] = 0; /* Check if we should be performing strict validation. */ if (config_get_dn_validate_strict()) { /* check that the dn is formatted correctly */ ret = slapi_dn_syntax_check(pb, orig, 1); if (ret) { /* syntax check failed */ slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "strict: invalid suffix (%s)\n", orig); send_ldap_result(pb, LDAP_INVALID_DN_SYNTAX, NULL, "invalid suffix", 0, NULL); return; } } sdn = slapi_sdn_new_dn_passin(orig); if (!sdn) { slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "Out of memory\n"); send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); return; } suffix = slapi_sdn_get_dn(sdn); /* be = slapi_be_select(sdn); */ be = slapi_mapping_tree_find_backend_for_sdn(sdn); if (be == NULL || be == defbackend_get_backend()) { /* might be instance name instead of suffix */ be = slapi_be_select_by_instance_name(suffix); } if (be == NULL || be == defbackend_get_backend()) { slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "invalid suffix or instance name '%s'\n", suffix); send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, "invalid suffix or instance name", 0, NULL); goto out; } slapi_pblock_set(pb, SLAPI_BACKEND, be); slapi_pblock_set( pb, SLAPI_REQUESTOR_ISROOT, &pb->pb_op->o_isroot ); { /* Access Control Check to see if the client is * allowed to use task import */ char *dummyAttr = "dummy#attr"; char *dummyAttrs[2] = { NULL, NULL }; int rc = 0; char dn[128]; Slapi_Entry *feature; /* slapi_str2entry modify its dn parameter so we must copy * this string each time we call it ! */ /* This dn is no need to be normalized. */ PR_snprintf(dn, sizeof(dn), "dn: oid=%s,cn=features,cn=config", EXTOP_BULK_IMPORT_START_OID); dummyAttrs[0] = dummyAttr; feature = slapi_str2entry(dn, 0); rc = plugin_call_acl_plugin (pb, feature, dummyAttrs, NULL, SLAPI_ACL_WRITE, ACLPLUGIN_ACCESS_DEFAULT, NULL); slapi_entry_free(feature); if (rc != LDAP_SUCCESS) { /* Client isn't allowed to do this. */ send_ldap_result(pb, rc, NULL, NULL, 0, NULL); goto out; } } if (be->be_wire_import == NULL) { /* not supported by this backend */ slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "bulk import attempted on '%s' (not supported)\n", suffix); send_ldap_result(pb, LDAP_NOT_SUPPORTED, NULL, NULL, 0, NULL); goto out; } ret = SLAPI_UNIQUEID_GENERATE_TIME_BASED; slapi_pblock_set(pb, SLAPI_LDIF2DB_GENERATE_UNIQUEID, &ret); ret = SLAPI_BI_STATE_START; slapi_pblock_set(pb, SLAPI_BULK_IMPORT_STATE, &ret); ret = (*be->be_wire_import)(pb); if (ret != 0) { slapi_log_err(SLAPI_LOG_ERR, "extop_handle_import_start", "error starting import (%d)\n", ret); send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL); goto out; } /* okay, the import is starting now -- save the backend in the * connection block & mark this connection as belonging to a bulk import */ PR_EnterMonitor(pb->pb_conn->c_mutex); pb->pb_conn->c_flags |= CONN_FLAG_IMPORT; pb->pb_conn->c_bi_backend = be; PR_ExitMonitor(pb->pb_conn->c_mutex); slapi_pblock_set(pb, SLAPI_EXT_OP_RET_OID, EXTOP_BULK_IMPORT_START_OID); bv.bv_val = NULL; bv.bv_len = 0; slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, &bv); send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL); slapi_log_err(SLAPI_LOG_INFO, "extop_handle_import_start", "Bulk import begin import on '%s'.\n", suffix); out: slapi_sdn_free(&sdn); return; }
static int windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e) { char *tmpstr = NULL; int retval = 0; if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsReplicaArea)) { tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsReplicaArea); if (NULL != tmpstr) { windows_private_set_windows_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) ); } retval = 1; } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7DirectoryReplicaArea)) { tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7DirectoryReplicaArea); if (NULL != tmpstr) { windows_private_set_directory_subtree(ra, slapi_sdn_new_dn_passin(tmpstr) ); } retval = 1; } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewUsers)) { tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewUsers); if (NULL != tmpstr && true_value_from_string(tmpstr)) { windows_private_set_create_users(ra, PR_TRUE); } else { windows_private_set_create_users(ra, PR_FALSE); } retval = 1; slapi_ch_free((void**)&tmpstr); } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewGroups)) { tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7CreateNewGroups); if (NULL != tmpstr && true_value_from_string(tmpstr)) { windows_private_set_create_groups(ra, PR_TRUE); } else { windows_private_set_create_groups(ra, PR_FALSE); } retval = 1; slapi_ch_free((void**)&tmpstr); } if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsDomain)) { tmpstr = slapi_entry_attr_get_charptr(e, type_nsds7WindowsDomain); if (NULL != tmpstr) { windows_private_set_windows_domain(ra,tmpstr); } /* No need to free tmpstr because it was aliased by the call above */ tmpstr = NULL; retval = 1; } if (type == NULL || slapi_attr_types_equivalent(type,type_winSyncInterval)) { tmpstr = slapi_entry_attr_get_charptr(e, type_winSyncInterval); if (NULL != tmpstr) { windows_private_set_sync_interval(ra,tmpstr); } slapi_ch_free_string(&tmpstr); retval = 1; } if (type == NULL || slapi_attr_types_equivalent(type,type_oneWaySync)) { tmpstr = slapi_entry_attr_get_charptr(e, type_oneWaySync); if (NULL != tmpstr) { if (strcasecmp(tmpstr, "fromWindows") == 0) { windows_private_set_one_way(ra, ONE_WAY_SYNC_FROM_AD); } else if (strcasecmp(tmpstr, "toWindows") == 0) { windows_private_set_one_way(ra, ONE_WAY_SYNC_TO_AD); } else { slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Ignoring illegal setting for %s attribute in replication " "agreement \"%s\". Valid values are \"toWindows\" or " "\"fromWindows\".\n", type_oneWaySync, slapi_entry_get_dn(e)); windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED); } } else { windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED); } slapi_ch_free((void**)&tmpstr); retval = 1; } return retval; }