* 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} | |||
} | |||
var isAttributeSSHPublicKeySet = len(strings.TrimSpace(source.LDAP().AttributeSSHPublicKey)) > 0 | |||
if !autoRegister { | |||
if isAttributeSSHPublicKeySet && synchronizeLdapSSHPublicKeys(user, source, sr.SSHPublicKey) { | |||
RewriteAllPublicKeys() | |||
} | |||
return user, nil | |||
} | |||
@@ -421,7 +427,14 @@ func LoginViaLDAP(user *User, login, password string, source *LoginSource, autoR | |||
IsActive: true, | |||
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 | |||
} | |||
// 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) | |||
has, err := x. | |||
has, err := e. | |||
Where("content like ?", content+"%"). | |||
Get(key) | |||
if err != nil { | |||
@@ -466,6 +464,12 @@ func SearchPublicKeyByContent(content string) (*PublicKey, error) { | |||
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. | |||
func SearchPublicKey(uid int64, fingerprint string) ([]*PublicKey, error) { | |||
keys := make([]*PublicKey, 0, 5) | |||
@@ -1402,7 +1402,7 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) { | |||
// Delete keys marked for deletion | |||
var sshKeysNeedUpdate bool | |||
for _, KeyToDelete := range keys { | |||
key, err := SearchPublicKeyByContent(KeyToDelete) | |||
key, err := searchPublicKeyByContentWithEngine(sess, KeyToDelete) | |||
if err != nil { | |||
log.Error(4, "SearchPublicKeyByContent: %v", err) | |||
continue | |||
@@ -1421,7 +1421,8 @@ func deleteKeysMarkedForDeletion(keys []string) (bool, error) { | |||
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 | |||
for _, sshKey := range SSHPublicKeys { | |||
_, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshKey)) | |||
@@ -1440,7 +1441,8 @@ func addLdapSSHPublicKeys(s *LoginSource, usr *User, SSHPublicKeys []string) boo | |||
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 | |||
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) | |||
} | |||
} | |||
if addLdapSSHPublicKeys(s, usr, newLdapSSHKeys) { | |||
if addLdapSSHPublicKeys(usr, s, newLdapSSHKeys) { | |||
sshKeysNeedUpdate = true | |||
} | |||
@@ -1581,7 +1583,7 @@ func SyncExternalUsers() { | |||
log.Error(4, "SyncExternalUsers[%s]: Error creating user %s: %v", s.Name, su.Username, err) | |||
} else if isAttributeSSHPublicKeySet { | |||
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 | |||
} | |||
} | |||
@@ -1589,7 +1591,7 @@ func SyncExternalUsers() { | |||
existingUsers = append(existingUsers, usr.ID) | |||
// 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 | |||
} | |||
@@ -247,10 +247,10 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul | |||
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( | |||
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) | |||
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) | |||
surname := sr.Entries[0].GetAttributeValue(ls.AttributeSurname) | |||
mail := sr.Entries[0].GetAttributeValue(ls.AttributeMail) | |||
sshPublicKey := sr.Entries[0].GetAttributeValues(ls.AttributeSSHPublicKey) | |||
isAdmin := checkAdmin(l, ls, userDN) | |||
if !directBind && ls.AttributesInBind { | |||
@@ -282,11 +283,12 @@ func (ls *Source) SearchEntry(name, passwd string, directBind bool) *SearchResul | |||
} | |||
return &SearchResult{ | |||
Username: username, | |||
Name: firstname, | |||
Surname: surname, | |||
Mail: mail, | |||
IsAdmin: isAdmin, | |||
Username: username, | |||
Name: firstname, | |||
Surname: surname, | |||
Mail: mail, | |||
SSHPublicKey: sshPublicKey, | |||
IsAdmin: isAdmin, | |||
} | |||
} | |||