Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.1.5

Bug #2297 truncated binary data
Submitted: 2004-09-07 10:50 UTC
From: martel at post dot pl Assigned: jw
Status: Closed Package: Net_LDAP
PHP Version: 4.3.8 OS: Gentoo 2004.0
Roadmaps: (Not assigned)    
Subscription  


 [2004-09-07 10:50 UTC] martel at post dot pl
Description: ------------ Attribute binary data gets truncated if there is a character 0x00 present. Reproduce code: --------------- $params = array( 'scope' => 'sub', 'sizelimit' => 0, 'timelimit' => 10, 'attrsonly' => false, 'attributes' => array ( 'guid', 'cn' ) ); $srch =& $ldap->search('', '(objectclass=Person)', $params); $en = $srch->shiftEntry(); $attrs = $en->attributes(); $attrs['guid'] = unpack('H*', $attrs['guid']); var_dump::display($attrs); Expected result: ---------------- You should see complete guids. The ones starting with zero are shown as empty strings and the rest is truncated on the first 0x00

Comments

 [2004-10-01 10:33 UTC] jw
Hmmh, having a quick look at this one, I must tell that this is not easliy fixable. The only way to handle binary ldap data in php is by using ldap_get_values_len instead of ldap_get_values. Unfortunately we don't even use ldap_get_values. One possibility would be to pass Net_LDAP_Entry the entry ressource and let it determine via the schema or some option, if we want the data as binary. This would mean a major restructering of the package right now. I might take this into thought while redoing the 0.7 release. So right now there is not much I can do. Sorry! If you or someone else has some thoughts about this, please tell me.
 [2004-10-01 11:02 UTC] martel at post dot pl
For now I have bypassed it through use of: $en =& $srch->shiftEntry(); $tmp = ldap_get_values_len($ldap->_link, $srch->_elink, 'guid'); It's not pretty but it works. And about my thoughts - in the next version you speak of, you could try pre-configure values that are stored in binary form and make sure they are taken by ldap_get_values_len. GUID for exmple is described as SYN_OCTET_STRING in NDS so it's always binary. I bet we can get a list of standard ldap binary attributes from the NDS somehow (if it can't be found in smoe of the RFCs). And at least you could put the binary field names as a config parameter. Then the user would choose whether to get attribute by values_len or vanilla values.
 [2004-10-01 11:27 UTC] jw
Well, your fix works for now (until it gets declared private for php5 ;-)). It is possible to get syntax information out of the schema (syntax = 1.3.6.1.4.1.1466.115.121.1.40). We make use of it anyway to determine which values should get utf8 en- and decoded anyway. The main problem is, that right now the values are already fetched when they are used in the entry class. This has to be changed. Then we can also add a parameter which determines to get the data as binary. Until then, thx for using the class, reporting bugs and most of all sharing your thoughts.
 [2004-10-07 13:23 UTC] jw
Okay, I checked in a couple of changes to CVS which should fix the problem. Attribute checking is done via schema for now, so this has to work first, but it does on most servers. This meant a lot of changes all over the place, but unit tests run fine for now, so there shouldn't be much problems. The only thing is, that this is head which had some api changes somewhere along development. It would be very nice if you could test this version as I don't have any binary data attributes over here. If it does not work for you, tell me, and I have to test myself. You don't need to change your code (except maybe for 0.7 compatibility) as I kept everything compatible. When an entry is instanciated it gets the entry_id now and fetches each attribute, according to its schema syntax (if that is available). No manual setting for now.
 [2004-10-12 11:37 UTC] martel at post dot pl
