2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "../util/util.h"
25 #define log_warn log_debug
26 #define log_error log_debug
30 #include <v2l_config.h>
31 #include <v2l_vcard.h>
33 #define LOG_ERROR_MEM log_error(ZONE, "Unable to allocate memory")
35 /* create the <FN> tag */
36 static int _v2l_create_fn (xmlnode vcard
);
38 /* mapping functions from LDAP to XML vCard */
39 static xmlnode
_v2l_ldap2vcard_generic (char *attr
, char **vals
, xmlnode res
,
41 static xmlnode
_v2l_ldap2vcard_generic_group (char *attr
, char **vals
,
42 xmlnode res
, const char *gtag
, const char **tags
);
44 static xmlnode
_v2l_ldap2vcard_n (char *attr
, char **vals
, xmlnode res
);
45 static xmlnode
_v2l_ldap2vcard_nickname (char *attr
, char **vals
, xmlnode res
);
46 static xmlnode
_v2l_ldap2vcard_url (char *attr
, char **vals
, xmlnode res
);
47 static xmlnode
_v2l_ldap2vcard_org (char *attr
, char **vals
, xmlnode res
);
48 static xmlnode
_v2l_ldap2vcard_title (char *attr
, char **vals
, xmlnode res
);
49 static xmlnode
_v2l_ldap2vcard_tel (char *attr
, char **vals
, xmlnode res
);
50 static xmlnode
_v2l_ldap2vcard_adr (char *attr
, char **vals
, xmlnode res
);
51 static xmlnode
_v2l_ldap2vcard_email (char *attr
, char **vals
, xmlnode res
);
53 /* mapping functions from XML Vcard to LDAP */
54 static v2l_LdapRequest
*_v2l_vcard2ldap_generic (v2l_LdapRequest
*req
,
55 xmlnode data
, const char **tags
);
57 static v2l_LdapRequest
*_v2l_vcard2ldap_n (v2l_LdapRequest
*req
, xmlnode data
);
58 static v2l_LdapRequest
*_v2l_vcard2ldap_nickname (v2l_LdapRequest
*req
,
60 static v2l_LdapRequest
*_v2l_vcard2ldap_url (v2l_LdapRequest
*req
,
62 static v2l_LdapRequest
*_v2l_vcard2ldap_org (v2l_LdapRequest
*req
,
64 static v2l_LdapRequest
*_v2l_vcard2ldap_title (v2l_LdapRequest
*req
,
66 static v2l_LdapRequest
*_v2l_vcard2ldap_tel (v2l_LdapRequest
*req
,
68 static v2l_LdapRequest
*_v2l_vcard2ldap_adr (v2l_LdapRequest
*req
,
70 static v2l_LdapRequest
*_v2l_vcard2ldap_email (v2l_LdapRequest
*req
,
73 /******* Translation maps */
74 static const char const *V2L_N_TAGS
[2][5] = {
76 {"FAMILY", "sn", "GIVEN", "givenName", NULL
}
78 static const char *V2L_NICKNAME_TAGS
[2][3] = {
80 {"NICKNAME", "displayName", NULL
}
82 static const char *V2L_URL_TAGS
[2][3] = {
84 {"URL", "labeledURI", NULL
}
86 static const char *V2L_ORG_TAGS
[2][5] = {
88 {"ORGNAME", "o", "ORGUNIT", "ou", NULL
}
90 static const char *V2L_TITLE_TAGS
[2][5] = {
92 {"TITLE", "irisPersonalTitle", "TITLE", "title", NULL
}
94 static const char *V2L_TEL_TAGS
[2][5] = {
96 {"NUMBER", "telephoneNumber", NULL
}
98 static const char *V2L_ADR_TAGS
[2][11] = {
100 {"STREET", "street", "LOCALITY", "l", "REGION", "st", "PCODE", "postalCode",
101 /* "COUNTRY", "c", */ NULL
}
103 static const char *V2L_EMAIL_TAGS
[2][9] = {
105 {"USERID", "irisMailMainAddress", "USERID", "mail", NULL
}
109 static v2l_Ldap2Vcard static_map_ldap
[] = {
110 {"givenName", _v2l_ldap2vcard_n
},
111 {"sn", _v2l_ldap2vcard_n
},
112 {"displayName", _v2l_ldap2vcard_nickname
},
113 {"labeledURI", _v2l_ldap2vcard_url
},
114 {"o", _v2l_ldap2vcard_org
},
115 {"ou", _v2l_ldap2vcard_org
},
116 {"title", _v2l_ldap2vcard_title
},
117 {"telephoneNumber", _v2l_ldap2vcard_tel
},
118 {"street", _v2l_ldap2vcard_adr
},
119 {"l", _v2l_ldap2vcard_adr
},
120 {"st", _v2l_ldap2vcard_adr
},
121 {"postalCode", _v2l_ldap2vcard_adr
},
122 /* {"c", _v2l_ldap2vcard_adr}, */
123 {"mail", _v2l_ldap2vcard_email
},
127 /* <FN> is not handled but created in v2l_create_fn() */
128 static v2l_Vcard2Ldap static_map_vcard
[] = {
129 {"N", _v2l_vcard2ldap_n
},
130 {"NICKNAME", _v2l_vcard2ldap_nickname
},
131 {"URL", _v2l_vcard2ldap_url
},
132 {"ORG", _v2l_vcard2ldap_org
},
133 {"TITLE", _v2l_vcard2ldap_title
},
134 {"TEL", _v2l_vcard2ldap_tel
},
135 {"ADR", _v2l_vcard2ldap_adr
},
136 {"EMAIL", _v2l_vcard2ldap_email
},
142 v2l_vcard_get (v2l_Config
*self
, v2l_LdapConn
*curr_conn
)
144 LDAPMessage
*current_result
;
146 v2l_Ldap2Vcard
*handled
;
151 /* LDAP request is asynchronous */
152 v2l_LdapEvt
*evt_res
;
154 evt_res
= (v2l_LdapEvt
*) malloc (sizeof (v2l_LdapEvt
));
162 evt_res
->ld
= curr_conn
->ld
;
164 /* get user info from LDAP */
165 rc
= v2l_ldap_search (curr_conn
->entry
, self
->suffix
, NULL
, 1, evt_res
);
167 if (rc
!= LDAP_SUCCESS
)
169 log_error(ZONE
, "LDAP error attempting to retrieve user info: %s",
170 ldap_err2string (rc
));
175 v2l_ldap_sync(evt_res
);
177 if (ldap_count_entries (evt_res
->ld
, evt_res
->result
) != 1)
180 "Multiple users with the same dn?, vCard is not retrieved");
185 /* prepare the XML result */
186 vcard
= xmlnode_new_tag ("vCard");
187 xmlnode_put_attrib (vcard
, "xmlns", "vcard-temp");
189 current_result
= ldap_first_entry (evt_res
->ld
, evt_res
->result
);
190 /* step through each attribute in objectclass */
193 ldap_first_attribute (evt_res
->ld
, current_result
, &ber
);
194 current_attr
!= NULL
;
195 current_attr
= ldap_next_attribute (evt_res
->ld
, current_result
, ber
))
197 /* and look for its associated callback */
198 for (handled
= static_map_ldap
; handled
->attrname
!= NULL
; handled
++)
200 if (strcmp (handled
->attrname
, current_attr
) == 0)
202 char **vals
= ldap_get_values (evt_res
->ld
, current_result
,
205 vcard
= (handled
->set
) (current_attr
, vals
, vcard
);
206 ldap_value_free (vals
);
211 ldap_memfree (current_attr
);
219 /* don't forget to free the next attribute */
220 ldap_memfree (current_attr
);
221 ldap_msgfree (evt_res
->result
);
224 _v2l_create_fn (vcard
);
225 log_debug (ZONE
, "vCard read from LDAP: %s", xmlnode2str (vcard
));
231 v2l_vcard_set (v2l_Config
*self
, v2l_LdapConn
*curr_conn
, xmlnode data
)
234 v2l_LdapRequest
*ldap_req
= NULL
;
235 v2l_Vcard2Ldap
*handled
;
239 log_warn (ZONE
, "vCard data is NULL?");
243 for (handled
= static_map_vcard
; handled
->tagname
!= NULL
; handled
++)
245 node
= xmlnode_get_tag (data
, handled
->tagname
);
249 ldap_req
= (handled
->set
) (ldap_req
, node
);
253 return v2l_request_record (self
, curr_conn
, ldap_req
);
256 /* public api ends here */
259 _v2l_create_fn (xmlnode vcard
)
262 char *family
, *given
, *fn_str
;
264 fn
= xmlnode_new_tag ("FN");
265 n
= xmlnode_get_tag (vcard
, V2L_N_TAGS
[0][0]);
266 family
= xmlnode_get_tag_data (n
, V2L_N_TAGS
[1][0]);
267 given
= xmlnode_get_tag_data (n
, V2L_N_TAGS
[1][2]);
269 if ((family
== NULL
) && (given
== NULL
))
271 log_debug (ZONE
, "<fn><n>...</n></fn> is empty, returning");
272 xmlnode_insert_tag_node (vcard
, fn
);
278 fn_str
= (char *) malloc (sizeof (char) * (strlen (family
) + 2));
279 sprintf (fn_str
, "%s ", family
);
283 fn_str
= (char *) realloc (fn_str
,
284 sizeof (char) * (strlen (family
) +
285 2 + strlen (given
)));
286 strcat (fn_str
, given
);
289 xmlnode_insert_cdata (fn
, fn_str
, strlen (fn_str
));
290 xmlnode_insert_tag_node (vcard
, fn
);
299 _v2l_ldap2vcard_generic (char *attr
, char **vals
, xmlnode res
, const char *tag
)
303 node
= xmlnode_new_tag (tag
);
304 xmlnode_insert_cdata (node
, vals
[0], strlen (vals
[0]));
308 xmlnode_insert_tag_node (res
, node
);
318 _v2l_ldap2vcard_generic_group (char *attr
, char **vals
, xmlnode res
,
319 const char *gtag
, const char **tags
)
323 const char **handled
, **pvals
;
327 node
= xmlnode_get_tag (res
, gtag
);
331 node
= xmlnode_new_tag (gtag
);
335 for (handled
= tags
, pvals
= (const char **) vals
;
336 *handled
!= NULL
&& *pvals
!= NULL
; handled
+= 2)
339 if (strcmp (attr
, *(handled
+ 1)) == 0)
341 xmlnode tmp
= xmlnode_new_tag (*handled
);
342 xmlnode_insert_cdata (tmp
, *pvals
, strlen (*pvals
));
343 xmlnode_insert_tag_node (node
, tmp
);
350 xmlnode_insert_tag_node (res
, node
);
357 _v2l_ldap2vcard_n (char *attr
, char **vals
, xmlnode res
)
359 return _v2l_ldap2vcard_generic_group (attr
, vals
, res
, V2L_N_TAGS
[0][0],
364 _v2l_ldap2vcard_nickname (char *attr
, char **vals
, xmlnode res
)
366 return _v2l_ldap2vcard_generic (attr
, vals
, res
, V2L_NICKNAME_TAGS
[0][0]);
370 _v2l_ldap2vcard_url (char *attr
, char **vals
, xmlnode res
)
372 return _v2l_ldap2vcard_generic (attr
, vals
, res
, V2L_URL_TAGS
[0][0]);
376 _v2l_ldap2vcard_org (char *attr
, char **vals
, xmlnode res
)
378 return _v2l_ldap2vcard_generic_group (attr
, vals
, res
,
379 V2L_ORG_TAGS
[0][0], V2L_ORG_TAGS
[1]);
383 _v2l_ldap2vcard_title (char *attr
, char **vals
, xmlnode res
)
385 return _v2l_ldap2vcard_generic (attr
, vals
, res
, V2L_TITLE_TAGS
[0][0]);
389 _v2l_ldap2vcard_tel (char *attr
, char **vals
, xmlnode res
)
391 return _v2l_ldap2vcard_generic_group (attr
, vals
, res
,
392 V2L_TEL_TAGS
[0][0], V2L_TEL_TAGS
[1]);
396 _v2l_ldap2vcard_adr (char *attr
, char **vals
, xmlnode res
)
398 return _v2l_ldap2vcard_generic_group (attr
, vals
, res
,
399 V2L_ADR_TAGS
[0][0], V2L_ADR_TAGS
[1]);
403 _v2l_ldap2vcard_email (char *attr
, char **vals
, xmlnode res
)
405 return _v2l_ldap2vcard_generic_group (attr
, vals
, res
,
406 V2L_EMAIL_TAGS
[0][0], V2L_EMAIL_TAGS
[1]);
411 static v2l_LdapRequest
*
412 _v2l_vcard2ldap_generic (v2l_LdapRequest
*req
, xmlnode data
, const char **tags
)
415 const char **handled
, *str
;
417 for (handled
= tags
; *handled
!= NULL
; handled
+= 2)
419 node
= xmlnode_get_tag (data
, *handled
);
420 str
= xmlnode_get_data(node
);
422 if (node
== NULL
|| str
== NULL
)
424 for (node
= xmlnode_get_firstchild (data
); node
!= NULL
;
425 node
= xmlnode_get_nextsibling (node
))
427 str
= xmlnode_get_data (node
);
429 if (str
!= NULL
&& str
[0] != '\n')
441 req
= v2l_add_attr_str (req
, *(char **) (handled
+ 1), str
);
447 static v2l_LdapRequest
*
448 _v2l_vcard2ldap_n (v2l_LdapRequest
* req
, xmlnode data
)
450 req
= _v2l_vcard2ldap_generic (req
, data
, V2L_N_TAGS
[1]);
454 v2l_LdapRequest
*ptr
;
457 for (ptr
= req
, sn
= NULL
; ptr
!= NULL
; ptr
= ptr
->next
)
459 if (strcmp (ptr
->attr
->mod_type
, "sn") == 0)
461 sn
= ptr
->attr
->mod_values
[0];
468 char *sit
, *sn1
, *sn2
;
470 for (sit
= sn
; *sit
!= ' ' && *sit
!= 0; sit
++);
472 sn1
= (char *) malloc (sizeof (char) * (sit
- sn
+ 1));
479 strncpy (sn1
, sn
, sizeof (char) * (sit
- sn
));
481 ptr
= v2l_add_attr_str (req
, "sn1", sn1
);
491 if (sit
- sn
!= strlen (sn
))
493 sn2
= (char *) malloc (sizeof (char) * (strlen (sit
) + 1));
502 ptr
= v2l_add_attr_str (req
, "sn2", sn2
);
518 static v2l_LdapRequest
*
519 _v2l_vcard2ldap_nickname (v2l_LdapRequest
* req
, xmlnode data
)
521 return _v2l_vcard2ldap_generic (req
, data
, V2L_NICKNAME_TAGS
[1]);
524 static v2l_LdapRequest
*
525 _v2l_vcard2ldap_url (v2l_LdapRequest
* req
, xmlnode data
)
527 return _v2l_vcard2ldap_generic (req
, data
, V2L_URL_TAGS
[1]);
530 static v2l_LdapRequest
*
531 _v2l_vcard2ldap_org (v2l_LdapRequest
* req
, xmlnode data
)
533 return _v2l_vcard2ldap_generic (req
, data
, V2L_ORG_TAGS
[1]);
536 static v2l_LdapRequest
*
537 _v2l_vcard2ldap_title (v2l_LdapRequest
* req
, xmlnode data
)
539 return _v2l_vcard2ldap_generic (req
, data
, V2L_TITLE_TAGS
[1]);
542 static v2l_LdapRequest
*
543 _v2l_vcard2ldap_tel (v2l_LdapRequest
* req
, xmlnode data
)
545 return _v2l_vcard2ldap_generic (req
, data
, V2L_TEL_TAGS
[1]);
548 static v2l_LdapRequest
*
549 _v2l_vcard2ldap_adr (v2l_LdapRequest
* req
, xmlnode data
)
551 return _v2l_vcard2ldap_generic (req
, data
, V2L_ADR_TAGS
[1]);
554 static v2l_LdapRequest
*
555 _v2l_vcard2ldap_email (v2l_LdapRequest
* req
, xmlnode data
)
557 return _v2l_vcard2ldap_generic (req
, data
, V2L_EMAIL_TAGS
[1]);