diff --git a/object/ldap.go b/object/ldap.go index 5122dd07..85376c42 100644 --- a/object/ldap.go +++ b/object/ldap.go @@ -33,6 +33,7 @@ type Ldap struct { Filter string `xorm:"varchar(200)" json:"filter"` FilterFields []string `xorm:"varchar(100)" json:"filterFields"` DefaultGroup string `xorm:"varchar(100)" json:"defaultGroup"` + PasswordType string `xorm:"varchar(100)" json:"passwordType"` AutoSync int `json:"autoSync"` LastSync string `xorm:"varchar(100)" json:"lastSync"` @@ -149,7 +150,7 @@ func UpdateLdap(ldap *Ldap) (bool, error) { } affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host", - "port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group").Update(ldap) + "port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync", "default_group", "password_type").Update(ldap) if err != nil { return false, nil } diff --git a/object/ldap_conn.go b/object/ldap_conn.go index f9cf497c..ca19c2d2 100644 --- a/object/ldap_conn.go +++ b/object/ldap_conn.go @@ -15,6 +15,8 @@ package object import ( + "crypto/md5" + "encoding/base64" "errors" "fmt" "strings" @@ -417,7 +419,22 @@ func ResetLdapPassword(user *User, newPassword string, lang string) error { modifyPasswordRequest.Replace("unicodePwd", []string{pwdEncoded}) modifyPasswordRequest.Replace("userAccountControl", []string{"512"}) } else { - pwdEncoded = newPassword + switch ldapServer.PasswordType { + case "SSHA": + pwdEncoded, err = generateSSHA(newPassword) + break + case "MD5": + md5Byte := md5.Sum([]byte(newPassword)) + md5Password := base64.StdEncoding.EncodeToString(md5Byte[:]) + pwdEncoded = "{MD5}" + md5Password + break + case "Plain": + pwdEncoded = newPassword + break + default: + pwdEncoded = newPassword + break + } modifyPasswordRequest.Replace("userPassword", []string{pwdEncoded}) } diff --git a/object/ldap_password_type.go b/object/ldap_password_type.go new file mode 100644 index 00000000..d1bd4c6c --- /dev/null +++ b/object/ldap_password_type.go @@ -0,0 +1,36 @@ +// Copyright 2025 The Casdoor Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package object + +import ( + "crypto/rand" + "crypto/sha1" + "encoding/base64" +) + +func generateSSHA(password string) (string, error) { + salt := make([]byte, 4) + _, err := rand.Read(salt) + if err != nil { + return "", err + } + + combined := append([]byte(password), salt...) + hash := sha1.Sum(combined) + hashWithSalt := append(hash[:], salt...) + encoded := base64.StdEncoding.EncodeToString(hashWithSalt) + + return "{SSHA}" + encoded, nil +} diff --git a/web/src/LdapEditPage.js b/web/src/LdapEditPage.js index df38d3fb..7bd289d0 100644 --- a/web/src/LdapEditPage.js +++ b/web/src/LdapEditPage.js @@ -228,6 +228,21 @@ class LdapEditPage extends React.Component { /> + + + {Setting.getLabel(i18next.t("general:Password type"), i18next.t("general:Password type - Tooltip"))} : + + + + + {Setting.getLabel(i18next.t("ldap:Default group"), i18next.t("ldap:Default group - Tooltip"))} :