aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/main.go b/main.go
index 2e4122d..d73ada4 100644
--- a/main.go
+++ b/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
+}
+