Closed Bug 3342 Opened 26 years ago Closed 25 years ago

Problems add()'ing entries with binary values

Categories

(Directory :: PerLDAP, defect, P1)

All
Solaris
defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: leif, Assigned: leif)

References

Details

From: "Carlos de Sousa" <Carlos.de_Sousa@ebc.ericsson.se>

Thanx, but I can't manage to get it to work with the addValue method, I did
got
it to work setting a HASH like below:

#
#  $entry = {
#       "objectclass"              => {"a",[\@object_classes]},
#       "uid"                      => {"a",["$uid"]},
#       "cn"                       => {"a",[\@cns]},
#       "sn"                       => {"a",["$sn0"]},
#       "initials"                 => {"a",["$initials0"]},
#       "l"                        => {"a",["$l"]},
#       "mailcode"                 => {"a",["$mailcode"]},
#       "mailsystemtype"           => {"a",["$mailsystemtype"]},
#       "maildelivery"             => {"a",["$maildelivery"]},
#       "mailnativeaddress"        => {"a",["$mailnativeaddress"]},
#       "mhs-or-addresses"         => {"a",["$mhs_or_addresses"]},
#       "givenname"                => {"a",["$givenname0"]},
#       "departmentnumber"         => {"a",["$departmentnumber"]},
#       "labeleduri"               => {"a",["$labeleduri"]},
#       "mail"                     => {"a",["$mail"]},
#       "telephonenumber"          => {"a",["$telephonenumber"]},
#       "ecnumber"                 => {"a",["$ecnumber"]},
#       "pager"                    => {"a",["$pager"]},
#       "mobile"                   => {"a",["$mobile"]},
#       "account"                  => {"a",["$account"]},
#       "employeenumber"           => {"a",["$employeenumber"]},
#       "vcard"                    => {"a",["$vcard"]},
#       "description"              => {"a",["$description0"]},
#       "postaladdress"            => {"a",["$postaladdress"]},
#       "ou"                       => {"a",["$ou"]},
#       "facsimiletelephonenumber" => {"a",["$facsimiletelephonenumber"]},
#       "orgsubunit"               => {"a",["$orgsubunit"]},
#       "roomnumber"               => {"a",["$roomnumber"]},
#       "title"                    => {"a",["$title"]},
#       "userpassword"             => {"a",["$userpassword"]},
#       "jpegphoto"                => {"ab",[$jpegphoto]},
#  };

This is the only thing I get in attribute jpegphoto when using the addValue
method:

jpegphoto:: /9j/4A==

I have checked the string length just before calling the addValue method at
it is
13244 bytes, but it seems addValue is trucating somehow!

I do exactly like your example below, except I using the add and not the
update method.

Any hints?

Sorry for bugging you with this!

Best Regards
Carlos de Sousa


-----Original Message-----
From: leif@netscape.com [mailto:leif@netscape.com]
Sent: den 3 februari 1999 10:44
To: Carlos de Sousa
Subject: Re: PerLDAP


Carlos de Sousa wrote:

> I have the 1.2 that you made accesible for me up and running! It's
> great!
>
> How would I do to add a binary value to an attribute?
>
> I can't find any option to the addValue method, I suppose I need
> to:

It should work to just read the JPG photo into a variable, and then use
addValue(), I'm including some code that I believe works.

PerLDAP actually treats all attribute values as binaries, since it can't
tell (yet) if an attribute is supposed to be binary or not. The server
doesn't care about this, and will do the right thing with text only
attributes.

In the next version I'm going to add some more Base64 features, e.g. for
LDIF.pm so that when printing out a binary attribute, it will convert to
Base64.

-- leif

# Do the normal PerLDAP crud to initialize the module, connections etc.
#
open(IMG, "/tmp/img.jpg");
$off = 0;
while ($read = sysread(FOO, $image, 1024, $off)) {
  $off += $read;
}

$entry = $conn->search($ld{root}, $ld{scope}, '(uid=leif)');
while ($entry)
{
  $entry->addValue("jpegphoto", $image);
  $conn->update($entry);
  $entry = $conn->nextEntry();
}
Status: NEW → ASSIGNED
Hi Leif,

Here's a patch to the 1.2 branch of the tree for this:

