* Synchronize SSH keys on login with LDAP * BUG: Fix hang on sqlite during LDAP key deletiontags/v1.7.0-dev
@@ -393,7 +393,13 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR | |||||
return nil, ErrUserNotExist{0, login, 0} | return nil, ErrUserNotExist{0, login, 0} | ||||
} | } | ||||
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0 | |||||
if !autoRegister { | if !autoRegister { | ||||
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) { | |||||
RewriteAllPublicKeys() | |||||
} | |||||
return user, nil | return user, nil | ||||
} | } | ||||
@@ -421,7 +427,14 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR | |||||
IsActive: true, | IsActive: true, | ||||
IsAdmin: sr.IsAdmin, | IsAdmin: sr.IsAdmin, | ||||
} | } | ||||
return user, CreateUser(user) | |||||
err := CreateUser(user) | |||||
if err == nil && isAttributeSSHPublicKeySet && addLdapSSHPublicKeys(user, source, sr.SSHPublicKey) { | |||||
RewriteAllPublicKeys() | |||||
} | |||||
return user, err | |||||
} | } | ||||
// _________ __________________________ | // _________ __________________________ | ||||
@@ -451,11 +451,9 @@ func GetPublicKeyByID(keyID int64) (*PublicKey, error) { | |||||
return key, nil | return key, nil | ||||
} | } | ||||
// SearchPublicKeyByContent searches content as prefix (leak e-mail part) | |||||
// and returns public key found. | |||||
func SearchPublicKeyByContent(content string) (*PublicKey, error) { | |||||
func searchPublicKeyByContentWithEngine(e Engine, content string) (*PublicKey, error) { | |||||
key := new(PublicKey) | key := new(PublicKey) | ||||
has, err := x. | |||||
has, err := e. | |||||
Where("content like ?", content+"%"). | Where("content like ?", content+"%"). | ||||
Get(key) | Get(key) | ||||
if err != nil { | if err != nil { | ||||
@@ -466,6 +464,12 @@ func SearchPublicKeyByContent(content string) (*PublicKey, error) { | |||||
return key, nil | return key, nil | ||||
} | } | ||||
// SearchPublicKeyByContent searches content as prefix (leak e-mail part) | |||||
// and returns public key found. | |||||
func SearchPublicKeyByContent(content string) (*PublicKey, error) { | |||||
return searchPublicKeyByContentWithEngine(x, content) | |||||
} | |||||
// SearchPublicKey returns a list of public keys matching the provided arguments. | // SearchPublicKey returns a list of public keys matching the provided arguments. | ||||
func SearchPublicKey(uid int64, fingerprint string) ([]*PublicKey, error) { | func SearchPublicKey(uid int64, fingerprint string) ([]*PublicKey, error) { | ||||
keys := make([]*PublicKey, 0, 5) | keys := make([]*PublicKey, 0, 5) | ||||
@@ -1402,7 +1402,7 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) { | |||||
// Delete keys marked for deletion | // Delete keys marked for deletion | ||||
var sshKeysNeedUpdate bool | var sshKeysNeedUpdate bool | ||||
for _, KeyToDelete := range keys { | for _, KeyToDelete := range keys { | ||||
key, err := SearchPublicKeyByContent(KeyToDelete) | |||||
key, err := searchPublicKeyByContentWithEngine(sess, KeyToDelete) | |||||
if err != nil { | if err != nil { | ||||
log.Error(4, "SearchPublicKeyByContent: %v", err) | log.Error(4, "SearchPublicKeyByContent: %v", err) | ||||
continue | continue | ||||
@@ -1421,7 +1421,8 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) { | |||||
return sshKeysNeedUpdate, nil | return sshKeysNeedUpdate, nil | ||||
} | } | ||||
func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) bool { | |||||
// addLdapSSHPublicKeys add a users public keys. Returns true if there are changes. | |||||
func addLdapSSHPublicKeys(usr *User, s *LoginSource, SSHPublicKeys []string) bool { | |||||
var sshKeysNeedUpdate bool | var sshKeysNeedUpdate bool | ||||
for _, sshKey := range SSHPublicKeys { | for _, sshKey := range SSHPublicKeys { | ||||
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | ||||
@@ -1440,7 +1441,8 @@ func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) boo | |||||
return sshKeysNeedUpdate | return sshKeysNeedUpdate | ||||
} | } | ||||
func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *User) bool { | |||||
// synchronizeLdapSSHPublicKeys updates a users public keys. Returns true if there are changes. | |||||
func synchronizeLdapSSHPublicKeys(usr *User, s *LoginSource, SSHPublicKeys []string) bool { | |||||
var sshKeysNeedUpdate bool | var sshKeysNeedUpdate bool | ||||
log.Trace("synchronizeLdapSSHPublicKeys[%s]: Handling LDAP Public SSH Key synchronization for user %s", s.Name, usr.Name) | log.Trace("synchronizeLdapSSHPublicKeys[%s]: Handling LDAP Public SSH Key synchronization for user %s", s.Name, usr.Name) | ||||
@@ -1479,7 +1481,7 @@ func synchronizeLdapSSHPublicKeys(s *LoginSource, SSHPublicKeys []string, usr *U | |||||
newLdapSSHKeys = append(newLdapSSHKeys, LDAPPublicSSHKey) | newLdapSSHKeys = append(newLdapSSHKeys, LDAPPublicSSHKey) | ||||
} | } | ||||
} | } | ||||
if addLdapSSHPublicKeys(s, usr, newLdapSSHKeys) { | |||||
if addLdapSSHPublicKeys(usr, s, newLdapSSHKeys) { | |||||
sshKeysNeedUpdate = true | sshKeysNeedUpdate = true | ||||
} | } | ||||
@@ -1581,7 +1583,7 @@ func SyncExternalUsers() { | |||||
log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err) | log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err) | ||||
} else if isAttributeSSHPublicKeySet { | } else if isAttributeSSHPublicKeySet { | ||||
log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", s.Name, usr.Name) | log.Trace("SyncExternalUsers[%s]: Adding LDAP Public SSH Keys for user %s", s.Name, usr.Name) | ||||
if addLdapSSHPublicKeys(s, usr, su.SSHPublicKey) { | |||||
if addLdapSSHPublicKeys(usr, s, su.SSHPublicKey) { | |||||
sshKeysNeedUpdate = true | sshKeysNeedUpdate = true | ||||
} | } | ||||
} | } | ||||
@@ -1589,7 +1591,7 @@ func SyncExternalUsers() { | |||||
existingUsers = append(existingUsers, usr.ID) | existingUsers = append(existingUsers, usr.ID) | ||||
// Synchronize SSH Public Key if that attribute is set | // Synchronize SSH Public Key if that attribute is set | ||||
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(s, su.SSHPublicKey, usr) { | |||||
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(usr, s, su.SSHPublicKey) { | |||||
sshKeysNeedUpdate = true | sshKeysNeedUpdate = true | ||||
} | } | ||||
@@ -247,10 +247,10 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul | |||||
return nil | return nil | ||||
} | } | ||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, userFilter, userDN) | |||||
log.Trace("Fetching attributes '%v', '%v', '%v', '%v', '%v' with filter %s and base %s", ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey, userFilter, userDN) | |||||
search := ldap.NewSearchRequest( | search := ldap.NewSearchRequest( | ||||
userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, | userDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, userFilter, | ||||
[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail}, | |||||
[]string{ls.AttributeUsername, ls.AttributeName, ls.AttributeSurname, ls.AttributeMail, ls.AttributeSSHPublicKey}, | |||||
nil) | nil) | ||||
sr, err := l.Search(search) | sr, err := l.Search(search) | ||||
@@ -271,6 +271,7 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul | |||||
firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName) | firstname := sr.Entries[0].GetAttributeValue(ls.AttributeName) | ||||
surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname) | surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname) | ||||
mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail) | mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail) | ||||
sshPublicKey := sr.Entries[0].GetAttributeValues(ls.AttributeSSHPublicKey) | |||||
isAdmin := checkAdmin(l, ls, userDN) | isAdmin := checkAdmin(l, ls, userDN) | ||||
if !directBind && ls.AttributesInBind { | if !directBind && ls.AttributesInBind { | ||||
@@ -282,11 +283,12 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul | |||||
} | } | ||||
return &SearchResult{ | return &SearchResult{ | ||||
Username: username, | |||||
Name: firstname, | |||||
Surname: surname, | |||||
Mail: mail, | |||||
IsAdmin: isAdmin, | |||||
Username: username, | |||||
Name: firstname, | |||||
Surname: surname, | |||||
Mail: mail, | |||||
SSHPublicKey: sshPublicKey, | |||||
IsAdmin: isAdmin, | |||||
} | } | ||||
} | } | ||||