1) The problem long discussed upstream to do with LDAP auth wanting the user name offered after the PASS command to stick around for later vcard use. The approach is to have vcard related searches use the citserver username to search against the ldap CN, while login searches behave as in the release version.
2) The vcard has a field uid, which citserver uses to tag vcards for uniqueness. LDAP also has a uuid for each of its records, most aptly saved also in the vcard as uuid. These collided causing the vcard to be reloaded every check owing to the overwriting the LDAP written uid over the citserver use of the same field. The patches below use the RFC approved 2.1 X- extension to support the field X-UUID for the ldap uuid. There's also small code cleanup to avoid setting the UID twice.
* GNU General Public License for more details.
*/
* GNU General Public License for more details.
*/
-int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size, uid_t *found_uid);
+int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size, uid_t *found_uid, int lookup_based_on_uid);
int CtdlTryPasswordLDAP(char *user_dn, const char *password);
int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v);
int CtdlTryPasswordLDAP(char *user_dn, const char *password);
int Ctdl_LDAP_to_vCard(char *ldap_dn, struct vCard *v);
int CtdlTryUserLDAP(char *username,
char *found_dn, int found_dn_size,
char *fullname, int fullname_size,
int CtdlTryUserLDAP(char *username,
char *found_dn, int found_dn_size,
char *fullname, int fullname_size,
+ uid_t *uid, int lookup_based_on_username)
{
LDAP *ldserver = NULL;
int i;
{
LDAP *ldserver = NULL;
int i;
tv.tv_usec = 0;
if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
tv.tv_usec = 0;
if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
- snprintf(searchstring, sizeof(searchstring), "(sAMAccountName=%s)", username);
+ if (lookup_based_on_username != 0)
+ snprintf(searchstring, sizeof(searchstring), "(displayName=%s)",username);
+ else
+ snprintf(searchstring, sizeof(searchstring), "(sAMAccountName=%s)", username);
- snprintf(searchstring, sizeof(searchstring), "(&(objectclass=posixAccount)(uid=%s))", username);
+ if (lookup_based_on_username != 0)
+ snprintf(searchstring, sizeof(searchstring), "(cn=%s)",username);
+ else
+ snprintf(searchstring, sizeof(searchstring), "(&(objectclass=posixAccount)(uid=%s))", username);
}
syslog(LOG_DEBUG, "LDAP search: %s", searchstring);
}
syslog(LOG_DEBUG, "LDAP search: %s", searchstring);
ldap_value_free(values);
}
}
ldap_value_free(values);
}
}
-
- if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
- values = ldap_get_values(ldserver, search_result, "objectGUID");
- if (values) {
- if (values[0]) {
- if (uid != NULL) {
- *uid = abs(HashLittle(values[0], strlen(values[0])));
- syslog(LOG_DEBUG, "uid hashed from objectGUID = %d", *uid);
+ /* If we know the username is the CN/displayName, we already set the uid*/
+ if (lookup_based_on_username==0) {
+ if (config.c_auth_mode == AUTHMODE_LDAP_AD) {
+ values = ldap_get_values(ldserver, search_result, "objectGUID");
+ if (values) {
+ if (values[0]) {
+ if (uid != NULL) {
+ *uid = abs(HashLittle(values[0], strlen(values[0])));
+ syslog(LOG_DEBUG, "uid hashed from objectGUID = %d", *uid);
+ }
+ ldap_value_free(values);
- ldap_value_free(values);
- }
- else {
- values = ldap_get_values(ldserver, search_result, "uidNumber");
- if (values) {
- if (values[0]) {
- syslog(LOG_DEBUG, "uidNumber = %s", values[0]);
- if (uid != NULL) {
- *uid = atoi(values[0]);
+ else {
+ values = ldap_get_values(ldserver, search_result, "uidNumber");
+ if (values) {
+ if (values[0]) {
+ syslog(LOG_DEBUG, "uidNumber = %s", values[0]);
+ if (uid != NULL) {
+ *uid = atoi(values[0]);
+ }
+ ldap_value_free(values);
- ldap_value_free(values);
if (strcmp(vals[i],oldval)) break;
}
if (i!=numvals) {
if (strcmp(vals[i],oldval)) break;
}
if (i!=numvals) {
+ syslog(LOG_DEBUG, "LDAP: vcard property %s, element %d of %d changed from %s to %s\n", propname, i, numvals, oldval, vals[i]);
for(i=0;i<numvals;i++) vcard_set_prop(v,propname,vals[i],(i==0) ? 0 : 1);
return 1;
}
for(i=0;i<numvals;i++) vcard_set_prop(v,propname,vals[i],(i==0) ? 0 : 1);
return 1;
}
if (mail) {
changed_something |= vcard_set_props_iff_different(v,"email;internet",ldap_count_values(mail),mail);
}
if (mail) {
changed_something |= vcard_set_props_iff_different(v,"email;internet",ldap_count_values(mail),mail);
}
- if (uuid) changed_something |= vcard_set_one_prop_iff_different(v,"uid","%s",uuid[0]);
+ if (uuid) changed_something |= vcard_set_one_prop_iff_different(v,"X-uuid","%s",uuid[0]);
if (o) changed_something |= vcard_set_one_prop_iff_different(v,"org","%s",o[0]);
if (cn) changed_something |= vcard_set_one_prop_iff_different(v,"fn","%s",cn[0]);
if (title) changed_something |= vcard_set_one_prop_iff_different(v,"title","%s",title[0]);
if (o) changed_something |= vcard_set_one_prop_iff_different(v,"org","%s",o[0]);
if (cn) changed_something |= vcard_set_one_prop_iff_different(v,"fn","%s",cn[0]);
if (title) changed_something |= vcard_set_one_prop_iff_different(v,"title","%s",title[0]);
vcard_set_prop(v, "FBURL;PREF", buf, 0);
}
vcard_set_prop(v, "FBURL;PREF", buf, 0);
}
- /* If the vCard has no UID, then give it one. */
s = vcard_get_prop(v, "UID", 1, 0, 0);
s = vcard_get_prop(v, "UID", 1, 0, 0);
+ if (s == NULL) { /* Note LDAP auth sets UID from the LDAP UUID, use that if it exists. */
+ /* Enforce local UID policy if applicable */
+ if (yes_my_citadel_config) {
+ snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, msg->cm_fields[eAuthor], NODENAME);
+ } else {
+ /* If the vCard has no UID, then give it one. */
- vcard_set_prop(v, "UID", buf, 0);
- }
+ }
+ vcard_set_prop(v, "UID", buf, 0);
+ }
- /* Enforce local UID policy if applicable */
- if (yes_my_citadel_config) {
- snprintf(buf, sizeof buf, VCARD_EXT_FORMAT, msg->cm_fields[eAuthor], NODENAME);
- vcard_set_prop(v, "UID", buf, 0);
- }
/*
* Set the EUID of the message to the UID of the vCard.
/*
* Set the EUID of the message to the UID of the vCard.
char buf[256];
int i;
struct vCard *v;
char buf[256];
int i;
struct vCard *v;
+ int need_default_vcard;
vcard_fn_to_n(vname, usbuf->fullname, sizeof vname);
syslog(LOG_DEBUG, "Converted <%s> to <%s>", usbuf->fullname, vname);
vcard_fn_to_n(vname, usbuf->fullname, sizeof vname);
syslog(LOG_DEBUG, "Converted <%s> to <%s>", usbuf->fullname, vname);
#endif // HAVE_GETPWUID_R
snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, config.c_fqdn);
vcard_add_prop(v, "email;internet", buf);
#endif // HAVE_GETPWUID_R
snprintf(buf, sizeof buf, "%s@%s", pwd.pw_name, config.c_fqdn);
vcard_add_prop(v, "email;internet", buf);
- /* Everyone gets an email address based on their display name */
- snprintf(buf, sizeof buf, "%s@%s", usbuf->fullname, config.c_fqdn);
- for (i=0; buf[i]; ++i) {
- if (buf[i] == ' ') buf[i] = '_';
- }
- vcard_add_prop(v, "email;internet", buf);
* into the user's vCard.
*/
if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
* into the user's vCard.
*/
if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
int found_user;
char ldap_cn[512];
char ldap_dn[512];
int found_user;
char ldap_cn[512];
char ldap_dn[512];
- found_user = CtdlTryUserLDAP(usbuf->fullname, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &ldap_uid);
+ found_user = CtdlTryUserLDAP(usbuf->fullname, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &usbuf->uid,1);
if (found_user == 0) {
if (Ctdl_LDAP_to_vCard(ldap_dn, v)) {
/* Allow global address book and internet directory update without login long enough to write this. */
CC->vcard_updated_by_ldap++; /* Otherwise we'll only update the user config. */
if (found_user == 0) {
if (Ctdl_LDAP_to_vCard(ldap_dn, v)) {
/* Allow global address book and internet directory update without login long enough to write this. */
CC->vcard_updated_by_ldap++; /* Otherwise we'll only update the user config. */
syslog(LOG_DEBUG, "LDAP Created Initial Vcard for %s\n",usbuf->fullname);
}
}
}
#endif
syslog(LOG_DEBUG, "LDAP Created Initial Vcard for %s\n",usbuf->fullname);
}
}
}
#endif
+ if (need_default_vcard!=0) {
+ /* Everyone gets an email address based on their display name */
+ snprintf(buf, sizeof buf, "%s@%s", usbuf->fullname, config.c_fqdn);
+ for (i=0; buf[i]; ++i) {
+ if (buf[i] == ' ') buf[i] = '_';
+ }
+ vcard_add_prop(v, "email;internet", buf);
+ }
vcard_write_user(usbuf, v);
vcard_free(v);
vcard_write_user(usbuf, v);
vcard_free(v);
char ldap_cn[256];
char ldap_dn[256];
char ldap_cn[256];
char ldap_dn[256];
- found_user = CtdlTryUserLDAP(username, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &ldap_uid);
+ found_user = CtdlTryUserLDAP(username, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &ldap_uid, 0);
if (found_user != 0) {
return login_not_found;
}
if (found_user != 0) {
return login_not_found;
}
#ifdef HAVE_LDAP
if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
#ifdef HAVE_LDAP
if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
- if (CtdlTryUserLDAP(username, NULL, 0, username, sizeof username, &uid) != 0) {
+ if (CtdlTryUserLDAP(username, NULL, 0, username, sizeof username, &uid, 0) != 0) {
return(ERROR + NO_SUCH_USER);
}
}
return(ERROR + NO_SUCH_USER);
}
}