Full_Name: Jiashun QIAN Version: 2.4.28 OS: CentOS 6 URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (85.115.60.180)
The backend shell and the backend perl can't handle some binary data.
This occurs only with MODIFY because when ADD the binary data is encoded in base64 but not MODIFY.
The binary data is truncated when if it contains \0. In fact, data is stored in a linked list of char * and treated as characters.
--- servers/slapd/back-perl/modify.c XPUSHs(sv_2mortal(newSVpv( mods->sm_values[i].bv_val, 0 ))); ---
The type of mods->sm_values[i].bv_val is char*.
To handle the binary data, for back-perl, just change another function mXPUSHp, which we can put the exacte length of mod->sm_values[i].bv_val as parameter, it's mod->sm_values[i].bv_len. So it will push the total data.
Same problem in servers/slapd/back-shell/modify.c : --- servers/slapd/back-shell/modify.c fprintf( wfp, "%s: %s\n", mod->sm_desc->ad_cname.bv_val, mod->sm_values[i].bv_val /* binary! */ ); ---
To fix this, uses a loop on mod->sm_values[i].bv_len to get all data.
*** openldap-2.4.28.org/servers/slapd/back-perl/modify.c 2011-11-25 19:52:29.000000000 +0100 --- openldap-2.4.28/servers/slapd/back-perl/modify.c 2012-02-02 14:15:37.823838779 +0100 *************** *** 61,67 **** mods->sm_values != NULL && mods->sm_values[i].bv_val != NULL; i++ ) { ! XPUSHs(sv_2mortal(newSVpv( mods->sm_values[i].bv_val, 0 ))); }
/* Fix delete attrib without value. */ --- 61,67 ---- mods->sm_values != NULL && mods->sm_values[i].bv_val != NULL; i++ ) { ! mXPUSHp(mods->sm_values[i].bv_val, mods->sm_values[i].bv_len); }
/* Fix delete attrib without value. */
*** openldap-2.4.28.org/servers/slapd/back-shell/modify.c 2011-11-25 19:52:29.000000000 +0100 --- openldap-2.4.28/servers/slapd/back-shell/modify.c 2012-02-02 14:26:40.609848244 +0100 *************** *** 49,55 **** Modifications *ml = op->orm_modlist; Entry e; FILE *rfp, *wfp; ! int i;
if ( si->si_modify == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, --- 49,56 ---- Modifications *ml = op->orm_modlist; Entry e; FILE *rfp, *wfp; ! int i,j; ! unsigned char *ptr;
if ( si->si_modify == NULL ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, *************** *** 105,112 ****
if( mod->sm_values != NULL ) { for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { ! fprintf( wfp, "%s: %s\n", mod->sm_desc->ad_cname.bv_val, ! mod->sm_values[i].bv_val /* binary! */ ); } }
--- 106,118 ----
if( mod->sm_values != NULL ) { for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { ! fprintf( wfp, "%s: ", mod->sm_desc->ad_cname.bv_val ); ! ptr = mod->sm_values[i].bv_val; ! for(j=0; j < mod->sm_values[i].bv_len; j++) ! { ! fprintf( wfp, "%c", *ptr++ ); ! } ! fprintf( wfp, "\n" ); } }
Special thanks to : Laurent Le Grandois, Cedric Pellerin, Phillipe Prados for the fix