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 typedef struct v2l_vCardItem
40 struct v2l_vCardItem
*next
;
43 static int _v2l_vcard_maps_init (v2l_Config
*self
);
45 /* create the <FN> tag */
46 static int _v2l_create_fn (xmlnode vcard
);
47 /* set sn1 and sn2 from sn */
48 static v2l_LdapRequest
*_v2l_set_sn12 (v2l_LdapRequest
*req
);
50 /* mapping functions from LDAP to XML vCard */
51 static xmlnode
_v2l_ldap2vcard_generic (v2l_vCardItem
*item
, char **vals
,
54 static xmlnode
_v2l_ldap2vcard_photo (v2l_vCardItem
*item
, char **vals
,
57 /* mapping functions from XML Vcard to LDAP */
58 static v2l_LdapRequest
*_v2l_vcard2ldap_generic (v2l_vCardItem
*item
,
59 xmlnode data
, v2l_LdapRequest
*req
);
61 static v2l_vCardItem
*_v2l_vcard_find_attr (v2l_vCardItem
*item
,
64 static v2l_vCardItem
*
65 _v2l_vcard_find_tag (v2l_vCardItem
*item
, char *tag
);
68 static v2l_vCardItem
*_V2L_TPL
;
70 /******* Translation maps */
71 static const char *_V2L_MAP_VCARD
[] = {
125 v2l_vcard_get (v2l_Config
*self
, v2l_LdapConn
*curr_conn
)
127 LDAPMessage
*current_result
;
133 if (!_v2l_vcard_maps_init (self
))
135 log_error (ZONE
, "Unreadable/malformed vCard template!");
139 /* LDAP request is asynchronous */
140 v2l_LdapEvt
*evt_res
;
142 evt_res
= (v2l_LdapEvt
*) malloc (sizeof (v2l_LdapEvt
));
150 evt_res
->ld
= curr_conn
->ld
;
152 /* get user info from LDAP */
153 rc
= v2l_ldap_search (curr_conn
->entry
, self
->suffix
, NULL
, 1, evt_res
);
155 if (rc
!= LDAP_SUCCESS
)
157 log_error (ZONE
, "LDAP error attempting to retrieve user info: %s",
158 ldap_err2string (rc
));
163 v2l_ldap_sync(evt_res
);
165 if (ldap_count_entries (evt_res
->ld
, evt_res
->result
) != 1)
168 "Multiple users with the same dn?, vCard is not retrieved");
173 /* prepare the XML result */
174 vcard
= xmlnode_new_tag ("vCard");
175 xmlnode_put_attrib (vcard
, "xmlns", "vcard-temp");
177 current_result
= ldap_first_entry (evt_res
->ld
, evt_res
->result
);
179 /* step through each attribute in objectclass */
181 ldap_first_attribute (evt_res
->ld
, current_result
, &ber
);
182 current_attr
!= NULL
;
183 current_attr
= ldap_next_attribute (evt_res
->ld
, current_result
, ber
))
185 v2l_vCardItem
*match
;
187 match
= _v2l_vcard_find_attr (_V2L_TPL
, current_attr
);
192 vals
= ldap_get_values (evt_res
->ld
, current_result
, current_attr
);
197 if (match
->group
!= NULL
&& (strcmp (match
->group
, "PHOTO") == 0))
199 _v2l_ldap2vcard_photo (match
, vals
, vcard
);
203 _v2l_ldap2vcard_generic (match
, vals
, vcard
);
206 ldap_value_free (vals
);
210 ldap_memfree (current_attr
);
218 /* don't forget to free the next attribute */
219 ldap_memfree (current_attr
);
220 ldap_msgfree (evt_res
->result
);
223 _v2l_create_fn (vcard
);
229 v2l_vcard_set (v2l_Config
*self
, v2l_LdapConn
*curr_conn
, xmlnode data
)
232 v2l_LdapRequest
*ldap_req
= NULL
;
237 log_warn (ZONE
, "vCard data is NULL?");
241 if (!_v2l_vcard_maps_init (self
))
243 log_error (ZONE
, "Unreadable/Malformed vCard template!");
251 if (strcmp (item
->vcard
, "FN") == 0) /* FIXME: ugly */
256 if (item
->group
!= NULL
)
260 sprintf (tag
, "%s/%s", item
->group
, item
->vcard
);
261 node
= xmlnode_get_tag (data
, tag
);
265 node
= xmlnode_get_tag (data
, item
->vcard
);
270 ldap_req
= _v2l_vcard2ldap_generic (item
, node
, ldap_req
);
274 } while (item
!= NULL
);
276 ldap_req
= _v2l_set_sn12 (ldap_req
);
278 return v2l_request_record (self
, curr_conn
, ldap_req
);
281 /* public api ends here */
284 _v2l_vcard_maps_init (v2l_Config
*self
)
287 char **stag
, *tmp
, group
[10];
290 if (_V2L_TPL
!= NULL
)
295 tpl
= xmlnode_file (self
->confpath
);
297 for (stag
= (char **) _V2L_MAP_VCARD
; *stag
!= NULL
; stag
++)
299 tmp
= strchr(*stag
, '/');
308 sprintf(group
, "%.*s", tmp
- *stag
, *stag
);
312 tag
= xmlnode_get_tag (tpl
, *stag
);
314 if (xmlnode_get_data(tag
) != NULL
)
323 ptr
= (v2l_vCardItem
*) pmalloc (self
->poolref
,
324 sizeof(v2l_vCardItem
));
327 ptr
->ldap
= pstrdup (self
->poolref
, xmlnode_get_data(tag
));
329 ptr
->group
= group
[0] == 0 ? NULL
:
330 pstrdup (self
->poolref
, group
);
332 if (_V2L_TPL
== NULL
)
343 sprintf (find_attr
, "%s?v2ln=%d", *stag
, ++ntags
);
344 tag
= xmlnode_get_tag (tpl
, find_attr
);
345 } while (tag
&& xmlnode_get_data (tag
) != NULL
&& ntags
< 10);
355 static v2l_vCardItem
*
356 _v2l_vcard_find_tag (v2l_vCardItem
*item
, char *tag
)
358 v2l_vCardItem
*res
= NULL
;
362 if (strcmp (item
->vcard
, tag
) == 0)
375 static v2l_vCardItem
*
376 _v2l_vcard_find_attr (v2l_vCardItem
*item
, char *attr
)
378 v2l_vCardItem
*res
= NULL
;
382 if (strcmp (item
->ldap
, attr
) == 0)
395 _v2l_create_fn (xmlnode vcard
)
398 char *family
, *given
, *fn_str
;
401 fn
= xmlnode_insert_tag (vcard
, "FN");
402 n
= xmlnode_get_tag (vcard
, "N");
403 family
= xmlnode_get_tag_data (n
, "FAMILY");
404 given
= xmlnode_get_tag_data (n
, "GIVEN");
407 len
+= (family
!= NULL
) ? strlen (family
) : 0;
408 len
+= (given
!= NULL
) ? strlen (given
) : 0;
412 log_debug (ZONE
, "<fn><n>...</n></fn> is empty, returning");
416 fn_str
= (char *) malloc (sizeof (char) * (len
+ 2));
428 sprintf (fn_str
, "%s ", family
);
433 strcat (fn_str
, given
);
436 xmlnode_insert_cdata (fn
, fn_str
, len
+ 1);
445 _v2l_ldap2vcard_generic (v2l_vCardItem
*item
, char **vals
, xmlnode res
)
449 if (item
->group
!= NULL
)
451 node
= xmlnode_get_tag (res
, item
->group
);
455 node
= xmlnode_insert_tag(res
, item
->group
);
463 node
= xmlnode_insert_tag (node
, item
->vcard
);
464 xmlnode_insert_cdata (node
, vals
[0], strlen (vals
[0]));
470 _v2l_ldap2vcard_photo (v2l_vCardItem
*item
, char **vals
, xmlnode res
)
472 xmlnode mimetype
, photo
;
474 res
= _v2l_ldap2vcard_generic (item
, vals
, res
);
476 /* FIXME: mimetype is hardcoded */
477 photo
= xmlnode_get_tag (res
, "PHOTO");
478 mimetype
= xmlnode_insert_tag (photo
, "TYPE");
479 xmlnode_insert_cdata (mimetype
, "image/jpeg", sizeof ("image/jpeg"));
486 static v2l_LdapRequest
*
487 _v2l_vcard2ldap_generic (v2l_vCardItem
*item
, xmlnode data
,
488 v2l_LdapRequest
*req
)
492 str
= xmlnode_get_data (data
);
494 return str
== NULL
? req
: v2l_add_attr_str (req
, item
->ldap
, str
);
497 static v2l_LdapRequest
*
498 _v2l_set_sn12 (v2l_LdapRequest
*req
)
502 v2l_LdapRequest
*ptr
;
505 for (ptr
= req
, sn
= NULL
; ptr
!= NULL
; ptr
= ptr
->next
)
507 if (strcmp (ptr
->attr
->mod_type
, "sn") == 0)
509 sn
= ptr
->attr
->mod_values
[0];
516 char *sit
, *sn1
, *sn2
;
518 for (sit
= sn
; *sit
!= ' ' && *sit
!= 0; sit
++);
520 sn1
= (char *) malloc (sizeof (char) * (sit
- sn
+ 1));
527 strncpy (sn1
, sn
, sizeof (char) * (sit
- sn
));
529 ptr
= v2l_add_attr_str (req
, "sn1", sn1
);
539 if (sit
- sn
!= strlen (sn
))
541 sn2
= (char *) malloc (sizeof (char) * (strlen (sit
) + 1));
550 ptr
= v2l_add_attr_str (req
, "sn2", sn2
);