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.Bind(gobottin.handleBind)
|
||||||
routes.Search(gobottin.handleSearch)
|
routes.Search(gobottin.handleSearch)
|
||||||
routes.Add(gobottin.handleAdd)
|
routes.Add(gobottin.handleAdd)
|
||||||
|
routes.Compare(gobottin.handleCompare)
|
||||||
|
routes.Delete(gobottin.handleDelete)
|
||||||
ldapserver.Handle(routes)
|
ldapserver.Handle(routes)
|
||||||
|
|
||||||
// listen on 10389
|
// listen on 10389
|
||||||
|
@ -556,3 +558,131 @@ func (server *Server) handleAddInternal(state *State, r *message.AddRequest) (in
|
||||||
|
|
||||||
return ldap.LDAPResultSuccess, nil
|
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