forked from Deuxfleurs/bottin
Handle LDAP Compare and Delete requests
This commit is contained in:
parent
3decb94271
commit
f9cb0552be
1 changed files with 130 additions and 0 deletions
130
main.go
130
main.go
|
@ -154,6 +154,8 @@ func main() {
|
|||
routes.Bind(gobottin.handleBind)
|
||||
routes.Search(gobottin.handleSearch)
|
||||
routes.Add(gobottin.handleAdd)
|
||||
routes.Compare(gobottin.handleCompare)
|
||||
routes.Delete(gobottin.handleDelete)
|
||||
ldapserver.Handle(routes)
|
||||
|
||||
// listen on 10389
|
||||
|
@ -556,3 +558,131 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
|||
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
|
||||
func (server *Server) handleCompare(s ldap.UserState, w ldap.ResponseWriter, m *ldap.Message) {
|
||||
state := s.(*State)
|
||||
r := m.GetCompareRequest()
|
||||
|
||||
code, err := server.handleCompareInternal(state, &r)
|
||||
|
||||
res := ldap.NewResponse(code)
|
||||
if err != nil {
|
||||
res.SetDiagnosticMessage(err.Error())
|
||||
}
|
||||
w.Write(message.CompareResponse(res))
|
||||
}
|
||||
|
||||
func (server *Server) handleCompareInternal(state *State, r *message.CompareRequest) (int, error) {
|
||||
dn := string(r.Entry())
|
||||
attr := string(r.Ava().AttributeDesc())
|
||||
expected := string(r.Ava().AssertionValue())
|
||||
|
||||
_, err := server.checkSuffix(dn, false)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultInvalidDNSyntax, err
|
||||
}
|
||||
|
||||
// TODO check user for permissions to read dn
|
||||
|
||||
exists, err := server.objectExists(dn)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
if !exists {
|
||||
return ldap.LDAPResultNoSuchObject, fmt.Errorf("Not found: %s", dn)
|
||||
}
|
||||
|
||||
values, err := server.getAttribute(dn, attr)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
|
||||
for _, v := range values {
|
||||
if v == expected {
|
||||
return ldap.LDAPResultCompareTrue, nil
|
||||
}
|
||||
}
|
||||
|
||||
return ldap.LDAPResultCompareFalse, nil
|
||||
}
|
||||
|
||||
func (server *Server) handleDelete(s ldap.UserState, w ldap.ResponseWriter, m *ldap.Message) {
|
||||
state := s.(*State)
|
||||
r := m.GetDeleteRequest()
|
||||
|
||||
code, err := server.handleDeleteInternal(state, &r)
|
||||
|
||||
res := ldap.NewResponse(code)
|
||||
if err != nil {
|
||||
res.SetDiagnosticMessage(err.Error())
|
||||
}
|
||||
w.Write(message.DelResponse(res))
|
||||
}
|
||||
|
||||
func (server *Server) handleDeleteInternal(state *State, r *message.DelRequest) (int, error) {
|
||||
dn := string(*r)
|
||||
|
||||
_, err := server.checkSuffix(dn, false)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultInvalidDNSyntax, err
|
||||
}
|
||||
|
||||
// TODO check user for permissions to write dn
|
||||
|
||||
// Check that this LDAP entry exists and has no children
|
||||
path := dnToConsul(dn) + "/"
|
||||
items, _, err := server.kv.List(path, nil)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
|
||||
if len(items) == 0 {
|
||||
return ldap.LDAPResultNoSuchObject, fmt.Errorf("Not found: %s", dn)
|
||||
}
|
||||
for _, item := range items {
|
||||
itemDN, _, _ := consulToDN(item)
|
||||
if itemDN != dn {
|
||||
return ldap.LDAPResultNotAllowedOnNonLeaf, fmt.Errorf(
|
||||
"Cannot delete %d as it has children", dn)
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve group membership before we delete everything
|
||||
memberOf, err := server.getAttribute(dn, "memberOf")
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
|
||||
// Delete the LDAP entry
|
||||
_, err = server.kv.DeleteTree(path, nil)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
|
||||
// Delete it from the member list of all the groups it was a member of
|
||||
if memberOf != nil {
|
||||
for _, group := range memberOf {
|
||||
groupMembers , err := server.getAttribute(dn, "member")
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
|
||||
newMembers := []string{}
|
||||
for _, memb := range groupMembers {
|
||||
if memb != dn {
|
||||
newMembers = append(newMembers, memb)
|
||||
}
|
||||
}
|
||||
|
||||
err = server.addElements(group, Entry{
|
||||
"member": newMembers,
|
||||
})
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue