/* ARGSUSED */ int _ns_ldap_modrdn2_s(char *service, int flags, char *dn, char *newrdn, int deleteoldrdn) { LDAP *ld = __s_api_getLDAPconn(flags); return (ldap_modrdn2_s(ld, dn, newrdn, deleteoldrdn)); }
/* rename a user changes samaccountname, userprincipalname and rdn/cn return AD_SUCCESS on success */ int ad_rename_user(char *dn, char *new_username) { LDAP *ds; int result; char *new_rdn; char *domain, *upn; ds=ad_login(); if(!ds) return ad_error_code; result=ad_mod_replace(dn, "sAMAccountName", new_username); if(!result) return ad_error_code; domain=dn2domain(dn); upn=malloc(strlen(new_username)+strlen(domain)+2); sprintf(upn, "%s@%s", new_username, domain); free(domain); result=ad_mod_replace(dn, "userPrincipalName", upn); free(upn); if(!result) return ad_error_code; new_rdn=malloc(strlen(new_username)+4); sprintf(new_rdn, "cn=%s", new_username); result=ldap_modrdn2_s(ds, dn, new_rdn, 1); if(result!=LDAP_SUCCESS) { snprintf(ad_error_msg, MAX_ERR_LENGTH, "Error in ldap_modrdn2_s for ad_rename_user: %s\n", ldap_err2string(result)); ad_error_code=AD_LDAP_OPERATION_FAILURE; free(new_rdn); return ad_error_code; } ad_error_code=AD_SUCCESS; free(new_rdn); return ad_error_code; }
int ldap_rename_account(char *oldaccount, char *newaccount) { char dn[MAXLEN], newdn[MAXLEN]; int rc; if(!admin_bind && LDAP_SUCCESS != ( rc = ldap_do_admin_bind())) { log_module(MAIN_LOG, LOG_ERROR, "failed to bind as admin"); return rc; } memset(dn, 0, MAXLEN); memset(newdn, 0, MAXLEN); snprintf(dn, MAXLEN-1, nickserv_conf.ldap_dn_fmt, oldaccount); strcat(newdn, nickserv_conf.ldap_field_account); strcat(newdn, "="); strcat(newdn, newaccount); rc = ldap_modrdn2_s(ld, dn, newdn, true); if(rc != LDAP_SUCCESS) { log_module(MAIN_LOG, LOG_ERROR, "Error modifying ldap account: %s -- %s", oldaccount, ldap_err2string(rc)); //return rc; } return rc; }
static void do_modrdn( char *uri, char *host, int port, char *manager, char *passwd, char *entry, int maxloop ) { LDAP *ld = NULL; int i; pid_t pid; char *DNs[2]; char *rdns[2]; pid = getpid(); DNs[0] = entry; DNs[1] = strdup( entry ); /* reverse the RDN, make new DN */ { char *p1, *p2; p1 = strchr( entry, '=' ) + 1; p2 = strchr( p1, ',' ); *p2 = '\0'; rdns[1] = strdup( entry ); *p2-- = ','; for (i = p1 - entry;p2 >= p1;) DNs[1][i++] = *p2--; DNs[1][i] = '\0'; rdns[0] = strdup( DNs[1] ); DNs[1][i] = ','; } if ( uri ) { ldap_initialize( &ld, uri ); } else { ld = ldap_init( host, port ); } if ( ld == NULL ) { perror( "ldap_init" ); exit( EXIT_FAILURE ); } { int version = LDAP_VERSION3; (void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); } if ( ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE ) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_bind" ); exit( EXIT_FAILURE ); } fprintf( stderr, "PID=%ld - Modrdn(%d): entry=\"%s\".\n", (long) pid, maxloop, entry ); for ( i = 0; i < maxloop; i++ ) { int rc; if (( rc = ldap_modrdn2_s( ld, DNs[0], rdns[0], 0 )) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); if ( rc != LDAP_NO_SUCH_OBJECT ) break; continue; } if (( rc = ldap_modrdn2_s( ld, DNs[1], rdns[1], 1 )) != LDAP_SUCCESS ) { ldap_perror( ld, "ldap_modrdn" ); if ( rc != LDAP_NO_SUCH_OBJECT ) break; continue; } } fprintf( stderr, " PID=%ld - Modrdn done.\n", (long) pid ); ldap_unbind( ld ); }
/** * Update contact to LDAP * * \param server AddressBook resource * \param contact GHashTable with object to update */ void ldapsvr_update_contact(LdapServer *server, GHashTable *contact) { LDAP *ld = NULL; LDAPMod *mods[MODSIZE]; LDAPMod modarr[4]; gint cnt = 0; gchar *param, *dn; Rdn *NoRemove = NULL; char *cn[] = {NULL, NULL}; char *givenName[] = {NULL, NULL}; char **mail = NULL; char *sn[] = {NULL, NULL}; GList *mailList; int mod_op; cm_return_if_fail(server != NULL || contact != NULL); ld = ldapsvr_connect(server->control); if (ld == NULL) { clean_up(ld, server, contact); return; } dn = g_hash_table_lookup(contact, "dn"); if (dn == NULL) { clean_up(ld, server, contact); return; } NoRemove = ldapsvr_modify_dn(contact, dn); if (NoRemove) { /* We are trying to change RDN */ gchar *newRdn = g_strdup_printf("%s=%s", NoRemove->attribute, NoRemove->value); #ifdef OPEN_LDAP_API_AT_LEAST_3000 int rc = ldap_rename_s(ld, dn, newRdn, NULL, 1, NULL, NULL); #else /* This is deprecated as of OpenLDAP-2.3.0 */ int rc = ldap_modrdn2_s(ld, dn, newRdn, 1); #endif if(rc != LDAP_SUCCESS) { if (rc == LDAP_ALREADY_EXISTS) { /* We are messing with a contact with more than one listed email * address and the email we are changing is not the one used for dn */ /* It needs to be able to handle renaming errors to an already defined * dn. For now we just refuse the update. It will be caught later on as * a LDAPRC_NAMING_VIOLATION error. */ } else { g_printerr("Current dn: %s\n", dn); g_printerr("new dn: %s\n", newRdn); g_printerr("LDAP Error(ldap_modrdn2_s) failed[0x%x]: %s\n", rc, ldaputil_get_error(ld)); g_free(newRdn); clean_up(ld, server, contact); return; } } else { ItemPerson *person = g_hash_table_lookup(contact, "person"); g_free(newRdn); dn = g_strdup(NoRemove->new_dn); g_hash_table_replace(contact, "dn", dn); if (person) { g_free(person->externalID); person->externalID = dn; } } } else { server->retVal = LDAPRC_NODN; clean_up(ld, server, contact); return; } param = g_hash_table_lookup(contact , "cn"); mod_op = ldapsvr_deside_operation(ld, server, dn, "displayName", param); if (mod_op >= 0 && (strcmp(param, NoRemove->value) != 0 && strcmp("cn", NoRemove->attribute) != 0)) { if (mod_op == LDAP_MOD_DELETE) { /* Setting param to NULL instructs OpenLDAP to remove any * value stored for this attribute and remove the attribute * completely. Should multiple instances of an attribute be * allowed in the future param is required to have the value * store for the attribute which is going to be deleted */ param = NULL; } if (mod_op == LDAP_MOD_REPLACE && strcmp(param, "") == 0) { /* Having an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we treate this as a request for deleting * the attribute. */ mod_op = LDAP_MOD_DELETE; param = NULL; } if (mod_op == LDAP_MOD_ADD && strcmp(param, "") == 0) { /* Adding an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we silently refuse to add this entry */ } else { SETMOD(mods[cnt], modarr[cnt], mod_op, "displayName", cn, param); cnt++; g_hash_table_insert(contact, "displayName", param); } } param = g_hash_table_lookup(contact , "givenName"); mod_op = ldapsvr_deside_operation(ld, server, dn, "givenName", param); if (mod_op >= 0 && (strcmp(param, NoRemove->value) != 0 && strcmp("givenName", NoRemove->attribute) != 0)) { if (mod_op == LDAP_MOD_DELETE) { /* Setting param to NULL instructs OpenLDAP to remove any * value stored for this attribute and remove the attribute * completely. Should multiple instances of an attribute be * allowed in the future param is required to have the value * store for the attribute which is going to be deleted */ param = NULL; } if (mod_op == LDAP_MOD_REPLACE && strcmp(param, "") == 0) { /* Having an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we treate this as a request for deleting * the attribute. */ mod_op = LDAP_MOD_DELETE; param = NULL; } if (mod_op == LDAP_MOD_ADD && strcmp(param, "") == 0) { /* Adding an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we silently refuse to add this entry */ } else { SETMOD(mods[cnt], modarr[cnt], mod_op, "givenName", givenName, param); cnt++; } } mailList = g_hash_table_lookup(contact , "mail"); if (mailList) { debug_print("# of mail: %d\n", g_list_length(mailList)); if (!(strcmp("mail", NoRemove->attribute) == 0 && g_list_length(mailList) == 1)) { char **tmp; tmp = g_malloc(sizeof(*tmp) * (g_list_length(mailList)+1)); mail = tmp; while (mailList) { EmailKeyValue *item = mailList->data; *tmp++ = g_strdup((gchar *) item->mail); mailList = g_list_next(mailList); } *tmp = NULL; /* * At least one email address is required * in which case it will always be a replace */ SETMODS(mods[cnt], modarr[cnt], LDAP_MOD_REPLACE, "mail", mail); cnt++; } } else { /* * an error condition since at least one email adress * is required. Should never occur though. */ } param = g_hash_table_lookup(contact , "sn"); mod_op = ldapsvr_deside_operation(ld, server, dn, "sn", param); if (mod_op >= 0 && (strcmp(param, NoRemove->value) != 0 && strcmp("sn", NoRemove->attribute) != 0)) { if (mod_op == LDAP_MOD_DELETE) { /* Setting param to NULL instructs OpenLDAP to remove any * value stored for this attribute and remove the attribute * completely. Should multiple instances of an attribute be * allowed in the future param is required to have the value * store for the attribute which is going to be deleted */ param = NULL; } if (mod_op == LDAP_MOD_REPLACE && strcmp(param, "") == 0) { /* Having an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we treate this as a request for deleting * the attribute. */ mod_op = LDAP_MOD_DELETE; param = NULL; } if (mod_op == LDAP_MOD_ADD && strcmp(param, "") == 0) { /* Adding an empty string is considered a syntax error in * ldap. E.g attributes with empty strings are not allowed * in which case we silently refuse to add this entry */ } else { SETMOD(mods[cnt], modarr[cnt], mod_op, "sn", sn, param); cnt++; } } debug_print("newDN: %s\n", dn); if (NoRemove) rdn_free(NoRemove); server->retVal = LDAPRC_SUCCESS; if (cnt > 0) { int rc; mods[cnt] = NULL; rc = ldap_modify_ext_s(ld, dn, mods, NULL, NULL); if (rc) { g_printerr("ldap_modify for dn=%s\" failed[0x%x]: %s\n", dn, rc, ldaputil_get_error(ld)); server->retVal = LDAPRC_NAMING_VIOLATION; } if (mail) g_free(mail); } ldapsvr_handle_other_attributes(ld, server, dn, contact); /* If we do not make changes persistent at this point then changes * will be lost if the user makes new search on the same server since * changes are only present in Claws' internal cache. This issue has to * be solved in addressbook.c since this involves access to structures * which are only accessible in addressbook.c */ clean_up(ld, server, contact); }