def write
@@logger.debug("stub: write called")
validate
entry = []
@@logger.debug("#write: dup'ing @ldap_data")
ldap_data = Marshal.load(Marshal.dump(@ldap_data))
@@logger.debug("#write: dup finished @ldap_data")
@@logger.debug("#write: expanding subtypes in @ldap_data")
ldap_data.keys.each do |key|
ldap_data[key].each do |value|
if value.class == Hash
suffix, real_value = extract_subtypes(value)
if ldap_data.has_key? key + suffix
ldap_data[key + suffix].push(real_value)
else
ldap_data[key + suffix] = real_value
end
ldap_data[key].delete(value)
end
end
end
@@logger.debug('#write: subtypes expanded for @ldap_data')
@@logger.debug('#write: duping @data')
data = Marshal.load(Marshal.dump(@data))
@@logger.debug('#write: finished duping @data')
@@logger.debug('#write: removing disallowed attributes from @data')
bad_attrs = @data.keys - (@must+@may)
bad_attrs.each do |removeme|
data.delete(removeme)
end
@@logger.debug('#write: finished removing disallowed attributes from @data')
@@logger.debug('#write: expanding subtypes for @data')
data.keys.each do |key|
data[key].each do |value|
if value.class == Hash
suffix, real_value = extract_subtypes(value)
if data.has_key? key + suffix
data[key + suffix].push(real_value)
else
data[key + suffix] = real_value
end
data[key].delete(value)
end
end
end
@@logger.debug('#write: subtypes expanded for @data')
if @exists
action = {}
replaceable = []
@@logger.debug('#write: traversing ldap_data determining replaces and deletes')
ldap_data.each do |pair|
suffix = ''
binary = 0
name, *suffix_a = pair[0].split(/;/)
suffix = ';'+ suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil?
value = data[name+suffix]
value = [] if value.nil?
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
replaceable.push(name+suffix)
if pair[1] != value
if not value.empty?
@@logger.debug("updating attribute of existing entry: #{name+suffix}: #{value.inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, value))
else
@@logger.debug("removing attribute from existing entry: #{name+suffix}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, []))
end
end
end
@@logger.debug('#write: finished traversing ldap_data')
@@logger.debug('#write: traversing data determining adds')
data.each do |pair|
suffix = ''
binary = 0
name, *suffix_a = pair[0].split(/;/)
suffix = ';' + suffix_a.join(';') if suffix_a.size > 0
name = @attr_methods[name]
name = pair[0].split(/;/)[0] if name.nil?
value = pair[1]
value = [] if value.nil?
if not replaceable.member? name+suffix
binary = LDAP::LDAP_MOD_BVALUES if Base.schema.binary? name
@@logger.debug("adding attribute to existing entry: #{name+suffix}: #{value.inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_REPLACE|binary, name + suffix, value)) unless value.empty?
end
end
@@logger.debug('#write: traversing data complete')
Base.connection(WriteError.new(
"Failed to modify: '#{entry}'")) do |conn|
@@logger.debug("#write: modifying #{@dn}")
conn.modify(@dn, entry)
@@logger.debug('#write: modify successful')
end
else
@@logger.debug('#write: adding all attribute value pairs')
@@logger.debug("#write: adding #{@attr_methods[dnattr()].inspect} = #{data[@attr_methods[dnattr()]].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD, @attr_methods[dnattr()],
data[@attr_methods[dnattr()]]))
@@logger.debug("#write: adding objectClass = #{data[@attr_methods['objectClass']].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD, 'objectClass',
data[@attr_methods['objectClass']]))
data.each do |pair|
if pair[1].size > 0 and pair[0] != 'objectClass' and pair[0] != @attr_methods[dnattr()]
if Base.schema.binary? pair[0].split(/;/)[0]
binary = LDAP::LDAP_MOD_BVALUES
else
binary = 0
end
@@logger.debug("adding attribute to new entry: #{pair[0].inspect}: #{pair[1].inspect}")
entry.push(LDAP.mod(LDAP::LDAP_MOD_ADD|binary, pair[0], pair[1]))
end
end
Base.connection(WriteError.new(
"Failed to add: '#{entry}'")) do |conn|
@@logger.debug("#write: adding #{@dn}")
conn.add(@dn, entry)
@@logger.debug("#write: add successful")
@exists = true
end
end
@@logger.debug("#write: resetting @ldap_data to a dup of @data")
@ldap_data = Marshal.load(Marshal.dump(data))
@@logger.debug('#write: removing attributes from @ldap_data not sent in data')
bad_attrs.each do |removeme|
@ldap_data.delete(removeme)
end
@@logger.debug('#write: @ldap_data reset complete')
@@logger.debug('stub: write exitted')
end