modify objectclass - Object class violation/Operations error

Summary: Is there anyway that someone has figured out how to adding/removing objectclasses to already existing entries using net-ldap 0.1.1?

Detail: I am adding and deleting all sorts of ldap entries just fine. I can even make new entries with objectclasses, but when I want to remove an existing one or add another one I get 'object class violation' or 'operations error'. I understand how objectclass and schema rules apply. So if i tried to add just the objectclass w/o its required attributes then i would get 'object class violation'. I can remove/add objectclasses with softerra ldap administrator just fine. I say this to prove out my ldap server is functioning fine. Softerra has a special menu option for adding/removing objectclasses to existing entries. This menu removes the dependency attributes associated with the objectclasses as required per the schema.

The entry log from the ldap server when using softerra to remove posixAccount and shadowaccount objectclasses from already existing entries. AuditV3--2010-09-02-18:36:52.865+00:00DST--V3 SSL Modify--bindDN: cn=root--client: x.x.x.x:22795--connectionID: 1943--received: 2010-09-02-18:36:52.470+00:00DST--Success operationResponseTime: 395 timeOnWorkQ: 0 rdbmLockWaitTime: 1 clientIOTime: 0 object: cn=myname,ou=int,O=stuff delete: gidNumber delete: homeDirectory delete: loginShell delete: shadowFlag delete: uidNumber delete: userid replace: objectClass

The entry log from the ldap server when trying using net-ldap: AuditV3--2010-09-02-18:02:34.520+00:00DST--V3 Modify--bindDN: cn=root--client: x.x.x.x:65284--connectionID: 1935--received: 2010-09-02-18:02:34.516+00:00DST--Object class violation operationResponseTime: 4 timeOnWorkQ: 0 rdbmLockWaitTime: 0 clientIOTime: 0 object: cn=myname,ou=int,o=stuff delete: userid delete: gidnumber delete: uidnumber delete: loginshell delete: homedirectory delete: objectclass

I notice they are using a replace action. I looked at the net-ldap replace api but it doesn't support this type of call. http://net-ldap.rubyforge.org/ I tried ldap.mod with ops array with even just the objectclasses listed. no luck. ldap.delete_attibute won't work for objectclasses.. ldap.replace_attribute won't work for objectclasses..

Tried the ldap.add with the attr array for adding new objectclasses to no avail. tried ldap.add_attribute for objectclass to no avail. would just give 'objectclass violation' which is correct because you need to add the objectclasses and the entries..tried ldap.replace_attribute for objectclass to no avail.

Here is the way it needs to be done but doesn't work.     dn = "cn=myname,ou=int,o=stuff"

    ops = [       [:add, :objectclass, ["posixAccount", "shadowAccount"]],       [:add, :homedirectory, "/home/myname"],       [:add, :loginshell, "/bin/bash"],       [:add, :uidnumber, "1234"],       [:add, :gidnumber, "1234],       [:add, :userid, "myname"]     ]

    ldap=self.connection.. <<-- just gets me a valid connection to ldap setup. it works just fine..     ldap.modify( :dn => dn, :attributes => ops ) This will yield "operations error" AuditV3--2010-09-03-15:00:44.165+00:00DST--V3 Modify--bindDN: cn=root--client: x.x.x.x:22544--connectionID: 4884--received: 2010-09-03-15:00:44.165+00:00DST--Operations error operationResponseTime: 0 timeOnWorkQ: 0 rdbmLockWaitTime: 0 clientIOTime: 0

Remember it needs to be a modify because the entry already exists and I'm dealing with objectclasses.

I can do it using ruby/ldap which is my only work around currently. I have left a note with the net-ldap devs but that rubyforge land seems scarce.. require 'rubygems' require 'ldap'

$HOST = 'servername' $PORT = LDAP::LDAP_PORT $SSLPORT = LDAP::LDAPS_PORT

conn = LDAP::Conn.new($HOST, $PORT) conn.bind('cn=root','xxxxxxx')

conn.perror("bind") entry1 = [   LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['posixAccount','shadowAccount']),   LDAP.mod(LDAP::LDAP_MOD_ADD,'homedirectory',['/home/myname']),   LDAP.mod(LDAP::LDAP_MOD_ADD,'loginshell',['/bin/bash']),   LDAP.mod(LDAP::LDAP_MOD_ADD,'uidnumber',['1234']),   LDAP.mod(LDAP::LDAP_MOD_ADD,'gidnumber',['1234']),   LDAP.mod(LDAP::LDAP_MOD_ADD,'userid',['myname']), ]

begin   conn.modify("cn=mystuff,ou=int,o=stuff", entry1) rescue LDAP::ResultError   conn.perror("add")   exit end conn.perror("add") conn.unbind

Unfortunately my dev env for this project is windoze so I have to try to get the ruby/ldap 0.1.1 gem compiled. I did the above on the linux server directly.