Well, I'm afraid it's still not working properly: $srch =& $ldap->search('', '(objectClass=Organizational Unit)', $params); if (Net_LDAP::isError($srch)) { trigger_error($srch->getMessage(), E_USER_WARNING); } while ($en =& $srch->shiftEntry()) { var_dump::display($en->dn()); //var_dump::display($en->getValues()); var_dump::display($en->getValue('guid')); var_dump::display(unpack("H*", $en->getValue('guid'))); } Among the values I get for example the guid 80a993b902e7d411bd4f instead of 80a993b902e7d411bd4f000255588efb. Truncated at first \x00 again. PS: A 'single' option in the getValue method was a great idea. Thanks :)
 [2004-10-13 14:13 UTC] jw
Sh... Okay, can you tell if schema checking works for you? ($schema =& $ldap->schema();). If it does, can you send me the output of var_dump::display($schema->get('attribute', 'guid')); I wonder if the attribute syntax is declared the way I check it. I took OpenLDAP syntaxes, but since you are using NDS it might be different.
 [2004-10-14 07:39 UTC] martel at post dot pl
Before we go, I have to tell you that the schema of the guid was unexistent (it gave an Net LDAP Error) until I have made an LDAP mapping of 'guid' to GUID (hence the alias in schema). I have checked if that was the problem with not getting the guid earlier but still no go. Here is the guid schema: array(12) { aliases => array(1) { 0 => string(4) guid } oid => string(29) 2.16.840.1.113719.1.1.4.1.501 name => string(4) grid desc => string(18) Standard Attribute syntax => string(33) 1.3.6.1.4.1.1466.115.121.1.40{16} single-value => int 1 no-user-modification => int 1 x-nds_public_read => string(1) 1 x-nds_not_sched_sync_immediate => string(1) 1 x-nds_lower_bound => string(2) 16 max_length => string(2) 16 type => string(9) attribute } And here is my NDS Person object (I have altered any personal data in the output so the character count isn't correct in the output). array(11) { isManager => string(5) FALSE manager => string(32) cn=AW,ou=IT,o=HQR mail => string(29) MM@pro-futuro.com guid => string(0) givenname => string(6) Michal fullname => string(15) Michal M lastlogin => string(15) 20041013125728Z title => string(37) Administrator Serwisow Internetowych surname => string(7) M uid => string(14) MM } Since the guid is binary this dump above is useless. And after issueing this var_dump: var_dump::display(unpack('H*', $attrs['guid'])); We get: array(1) { 1 => string(0) } Which should print this: 000e44b4097bd71183c80002557cd268: And this problem aside, you have a little bug in LDAP.php at line 992: FATAL [/usr/lib/php/Net/LDAP.php:992] Use of undefined constant LDAP_ERROR - assumed 'LDAP_ERROR' I guess it should be NET_LDAP_ERROR. PS. Please implement a sort function as you have altered the code and my sorting trick does not work at the moment ;) PPS: Maybe we should start e-mailing each other directly since it would be a lot more covenient. What do you think?
 [2004-11-12 19:03 UTC] shaffin_bhanji at yahoo dot ca
Emailing each other directly defeats the purpose of understanding the history behind the change/bugfix that was implemented. In my opinion I find the history of the conversation very intuitive and not to mention that others highly appreciate the work that goes into this product and others for that matter. THANK YOU FOR BEING HEARD AND FOR ALL THE GOOD WORK THAT YOU GUYS ARE PUTTING IN!! :)
 [2004-11-18 13:13 UTC] jw
> Before we go, I have to tell you that the schema of the guid was > unexistent (it gave an Net LDAP Error) until I have made an LDAP > mapping of 'guid' to GUID (hence the alias in schema). I have checked > if that was the problem with not getting the guid earlier but still no > go. This is why we introduced attribute name mapping in Net_LDAP_Entry, as some servers seem to return attribute names as defined in the schema which is fun when working with either objectClass or objectclass which shouldn't make a difference. I will try implementing that in Net_LDAP_Schema. > Here is the guid schema: > > array(12) { > aliases => array(1) { > 0 => string(4) guid > } > oid => string(29) 2.16.840.1.113719.1.1.4.1.501 > name => string(4) grid > desc => string(18) Standard Attribute > syntax => string(33) 1.3.6.1.4.1.1466.115.121.1.40{16} > single-value => int 1 > no-user-modification => int 1 > x-nds_public_read => string(1) 1 > x-nds_not_sched_sync_immediate => string(1) 1 > x-nds_lower_bound => string(2) 16 > max_length => string(2) 16 > type => string(9) attribute > } > > And here is my NDS Person object (I have altered any personal data in > the output so the character count isn't correct in the output). > > array(11) { > isManager => string(5) FALSE > manager => string(32) cn=AW,ou=IT,o=HQR > mail => string(29) MM@pro-futuro.com > guid => string(0) > givenname => string(6) Michal > fullname => string(15) Michal M > lastlogin => string(15) 20041013125728Z > title => string(37) Administrator Serwisow Internetowych > surname => string(7) M > uid => string(14) MM > } > > Since the guid is binary this dump above is useless. And after issueing > this var_dump: > var_dump::display(unpack('H*', $attrs['guid'])); > > We get: > > array(1) { > 1 => string(0) > } > > Which should print this: 000e44b4097bd71183c80002557cd268: Okay, the problem is the length definition at the end of syntax. Could you change Net/LDAP/Entry.php in line 227: - if ($attr_s['syntax'] == NET_LDAP_SYNTAX_OCTET_STRING) { + if (false !== strpos($attr_s['syntax'], NET_LDAP_SYNTAX_OCTET_STRING)) { > And this problem aside, you have a little bug in LDAP.php at line 992: > > FATAL [/usr/lib/php/Net/LDAP.php:992] Use of undefined constant > LDAP_ERROR - assumed 'LDAP_ERROR' > > I guess it should be NET_LDAP_ERROR. Will fix that. > PS. Please implement a sort function as you have altered the code and > my sorting trick does not work at the moment ;) Sorting will be hard to implement. What trick were you using?
 [2004-11-18 13:15 UTC] jw
On Thursday 14 of October 2004 10:50, you wrote: > Okay, the problem is the length definition at the end of syntax. Could > you change Net/LDAP/Entry.php in line 227: > > - if ($attr_s['syntax'] == NET_LDAP_SYNTAX_OCTET_STRING) { > + if (false !== strpos($attr_s['syntax'], NET_LDAP_SYNTAX_OCTET_STRING)) > { It works! Well done :) Now I'm going to convert my old scripts to the new code. I'm using "$en = $srch->shiftEntry(); $attrs = $en->attributes();" all over the place. I'll let you know in case something goes wrong. > > PS. Please implement a sort function as you have altered the code and > > my sorting trick does not work at the moment ;) > Sorting will be hard to implement. What trick were you using? The same way I got the binary values earlier ;) ldap_sort($ldap->_link, $srch->_search, 'surname'); while ($en = $srch->shiftEntry()) { > > PPS: Maybe we should start e-mailing each other directly since it would > > be a lot more covenient. What do you think? > Just did that! And if in the future you wish me to test something you don't have access to, just feel free to drop me an email.
 [2004-11-18 13:16 UTC] jw
> > Okay, the problem is the length definition at the end of syntax. Could > > you change Net/LDAP/Entry.php in line 227: > > > > - if ($attr_s['syntax'] == NET_LDAP_SYNTAX_OCTET_STRING) { > > + if (false !== strpos($attr_s['syntax'], NET_LDAP_SYNTAX_OCTET_STRING)) > > { > > It works! Well done :) Great! Thanks for testing this out. > Now I'm going to convert my old scripts to the new code. I'm using "$en = > $srch->shiftEntry(); $attrs = $en->attributes();" all over the place. I'll > let you know in case something goes wrong. I remodeled some functions to be more like perl-ldap. Don't know if that makes sense with php, so if you have suggestions how to optimize functions go ahead. > > > PS. Please implement a sort function as you have altered the code and > > > my sorting trick does not work at the moment ;) > > Sorting will be hard to implement. What trick were you using? > > The same way I got the binary values earlier ;) > > ldap_sort($ldap->_link, $srch->_search, 'surname'); > while ($en = $srch->shiftEntry()) { Somehow, I missed this function entirely. It should be no problem to implement that. Besides that, it should still work your way. > And if in the future you wish me to test something you don't have access to, > just feel free to drop me an email. I will do that. Been thinking over lunch about redoing the changes and put the attribute fetching back into Search.php ...
 [2004-11-18 13:19 UTC] jw
This bug has been fixed in CVS. In case this was a documentation problem, the fix will show up at the end of next Sunday (CET) on pear.php.net. In case this was a pear.php.net website problem, the change will show up on the website in short time. Thank you for the report, and for helping us make PEAR better.