#include "ldap_plugin.h" #include #include #define VCARDATTR 0 #define LDAPATTR 1 #define VCARDPROP 2 char *vcardattrs[][4][3] = { //Normal Stuff {{"TEL"}, {"homePhone"}, {"HOME", NULL}, {NULL}}, {{"TEL"}, {"companyPhone"}, {"WORK", NULL}, {"1"}}, {{"TEL"}, {"facsimileTelephoneNumber"}, {"FAX", "WORK", NULL}, {NULL}}, {{"TEL"}, {"mobile"}, {"CELL", NULL}, {NULL}}, {{"TEL"}, {"carPhone"}, {"CAR", NULL}, {"1"}}, {{"TEL"}, {"telephoneNumber"}, {"WORK", "VOICE", NULL}, {NULL}}, {{"TEL"}, {"homeFacsimileTelephoneNumber"}, {"HOME", "FAX", NULL}, {"1"}}, {{"TEL"}, {"otherPhone"}, {"VOICE", NULL}, {"1"}}, {{"TEL"}, {"otherFax"}, {"FAX", NULL}, {"1"}}, {{"TEL"}, {"otherFacsimileTelephoneNumber"}, {"FAX", NULL}, {"1"}}, {{"TEL"}, {"callbackPhone"}, {"X-EVOLUTION-CALLBACK", NULL}, {"1"}}, {{"TEL"}, {"internationaliSDNNumber"}, {"ISDN", NULL}, {NULL}}, {{"TEL"}, {"pager"}, {"PAGER", NULL}, {NULL}}, {{"TEL"}, {"primaryPhone"}, {"PREF", NULL}, {"1"}}, {{"TEL"}, {"radio"}, {"X-EVOLUTION-RADIO", NULL}, {"1"}}, {{"TEL"}, {"telex"}, {"X-EVOLUTION-TELEX", NULL}, {"1"}}, {{"TEL"}, {"tty"}, {"X-EVOLUTION-TTYTDD", NULL}, {"1"}}, {{"TEL"}, {"assistantPhone"}, {"X-EVOLUTION-ASSISTANT", NULL}, {"1"}}, {{"BDAY"}, {"birthDate"}, {NULL}, {"1"}}, {{"X-EVOLUTION-SPOUSE"}, {"spouseName"}, {NULL}, {"1"}}, {{"CATEGORIES"}, {"category"}, {NULL}, {"1"}}, {{"ROLE"}, {"businessRole"}, {NULL}, {"1"}}, {{"X-EVOLUTION-ASSISTANT"}, {"assistantName"}, {NULL}, {"1"}}, {{"X-EVOLUTION-MANAGER"}, {"managerName"}, {NULL}, {"1"}}, {{"X-EVOLUTION-ANNIVERSARY"}, {"anniversary"}, {NULL}, {"1"}}, {{"X-EVOLUTION-OFFICE"}, {"roomNumber"}, {NULL}, {NULL}}, {{"NICKNAME"}, {"displayName"}, {NULL}, {NULL}}, {{"CALURI"}, {"calendarURI"}, {NULL}, {"1"}}, {{"FBURL"}, {"freeBusyURI"}, {NULL}, {"1"}}, {{"X-EVOLUTION-FILE-AS"}, {"fileAs"}, {NULL}, {"1"}}, //{{"ORG"}, {"o"}, {NULL}, {"ORGNAME", NULL}}, {{"URL"}, {"labeledURI"}, {NULL}, {NULL}}, {{"EMAIL"}, {"mail"}, {"INTERNET", NULL}, {NULL}}, {{"EMAIL"}, {"mail"}, {NULL}, {NULL}}, {{"TITLE"}, {"title"}, {NULL}, {NULL}}, // //Should be made by autodetection {{"NOTE"}, {"note"}, {NULL}, {"1"}}, {{"ADR"}, {NULL}, {NULL}, {NULL}}, //{{"ADR"}, {"postalAddress"}, {"WORK", NULL}, {"BOX", NULL}}, //{{"ADR"}, {"homePostalAddress"}, {"HOME", NULL}, {"BOX", NULL}}, //{{"ADR"}, {"homePostalAddress"}, {"HOME", "PREF", NULL}, {"BOX", NULL}}, {{"LABEL"}, {"otherPostalAddress"}, {"POSTAL", NULL}, {"1"}}, {{"LABEL"}, {"homePostalAddress"}, {"HOME", NULL}, {NULL}}, {{"LABEL"}, {"postalAddress"}, {"WORK", NULL}, {NULL}}, {{"LABEL"}, {"otherPostalAddress"}, {"POSTAL", "PREF", NULL}, {"1"}}, {{"LABEL"}, {"homePostalAddress"}, {"HOME", "PREF", NULL}, {NULL}}, {{"LABEL"}, {"postalAddress"}, {"WORK", "PREF", NULL}, {NULL}}, // //Special Entries or entries being ignored {{"N"}, {NULL}, {NULL}, {NULL}}, {{"X-MOZILLA-HTML"}, {NULL}, {NULL}, {NULL}}, {{""}, {"objectClass"}, {NULL}, {NULL}}, {{""}, {"uid"}, {NULL}, {NULL}}, {{"FN"}, {"cn"}, {NULL}, {NULL}}, {{"VERSION"}, {NULL}, {NULL}, {NULL}}, {{"UID"}, {NULL}, {NULL}, {NULL}}, NULL}; char *quoted_encode(char *string) { char *data; char buffer[1024]; int i = 0; int chr = 0; data = malloc(1024 * sizeof(char)); strcpy(data, string); for (i = 0; i < strlen(data); i++) { if (data[i] == '=') { data[i] = 0; sprintf(buffer, "%s%s%s", data, "=3D", &data[i + 1]); i = i + 2; strcpy(data, buffer); } } while(1) { //Found new char to encode i = strcspn(data, "\n\r "); chr = data[i]; data[i] = 0; if (!chr) { break; } sprintf(buffer, "%s=%02X%s", data, chr, &data[i + 1]); strcpy(data, buffer); } return data; } char *quoted_decode(char *string) { int i = 0; char *data; char hex[1024]; char buffer[1024]; data = malloc(1024 * sizeof(char)); strcpy(data, string); while(1) { //Found new char to decode i = i + strcspn(&data[i], "="); if (!data[i]) { break; } data[i] = 0; strcpy(hex, "0x"); strncat(hex, &data[i + 1], 2); sprintf(buffer, "%s%c%s", data, ((int)(strtod(hex, NULL))), &data[i + 3]); strcpy(data, buffer); i++; } return data; } GString *ldap2vcard(ldap_connection *conn, LDAPMod **ldapdata) { VObjectO *prop; VObjectO *vcard; int i = 0, n = 0, x = 0, k = 0; GString *vcardstr; char var1[1024], var2[1024], var3[1024], var4[1024], var5[1024]; char *title = "", *first = "", *middle = "", *last = "", *suffix = "", *orgname = NULL, *orgunit = NULL; ldap_debug(conn, 2, "Converting ldap to vcard"); vcard = newVObjectO(VCCardPropO); addPropValueO(vcard, VCVersionPropO, "2.1"); //Walk through all the ldap attributes for (n = 0; ldapdata[n]; n++) { for (x = 0; ldapdata[n]->mod_values[x]; x++) { i = 0; ldap_debug(conn, 2, "Converting: %s=%s", ldapdata[n]->mod_type, ldapdata[n]->mod_values[x]); //Handle with names //First the common name if (!strcmp(ldapdata[n]->mod_type, "cn")) { switch (sscanf(ldapdata[n]->mod_values[x], "%s %s %s %s %s", var1, var2, var3, var4, var5)) { case 1: last = var1; break; case 2: first = var1; last = var2; break; case 3: first = var1; middle = var2; last = var3; break; case 4: title = var1; first = var2; middle = var3; last = var4; break; case 5: title = var1; first = var2; middle = var3; last = var4; suffix = var5; break; } } //the givenName if (!strcmp(ldapdata[n]->mod_type, "givenName")) { if (strcmp(ldapdata[n]->mod_values[x], first)) { ldap_debug(conn, 1, "First names do not match"); first = ldapdata[n]->mod_values[x]; } goto next; } //familyName if (!strcmp(ldapdata[n]->mod_type, "sn")) { if (strcmp(ldapdata[n]->mod_values[x], last)) { ldap_debug(conn, 1, "Last names do not match"); last = ldapdata[n]->mod_values[x]; } goto next; } //department handling if (!strcmp(ldapdata[n]->mod_type, "o")) { orgname = strdup(ldapdata[n]->mod_values[x]); goto next; } if (!strcmp(ldapdata[n]->mod_type, "ou")) { orgunit = strdup(ldapdata[n]->mod_values[x]); goto next; } //convert entries while (vcardattrs[i][VCARDATTR][0]) { if (vcardattrs[i][LDAPATTR][0]) { if (strcmp(ldapdata[n]->mod_type, vcardattrs[i][LDAPATTR][0]) == 0) { if (vcardattrs[i][VCARDATTR][0][0]) { //Found the entry in our array. Now convert it prop = addPropValueO(vcard, vcardattrs[i][VCARDATTR][0], ldapdata[n]->mod_values[x]); k = 0; while (vcardattrs[i][VCARDPROP][k]) { addPropO(prop, vcardattrs[i][VCARDPROP][k]); k++; } //Handle for quoted-printable if (!strcmp(vcardattrs[i][VCARDATTR][0], "ADR") || !strcmp(vcardattrs[i][VCARDATTR][0], "NOTE") || !strcmp(vcardattrs[i][VCARDATTR][0], "LABEL")) { addPropO(prop, VCQuotedPrintablePropO); } } goto next; } } i++; } //We could not find the attribute in our database. ldap_debug(conn, 1, "Could not match ldapattribute: %s", ldapdata[n]->mod_type); next: ; } } prop = addPropO(vcard,"N"); addPropValueO(prop, VCGivenNamePropO, first); addPropValueO(prop, VCAdditionalNamesPropO, middle); addPropValueO(prop, VCFamilyNamePropO, last); addPropValueO(prop, VCNameSuffixesPropO, suffix); addPropValueO(prop, VCNamePrefixesPropO, title); if (orgname || orgunit) prop = addPropO(vcard, "ORG"); if (orgname) addPropValueO(prop, "ORGNAME", orgname); if (orgunit) addPropValueO(prop, "OUN", orgunit); /* convert VObjectO to string */ vcardstr = g_string_new(writeMemVObjectO(0,0,vcard)); deleteVObjectO(vcard); ldap_debug(conn, 3, "VCARD: %i\n%s\n", &vcardstr, vcardstr->str); return vcardstr; } const char *propNamesO[][4] = { { VC7bitPropO, 0, 0, 0 }, { VC8bitPropO, 0, 0, 0 }, { VCAAlarmPropO, 0, 0, 0 }, { VCAdditionalNamesPropO, 0, 0, 0 }, { VCAdrPropO, 0, 0, 0 }, { VCAgentPropO, 0, 0, 0 }, { VCAIFFPropO, 0, 0, 0 }, { VCAOLPropO, 0, 0, 0 }, { VCAppleLinkPropO, 0, 0, 0 }, { VCAttachPropO, 0, 0, 0 }, { VCAttendeePropO, 0, 0, 0 }, { VCATTMailPropO, 0, 0, 0 }, { VCAudioContentPropO, 0, 0, 0 }, { VCAVIPropO, 0, 0, 0 }, { VCBase64PropO, 0, 0, 0 }, { VCBBSPropO, 0, 0, 0 }, { VCBirthDatePropO, 0, 0, 0 }, { VCBMPPropO, 0, 0, 0 }, { VCBodyPropO, 0, 0, 0 }, { VCBusinessRolePropO, 0, 0, 0 }, { VCCalPropO, 0, 0, 0 }, { VCCaptionPropO, 0, 0, 0 }, { VCCardPropO, 0, 0, 0 }, { VCCarPropO, 0, 0, 0 }, { VCCategoriesPropO, 0, 0, 0 }, { VCCellularPropO, 0, 0, 0 }, { VCCGMPropO, 0, 0, 0 }, { VCCharSetPropO, 0, 0, 0 }, { VCCIDPropO, 0, 0, 0 }, { VCCISPropO, 0, 0, 0 }, { VCCityPropO, 0, 0, 0 }, { VCClassPropO, 0, 0, 0 }, { VCCommentPropO, 0, 0, 0 }, { VCCompletedPropO, 0, 0, 0 }, { VCContentIDPropO, 0, 0, 0 }, { VCCountryNamePropO, 0, 0, 0 }, { VCDAlarmPropO, 0, 0, 0 }, { VCDataSizePropO, 0, 0, 0 }, { VCDayLightPropO, 0, 0, 0 }, { VCDCreatedPropO, 0, 0, 0 }, { VCDeliveryLabelPropO, 0, 0, 0 }, { VCDescriptionPropO, 0, 0, 0 }, { VCDIBPropO, 0, 0, 0 }, { VCDisplayStringPropO, 0, 0, 0 }, { VCDomesticPropO, 0, 0, 0 }, { VCDTendPropO, 0, 0, 0 }, { VCDTstartPropO, 0, 0, 0 }, { VCDuePropO, 0, 0, 0 }, { VCEmailAddressPropO, 0, 0, 0 }, { VCEncodingPropO, 0, 0, 0 }, { VCEndPropO, 0, 0, 0 }, { VCEventPropO, 0, 0, 0 }, { VCEWorldPropO, 0, 0, 0 }, { VCExNumPropO, 0, 0, 0 }, { VCExpDatePropO, 0, 0, 0 }, { VCExpectPropO, 0, 0, 0 }, { VCExtAddressPropO, 0, 0, 0 }, { VCFamilyNamePropO, 0, 0, 0 }, { VCFaxPropO, 0, 0, 0 }, { VCFullNamePropO, 0, 0, 0 }, { VCGeoLocationPropO, 0, 0, 0 }, { VCGeoPropO, 0, 0, 0 }, { VCGIFPropO, 0, 0, 0 }, { VCGivenNamePropO, 0, 0, 0 }, { VCGroupingPropO, 0, 0, 0 }, { VCHomePropO, 0, 0, 0 }, { VCIBMMailPropO, 0, 0, 0 }, { VCInlinePropO, 0, 0, 0 }, { VCInternationalPropO, 0, 0, 0 }, { VCInternetPropO, 0, 0, 0 }, { VCISDNPropO, 0, 0, 0 }, { VCJPEGPropO, 0, 0, 0 }, { VCLanguagePropO, 0, 0, 0 }, { VCLastModifiedPropO, 0, 0, 0 }, { VCLastRevisedPropO, 0, 0, 0 }, { VCLocationPropO, 0, 0, 0 }, { VCLogoPropO, 0, 0, 0 }, { VCMailerPropO, 0, 0, 0 }, { VCMAlarmPropO, 0, 0, 0 }, { VCMCIMailPropO, 0, 0, 0 }, { VCMessagePropO, 0, 0, 0 }, { VCMETPropO, 0, 0, 0 }, { VCModemPropO, 0, 0, 0 }, { VCMPEG2PropO, 0, 0, 0 }, { VCMPEGPropO, 0, 0, 0 }, { VCMSNPropO, 0, 0, 0 }, { VCNamePrefixesPropO, 0, 0, 0 }, { VCNamePropO, 0, 0, 0 }, { VCNameSuffixesPropO, 0, 0, 0 }, { VCNotePropO, 0, 0, 0 }, { VCOrgNamePropO, 0, 0, 0 }, { VCOrgPropO, 0, 0, 0 }, { VCOrgUnit2PropO, 0, 0, 0 }, { VCOrgUnit3PropO, 0, 0, 0 }, { VCOrgUnit4PropO, 0, 0, 0 }, { VCOrgUnitPropO, 0, 0, 0 }, { VCPagerPropO, 0, 0, 0 }, { VCPAlarmPropO, 0, 0, 0 }, { VCParcelPropO, 0, 0, 0 }, { VCPartPropO, 0, 0, 0 }, { VCPCMPropO, 0, 0, 0 }, { VCPDFPropO, 0, 0, 0 }, { VCPGPPropO, 0, 0, 0 }, { VCPhotoPropO, 0, 0, 0 }, { VCPICTPropO, 0, 0, 0 }, { VCPMBPropO, 0, 0, 0 }, { VCPostalBoxPropO, 0, 0, 0 }, { VCPostalCodePropO, 0, 0, 0 }, { VCPostalPropO, 0, 0, 0 }, { VCPowerSharePropO, 0, 0, 0 }, { VCPreferredPropO, 0, 0, 0 }, { VCPriorityPropO, 0, 0, 0 }, { VCProcedureNamePropO, 0, 0, 0 }, { VCProdIdPropO, 0, 0, 0 }, { VCProdigyPropO, 0, 0, 0 }, { VCPronunciationPropO, 0, 0, 0 }, { VCPSPropO, 0, 0, 0 }, { VCPublicKeyPropO, 0, 0, 0 }, { VCQPPropO, 0, 0, 0 }, { VCQuickTimePropO, 0, 0, 0 }, { VCQuotedPrintablePropO, 0, 0, 0 }, { VCRDatePropO, 0, 0, 0 }, { VCRegionPropO, 0, 0, 0 }, { VCRelatedToPropO, 0, 0, 0 }, { VCRepeatCountPropO, 0, 0, 0 }, { VCResourcesPropO, 0, 0, 0 }, { VCRNumPropO, 0, 0, 0 }, { VCRolePropO, 0, 0, 0 }, { VCRRulePropO, 0, 0, 0 }, { VCRSVPPropO, 0, 0, 0 }, { VCRunTimePropO, 0, 0, 0 }, { VCSequencePropO, 0, 0, 0 }, { VCSnoozeTimePropO, 0, 0, 0 }, { VCStartPropO, 0, 0, 0 }, { VCStatusPropO, 0, 0, 0 }, { VCStreetAddressPropO, 0, 0, 0 }, { VCSubTypePropO, 0, 0, 0 }, { VCSummaryPropO, 0, 0, 0 }, { VCTelephonePropO, 0, 0, 0 }, { VCTIFFPropO, 0, 0, 0 }, { VCTimeZonePropO, 0, 0, 0 }, { VCTitlePropO, 0, 0, 0 }, { VCTLXPropO, 0, 0, 0 }, { VCTodoPropO, 0, 0, 0 }, { VCTranspPropO, 0, 0, 0 }, { VCUniqueStringPropO, 0, 0, 0 }, { VCURLPropO, 0, 0, 0 }, { VCURLValuePropO, 0, 0, 0 }, { VCValuePropO, 0, 0, 0 }, { VCVersionPropO, 0, 0, 0 }, { VCVideoPropO, 0, 0, 0 }, { VCVoicePropO, 0, 0, 0 }, { VCWAVEPropO, 0, 0, 0 }, { VCWMFPropO, 0, 0, 0 }, { VCWorkPropO, 0, 0, 0 }, { VCX400PropO, 0, 0, 0 }, { VCX509PropO, 0, 0, 0 }, { VCXRulePropO, 0, 0, 0 }, { VCDTStampPropO, 0, 0, 0 }, { VCPctCompletePropO, 0, 0, 0 }, { VCTzidPropO, 0, 0, 0 }, { VCAlarmPropO, 0, 0, 0 }, { VCTriggerPropO, 0, 0, 0 }, { VCRelatedPropO, 0, 0, 0 }, { VCActionPropO, 0, 0, 0 }, { XEvoAlarmUidO, 0, 0, 0 }, { VCFreqPropO, 0, 0, 0 }, { VCUntilPropO, 0, 0, 0 }, { VCIntervalPropO, 0, 0, 0 }, { VCByDayPropO, 0, 0, 0 }, { VCBySetPosPropO, 0, 0, 0 }, { XEvolutionSpouseO, 0, 0, 0 }, { XEvolutionAssistantO, 0, 0, 0 }, { XEvolutionManagerO, 0, 0, 0 }, { XEvolutionOfficeO, 0, 0, 0 }, { XEvolutionAnniversaryO, 0, 0, 0 }, { VCNicknameO, 0, 0, 0 }, { VCCalendarURIO, 0, 0, 0 }, { VCFBURLO, 0, 0, 0 }, { NULL,0,0,0 } }; int checkprops(VObjectO *v, int i) { VObjectO *prop; int n = 0, k = 0; while (vcardattrs[i][VCARDPROP][k]) { if (!isAPropertyOfO(v, vcardattrs[i][VCARDPROP][k])) { //Property did not match return 1; } k++; } k = 0; while (propNamesO[k][0]) { prop = isAPropertyOfO(v, propNamesO[k][0]); if(prop) { n = 0; if (strcmp(fakeCStringO(vObjectUStringZValueO(prop)), "")) { goto next; } while (vcardattrs[i][VCARDPROP][n]) { if (!strcmp(vcardattrs[i][VCARDPROP][n], propNamesO[k][0])) { goto next; } if (!strcmp(propNamesO[k][0], "QUOTED-PRINTABLE")) { goto next; } if (!strcmp(propNamesO[k][0], "ENCODING:QERA")) { goto next; } n++; } return 1; next: ; } k++; } return 0; } void printprops(ldap_connection *conn, VObjectO *v) { VObjectO *prop; char buffer[2048]; int n = 0, k = 0; strcpy(buffer, "Properties: "); k = 0; while (propNamesO[k][0]) { prop = isAPropertyOfO(v, propNamesO[k][0]); if(prop) { strcat(buffer, propNamesO[k][0]); if (strcmp(fakeCStringO(vObjectUStringZValueO(prop)), "")) { strcat(buffer, ":"); strcat(buffer, fakeCStringO(vObjectUStringZValueO(prop))); } strcat(buffer, ";"); } k++; } ldap_debug(conn, 1, "%s", buffer); } void VObjectOErrorHander(char *errstr) { printf("VObjectO parse failed: %s\n", errstr); } LDAPMod **vcard2ldap(ldap_connection *conn, char *origvcard) { int i = 0, n = 0, x = 0, k = 0, m = 0, count = 0; const char *attributes; GString *name = g_string_new(""); LDAPMod **ldapentries = NULL; char *vcardline, *valueline, value[1024], *vcardname; char *vcard; char *first = NULL, *last = NULL, *middle = NULL, *prefix = NULL, *suffix = NULL; VObjectO *v, *prop, *vcontact; VObjectIteratorO iter; char buffer[2048]; ldap_debug(conn, 3, "converting vcard to ldap"); ldap_debug(conn, 3, "VCARD: %s", origvcard); ldapentries = g_malloc0(1024 * sizeof(LDAPMod *)); registerMimeErrorHandlerO(VObjectOErrorHander); vcontact = Parse_MIMEO(origvcard, strlen(origvcard)); initPropIteratorO(&iter,vcontact); while(moreIterationO(&iter)) { v = nextVObjectO(&iter); attributes = vObjectNameO(v); //Name handling if (!strcmp(attributes,VCNamePropO)) { /* last name */ prop = isAPropertyOfO(vcontact, "FN"); if (!prop) { ldap_debug(conn, 1, "VCARD is missing FN attribute"); //Adding FN ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "cn"; ldapentries[count]->mod_values = malloc(2 * sizeof(char *)); ldapentries[count]->mod_values[0] = "test"; //TODO ldapentries[count]->mod_values[1] = NULL; count++; } prop = isAPropertyOfO(v, VCFamilyNamePropO); if (prop) { ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "sn"; ldapentries[count]->mod_values = malloc(2 * sizeof(char *)); ldapentries[count]->mod_values[0] = strdup(fakeCStringO(vObjectUStringZValueO(prop))); ldapentries[count]->mod_values[1] = NULL; count++; } /* first name */ prop = isAPropertyOfO(v, VCGivenNamePropO); if (prop) { ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "givenName"; ldapentries[count]->mod_values = malloc(2 * sizeof(char *)); ldapentries[count]->mod_values[0] = strdup(fakeCStringO(vObjectUStringZValueO(prop))); ldapentries[count]->mod_values[1] = NULL; count++; } goto next; } //Categories handling if(!strcmp(attributes,VCCategoriesPropO)) { if (!conn->evolution_support) { //No evolution support and evo property ldap_debug(conn, 1, "Detected evolution property CATEGORIES but ldap server lacks evolution support"); goto next; } x = 0; ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "category"; ldapentries[count]->mod_values = malloc(1024 * sizeof(char *)); strcpy(value, fakeCStringO(vObjectUStringZValueO(v))); vcardname = value; for (i = 0; value[i]; i++) { if (value[i] == ',') { value[i] = 0; ldapentries[count]->mod_values[x] = strdup(vcardname); ldapentries[count]->mod_values[x + 1] = NULL; vcardname = &value[i + 1]; x++; } } ldapentries[count]->mod_values[x] = strdup(vcardname); ldapentries[count]->mod_values[x + 1] = NULL; count++; goto next; } //department handling if (!strcmp(attributes,"ORG")) { prop = isAPropertyOfO(v, "ORGNAME"); if (prop) { ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "o"; ldapentries[count]->mod_values = malloc(2 * sizeof(char *)); ldapentries[count]->mod_values[0] = strdup(fakeCStringO(vObjectUStringZValueO(prop))); ldapentries[count]->mod_values[1] = NULL; count++; } prop = isAPropertyOfO(v, "OUN"); if (prop) { ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = "ou"; ldapentries[count]->mod_values = malloc(2 * sizeof(char *)); ldapentries[count]->mod_values[0] = strdup(fakeCStringO(vObjectUStringZValueO(prop))); ldapentries[count]->mod_values[1] = NULL; count++; } goto next; } i = 0; while (vcardattrs[i][0][0]) { ldap_debug(conn, 4, "Comparing %s to %s\n", vcardattrs[i][VCARDATTR][0], attributes); if (!strcmp(attributes, vcardattrs[i][VCARDATTR][0])) { //Found the entry in our array. if (vcardattrs[i][LDAPATTR][0]) { // It needs to be converted //Now check if the properties match if (checkprops(v, i)) { //did not match goto nextattr; } //Search for the attribute in the existing LDAPMod array n = 0; while (ldapentries[n]) { if (!strcmp(ldapentries[n]->mod_type, vcardattrs[i][LDAPATTR][0])) { //Found existing LDAPMod entry x = 0; while (ldapentries[n]->mod_values[x]) { x++; } ldapentries[n]->mod_values[x] = strdup(fakeCStringO(vObjectUStringZValueO(v))); ldapentries[n]->mod_values[x + 1] = NULL; //next vcard part goto next; } n++; } if (!conn->evolution_support && vcardattrs[i][3][0]) { //No evolution support and evo property ldap_debug(conn, 1, "Detected evolution property %s but ldap server lacks evolution support", vcardattrs[i][0][0]); goto next; } //Now convert it to a new LDAPMod entry ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_type = strdup(vcardattrs[i][LDAPATTR][0]); ldapentries[count]->mod_values = malloc(1024 * sizeof(char *)); ldapentries[count]->mod_values[0] = strdup(fakeCStringO(vObjectUStringZValueO(v))); ldapentries[count]->mod_values[1] = NULL; ldap_debug(conn, 2, "Converted %s to %s=%s\n", attributes, ldapentries[n]->mod_type, ldapentries[n]->mod_values[0]); count++; } goto next; } nextattr: i++; } //We could not find the attribute in our database. ldap_debug(conn, 1, "Could not match vcard attribute: %s Possible dataloss!", attributes); printprops(conn, v); next: ; } ldapentries[count] = malloc(sizeof(LDAPMod)); ldapentries[count]->mod_op = 0; ldapentries[count]->mod_type = "objectClass"; ldapentries[count]->mod_values = malloc(6 * sizeof(char *)); ldapentries[count]->mod_values[0] = "top"; ldapentries[count]->mod_values[1] = "person"; ldapentries[count]->mod_values[2] = "organizationalPerson"; ldapentries[count]->mod_values[3] = "inetOrgPerson"; if (conn->evolution_support) { ldapentries[count]->mod_values[4] = "evolutionPerson"; } ldapentries[count]->mod_values[5] = NULL; count++; ldapentries[count] = NULL; ldap_modify_entry(conn, ldapentries); ldap_debug(conn, 2, "end: vcard2ldap"); return ldapentries; }