summaryrefslogtreecommitdiff
path: root/src/parabola_hackers/nslcd_backend/db_pam.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/parabola_hackers/nslcd_backend/db_pam.go')
-rw-r--r--src/parabola_hackers/nslcd_backend/db_pam.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/parabola_hackers/nslcd_backend/db_pam.go b/src/parabola_hackers/nslcd_backend/db_pam.go
index 303a66c..3374170 100644
--- a/src/parabola_hackers/nslcd_backend/db_pam.go
+++ b/src/parabola_hackers/nslcd_backend/db_pam.go
@@ -17,17 +17,32 @@
package hackers_nslcd_backend
import (
+ "fmt"
"parabola_hackers"
s "syscall"
"lukeshu.com/git/go/libgnulinux.git/crypt"
p "lukeshu.com/git/go/libnslcd.git/proto"
+ "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger"
)
func checkPassword(password string, hash string) bool {
return crypt.Crypt(password, hash) == hash
}
+func hashPassword(newPassword string, oldHash string) string {
+ salt := oldHash
+ if salt == "!" {
+ str, err := parabola_hackers.RandomString(crypt.SaltAlphabet, 8)
+ if err != nil {
+ logger.Err("Could not generate a random string")
+ str = ""
+ }
+ salt = "$6$" + str + "$"
+ }
+ return crypt.Crypt(newPassword, salt)
+}
+
func (o *Hackers) PAM_Authentication(cred s.Ucred, req p.Request_PAM_Authentication) <-chan p.PAM_Authentication {
o.lock.RLock()
ret := make(chan p.PAM_Authentication)
@@ -97,3 +112,56 @@ func (o *Hackers) PAM_SessionClose(cred s.Ucred, req p.Request_PAM_SessionClose)
go close(ret)
return ret
}
+
+func (o *Hackers) PAM_PwMod(cred s.Ucred, req p.Request_PAM_PwMod) <-chan p.PAM_PwMod {
+ ret := make(chan p.PAM_PwMod)
+ o.lock.Lock()
+ go func() {
+ defer close(ret)
+ defer o.lock.Unlock()
+
+ uid := o.name2uid(req.UserName)
+ if uid < 0 {
+ return
+ }
+ user := o.users[uid]
+
+ // Check the OldPassword
+ if req.AsRoot == 1 {
+ if !checkPassword(req.OldPassword, user.Passwd.PwHash) {
+ ret <- p.PAM_PwMod{
+ Result: p.NSLCD_PAM_PERM_DENIED,
+ Error: fmt.Sprintf("password change failed: %s", "Old password did not match"),
+ }
+ return
+ }
+ }
+
+ // Update the PwHash in memory
+ user.Passwd.PwHash = hashPassword(req.NewPassword, user.Passwd.PwHash)
+ if user.Passwd.PwHash == "" {
+ logger.Err("Password hashing failed")
+ return
+ }
+
+ // Update the PwHash on disk
+ passwords := make(map[string]string, len(o.users))
+ for _, ouser := range o.users {
+ passwords[ouser.Passwd.Name] = ouser.Passwd.PwHash
+ }
+ passwords[user.Passwd.Name] = user.Passwd.PwHash
+ err := parabola_hackers.SaveAllPasswords(passwords)
+ if err != nil {
+ logger.Err("Writing passwords to disk: %v", err)
+ return
+ }
+
+ // Ok, we're done, commit the changes
+ o.users[uid] = user
+ ret <- p.PAM_PwMod{
+ Result: p.NSLCD_PAM_SUCCESS,
+ Error: "",
+ }
+ }()
+ return ret
+}