+
+/*
+ * Extract a user's Internet email addresses from LDAP.
+ * Returns zero if we got a valid set of addresses; nonzero for error.
+ */
+int extract_email_addresses_from_ldap(char *ldap_dn, char *emailaddrs)
+{
+ LDAP *ldserver = NULL;
+ struct timeval tv;
+ LDAPMessage *search_result = NULL;
+ LDAPMessage *entry = NULL;
+ char **mail;
+ char *attrs[] = { "*","+",NULL};
+
+ if (!ldap_dn) return(1);
+ if (!emailaddrs) return(1);
+
+ ldserver = ctdl_ldap_bind();
+ if (!ldserver) return(-1);
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+
+ syslog(LOG_DEBUG, "ldap: search: %s", ldap_dn);
+ (void) ldap_search_ext_s(
+ ldserver, // ld
+ ldap_dn, // base
+ LDAP_SCOPE_SUBTREE, // scope
+ NULL, // filter
+ attrs, // attrs (all attributes)
+ 0, // attrsonly (attrs + values)
+ NULL, // serverctrls (none)
+ NULL, // clientctrls (none)
+ &tv, // timeout
+ 1, // sizelimit (1 result max)
+ &search_result // res
+ );
+
+ /* Ignore the return value of ldap_search_ext_s(). Sometimes it returns an error even when
+ * the search succeeds. Instead, we check to see whether search_result is still NULL.
+ */
+ if (search_result == NULL) {
+ syslog(LOG_DEBUG, "ldap: zero search results were returned");
+ ldap_unbind(ldserver);
+ return(4);
+ }
+
+ /* At this point we've got at least one result from our query. If there are multiple
+ * results, we still only look at the first one.
+ */
+ emailaddrs[0] = 0; /* clear out any previous results */
+ entry = ldap_first_entry(ldserver, search_result);
+ if (entry) {
+ syslog(LOG_DEBUG, "ldap: search got user details");
+ mail = ldap_get_values(ldserver, search_result, "mail");
+
+ if (mail) {
+ int q;
+ for (q=0; q<ldap_count_values(mail); ++q) {
+ if (IsDirectory(mail[q], 0)) {
+ if ((strlen(emailaddrs) + strlen(mail[q]) + 2) > 512) {
+ syslog(LOG_ERR, "ldap: can't fit all email addresses into user record");
+ }
+ else {
+ if (!IsEmptyStr(emailaddrs)) {
+ strcat(emailaddrs, "|");
+ }
+ strcat(emailaddrs, mail[q]);
+ }
+ }
+ }
+ }
+ }
+
+ /* free the results */
+ ldap_msgfree(search_result);
+
+ /* unbind so we can go back in as the authenticating user */
+ ldap_unbind(ldserver);
+ return(0);
+}
+
+
+/*
+ * Scan LDAP for users and populate Citadel's user database with everyone
+ */
+void CtdlSynchronizeUsersFromLDAP(void)
+{
+ LDAP *ldserver = NULL;
+ LDAPMessage *search_result = NULL;
+ LDAPMessage *entry = NULL;
+ char *user_dn = NULL;
+ char searchstring[1024];
+ struct timeval tv;
+
+ if ((CtdlGetConfigInt("c_auth_mode") != AUTHMODE_LDAP) && (CtdlGetConfigInt("c_auth_mode") != AUTHMODE_LDAP_AD)) {
+ return; // not running LDAP
+ }
+
+ syslog(LOG_INFO, "ldap: synchronizing Citadel user database from LDAP");
+
+ ldserver = ctdl_ldap_bind();
+ if (!ldserver) return;
+
+ tv.tv_sec = 10;
+ tv.tv_usec = 0;
+
+ if (CtdlGetConfigInt("c_auth_mode") == AUTHMODE_LDAP_AD) {
+ snprintf(searchstring, sizeof(searchstring), "(&(objectClass=user)(objectClass=person)(!(objectClass=computer)))");
+ } else {
+ snprintf(searchstring, sizeof(searchstring), "(objectClass=inetOrgPerson)");
+ }
+
+ syslog(LOG_DEBUG, "ldap: search: %s", searchstring);
+ (void) ldap_search_ext_s(
+ ldserver, // ld
+ CtdlGetConfigStr("c_ldap_base_dn"), // base
+ LDAP_SCOPE_SUBTREE, // scope
+ searchstring, // filter
+ NULL, // attrs (all attributes)
+ 0, // attrsonly (attrs + values)
+ NULL, // serverctrls (none)
+ NULL, // clientctrls (none)
+ &tv, // timeout
+ INT_MAX, // sizelimit (max)
+ &search_result // result
+ );
+
+ /* Ignore the return value of ldap_search_ext_s(). Sometimes it returns an error even when
+ * the search succeeds. Instead, we check to see whether search_result is still NULL.
+ */
+ if (search_result == NULL) {
+ syslog(LOG_DEBUG, "ldap: zero search results were returned");
+ ldap_unbind(ldserver);
+ return;
+ }
+
+ syslog(LOG_DEBUG, "ldap: %d entries returned", ldap_count_entries(ldserver, search_result));
+ entry = ldap_first_entry(ldserver, search_result);
+ while (entry) {
+
+ user_dn = ldap_get_dn(ldserver, entry);
+ if (user_dn) {
+ syslog(LOG_DEBUG, "ldap: found %s", user_dn);
+
+ int fullname_size = 256;
+ char fullname[256] = { 0 } ;
+ uid_t uid = (-1);
+
+ derive_fullname_from_ldap_result(fullname, fullname_size, ldserver, entry);
+ uid = derive_uid_from_ldap(ldserver, entry);
+ syslog(LOG_DEBUG, "\033[33mldap: display name: <%s> , uid = <%d>\033[0m", fullname, uid);
+
+ // FIXME now create or update the user
+ int i;
+ struct ctdluser usbuf;
+
+ i = getuserbyuid(&usbuf, uid);
+ if (i == 0) {
+ syslog(LOG_DEBUG, "\033[32m...and that user EXISTZ0RS!!!\033[0m");
+ }
+ else {
+ syslog(LOG_DEBUG, "\033[31m...and that user D0EZ N0T EXISTZ0R!!\033[0m");
+ }
+
+
+ }
+
+ entry = ldap_next_entry(ldserver, entry);
+ }
+
+ /* free the results */
+ ldap_msgfree(search_result);
+
+ /* unbind so we can go back in as the authenticating user */
+ ldap_unbind(ldserver);
+}
+