*** Conn.orig.pm	Fri Jun  4 17:26:56 1999
--- Conn.pm	Fri Jun  4 17:29:46 1999
***************
*** 425,431 ****
        foreach $key (@{$entry->{"_oc_order_"}})
  	{
  	  next if (($key eq "dn") || ($key =~ /^_.+_$/));
! 	  $ent{$key} = $entry->{$key};
  	  $gotcha++;
  	  $entry->attrClean($key);
  	}
--- 425,431 ----
        foreach $key (@{$entry->{"_oc_order_"}})
  	{
  	  next if (($key eq "dn") || ($key =~ /^_.+_$/));
! 	  $ent{$key} = {'ab' => $entry->{$key}};
  	  $gotcha++;
  	  $entry->attrClean($key);
  	}


I haven't tested this yet (sorry).  The reason you have to specify 'ab' is
because in API.xs, parse1mod() does not set ldap_current_mod->mod_op =
LDAP_MOD_BVALUES when you pass in a reference to an array (for an add
operation).  It sets mod_op = 0, which does not perform a binary add.

Note that parse1mod() does correctly set mod_op = LDAP_MOD_BVALUE when you pass
in a reference to a hash with the 'ab' set, which is why it worked for Carlos.

The other alternative to this patch would be to modify API.xs, but this might
cause unexpected behaviour to people calling ldap_add_s directly.

-Kevin McCarthy
I emailed the patch to Carlos and asked him to test it.  Here's his reply:

Hi!

Sorry, but I just didn't make it yesterday.

I have tried the patch today, and it seems to work! Yeahhh :-)


Thanks!
keep up the good work

Best Regards
Carlos de Sousa
Kevin McCarthy writes:

n the $conn->add you are simply passing [@values], as opposed to {'ab' => [
@values ]}.  I believe this was because
the ldap_add_s documentation says:

     NOTE: If you are using the structure to add a new entry, you can specify 0
for the mod_op field (unless you are
     adding binary values and need to specify LDAP_MOD_BVALUES). See "Adding a
New Entry" for details.

If you look inside API.xs, ldap_add_s() calls hash2mod() which calls
parse1mod()   [with the ldap_add_func
parameter == 1].  In that code, it behaves differently if you pass in   [
@values ] versus  { 'ab' => [@values] }.  The first
simply sets ldap_current_mod->mod_op =0.  The second sets
ldap_current_mod->mod_op = 0 and then does a
ldap_current_mod->mod_op |= LDAP_MOD_BVALUES.

So basically your current code is NOT adding the values as binary values.  The
simple solution is to modify
$conn->add() to pass in {'ab' => [ @values]}.  Another solution would be to
change API.xs to set mod_op =
LDAP_MOD_BVALUES whenever ldap_add_func == 1.  I don't know which one you would
prefer.
The patch from Kevin seems to work. I've made a little more changes, the patch
is now:

Index: Conn.pm
===================================================================
RCS file: /cvsroot/mozilla/directory/perldap/Conn.pm,v
retrieving revision 1.22
diff -c -r1.22 Conn.pm
*** Conn.pm     1999/03/30 01:35:42     1.22
--- Conn.pm     1999/06/22 21:26:17
***************
*** 425,441 ****
        foreach $key (@{$entry->{"_oc_order_"}})
        {
          next if (($key eq "dn") || ($key =~ /^_.+_$/));
!         $ent{$key} = $entry->{$key};
          $gotcha++;
          $entry->attrClean($key);
        }
      }
!   elsif  ($ref eq "HASH")
      {
        foreach $key (keys(%{$entry}))
        {
          next if (($key eq "dn") || ($key =~ /^_.+_$/));
!         $ent{$key} = $entry->{$key};
          $gotcha++;
        }
      }
--- 425,441 ----
        foreach $key (@{$entry->{"_oc_order_"}})
        {
          next if (($key eq "dn") || ($key =~ /^_.+_$/));
!         $ent{$key} = { "ab" => $entry->{$key} };
          $gotcha++;
          $entry->attrClean($key);
        }
      }
!   elsif ($ref eq "HASH")
      {
        foreach $key (keys(%{$entry}))
        {
          next if (($key eq "dn") || ($key =~ /^_.+_$/));
!         $ent{$key} = { "ab" => $entry->{$key} };
          $gotcha++;
        }
      }
*** Bug 1332 has been marked as a duplicate of this bug. ***
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Fixed.
You need to log in before you can comment on or make changes to this bug.