mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Merge branch 'develop' of https://github.com/SergioBenitez/gogs into develop
# Conflicts: # modules/bindata/bindata.go
This commit is contained in:
		@@ -817,6 +817,7 @@ auths.port = Port
 | 
				
			|||||||
auths.bind_dn = Bind DN
 | 
					auths.bind_dn = Bind DN
 | 
				
			||||||
auths.bind_password = Bind Password
 | 
					auths.bind_password = Bind Password
 | 
				
			||||||
auths.user_base = User Search Base
 | 
					auths.user_base = User Search Base
 | 
				
			||||||
 | 
					auths.user_dn = User DN
 | 
				
			||||||
auths.attribute_name = First name attribute
 | 
					auths.attribute_name = First name attribute
 | 
				
			||||||
auths.attribute_surname = Surname attribute
 | 
					auths.attribute_surname = Surname attribute
 | 
				
			||||||
auths.attribute_mail = E-mail attribute
 | 
					auths.attribute_mail = E-mail attribute
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										122
									
								
								models/login.go
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								models/login.go
									
									
									
									
									
								
							@@ -27,6 +27,7 @@ const (
 | 
				
			|||||||
	NOTYPE LoginType = iota
 | 
						NOTYPE LoginType = iota
 | 
				
			||||||
	PLAIN
 | 
						PLAIN
 | 
				
			||||||
	LDAP
 | 
						LDAP
 | 
				
			||||||
 | 
						DLDAP
 | 
				
			||||||
	SMTP
 | 
						SMTP
 | 
				
			||||||
	PAM
 | 
						PAM
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -38,9 +39,10 @@ var (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var LoginTypes = map[LoginType]string{
 | 
					var LoginTypes = map[LoginType]string{
 | 
				
			||||||
	LDAP: "LDAP",
 | 
						LDAP:  "LDAP (via BindDN)",
 | 
				
			||||||
	SMTP: "SMTP",
 | 
						DLDAP: "LDAP (simple auth)",
 | 
				
			||||||
	PAM:  "PAM",
 | 
						SMTP:  "SMTP",
 | 
				
			||||||
 | 
						PAM:   "PAM",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ensure structs implemented interface.
 | 
					// Ensure structs implemented interface.
 | 
				
			||||||
@@ -106,6 +108,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
 | 
				
			|||||||
	case "type":
 | 
						case "type":
 | 
				
			||||||
		switch LoginType((*val).(int64)) {
 | 
							switch LoginType((*val).(int64)) {
 | 
				
			||||||
		case LDAP:
 | 
							case LDAP:
 | 
				
			||||||
 | 
								fallthrough
 | 
				
			||||||
 | 
							case DLDAP:
 | 
				
			||||||
			source.Cfg = new(LDAPConfig)
 | 
								source.Cfg = new(LDAPConfig)
 | 
				
			||||||
		case SMTP:
 | 
							case SMTP:
 | 
				
			||||||
			source.Cfg = new(SMTPConfig)
 | 
								source.Cfg = new(SMTPConfig)
 | 
				
			||||||
@@ -171,84 +175,74 @@ func DelLoginSource(source *LoginSource) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// UserSignIn validates user name and password.
 | 
					// UserSignIn validates user name and password.
 | 
				
			||||||
func UserSignIn(uname, passwd string) (*User, error) {
 | 
					func UserSignIn(uname, passwd string) (*User, error) {
 | 
				
			||||||
	u := new(User)
 | 
						var u *User
 | 
				
			||||||
	if strings.Contains(uname, "@") {
 | 
						if strings.Contains(uname, "@") {
 | 
				
			||||||
		u = &User{Email: uname}
 | 
							u = &User{Email: uname}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		u = &User{LowerName: strings.ToLower(uname)}
 | 
							u = &User{LowerName: strings.ToLower(uname)}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	has, err := x.Get(u)
 | 
						userExists, err := x.Get(u)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if u.LoginType == NOTYPE && has {
 | 
						if userExists {
 | 
				
			||||||
		u.LoginType = PLAIN
 | 
							switch u.LoginType {
 | 
				
			||||||
	}
 | 
							case NOTYPE:
 | 
				
			||||||
 | 
								fallthrough
 | 
				
			||||||
	// For plain login, user must exist to reach this line.
 | 
							case PLAIN:
 | 
				
			||||||
	// Now verify password.
 | 
								if u.ValidatePassword(passwd) {
 | 
				
			||||||
	if u.LoginType == PLAIN {
 | 
									return u, nil
 | 
				
			||||||
		if !u.ValidatePassword(passwd) {
 | 
					 | 
				
			||||||
			return nil, ErrUserNotExist{u.Id, u.Name}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return u, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !has {
 | 
					 | 
				
			||||||
		var sources []LoginSource
 | 
					 | 
				
			||||||
		if err = x.UseBool().Find(&sources,
 | 
					 | 
				
			||||||
			&LoginSource{IsActived: true, AllowAutoRegister: true}); err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, source := range sources {
 | 
					 | 
				
			||||||
			if source.Type == LDAP {
 | 
					 | 
				
			||||||
				u, err := LoginUserLdapSource(nil, uname, passwd,
 | 
					 | 
				
			||||||
					source.ID, source.Cfg.(*LDAPConfig), true)
 | 
					 | 
				
			||||||
				if err == nil {
 | 
					 | 
				
			||||||
					return u, nil
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
 | 
					 | 
				
			||||||
			} else if source.Type == SMTP {
 | 
					 | 
				
			||||||
				u, err := LoginUserSMTPSource(nil, uname, passwd,
 | 
					 | 
				
			||||||
					source.ID, source.Cfg.(*SMTPConfig), true)
 | 
					 | 
				
			||||||
				if err == nil {
 | 
					 | 
				
			||||||
					return u, nil
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
 | 
					 | 
				
			||||||
			} else if source.Type == PAM {
 | 
					 | 
				
			||||||
				u, err := LoginUserPAMSource(nil, uname, passwd,
 | 
					 | 
				
			||||||
					source.ID, source.Cfg.(*PAMConfig), true)
 | 
					 | 
				
			||||||
				if err == nil {
 | 
					 | 
				
			||||||
					return u, nil
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				log.Warn("Fail to login(%s) by PAM(%s): %v", uname, source.Name, err)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return nil, ErrUserNotExist{u.Id, u.Name}
 | 
								return nil, ErrUserNotExist{u.Id, u.Name}
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								var source LoginSource
 | 
				
			||||||
 | 
								hasSource, err := x.Id(u.LoginSource).Get(&source)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								} else if !hasSource {
 | 
				
			||||||
 | 
									return nil, ErrLoginSourceNotExist
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return ExternalUserLogin(u, u.LoginName, passwd, &source, false)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var source LoginSource
 | 
						var sources []LoginSource
 | 
				
			||||||
	hasSource, err := x.Id(u.LoginSource).Get(&source)
 | 
						if err = x.UseBool().Find(&sources, &LoginSource{IsActived: true, AllowAutoRegister: true}); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	} else if !hasSource {
 | 
						}
 | 
				
			||||||
		return nil, ErrLoginSourceNotExist
 | 
					
 | 
				
			||||||
	} else if !source.IsActived {
 | 
						for _, source := range sources {
 | 
				
			||||||
 | 
							u, err := ExternalUserLogin(nil, uname, passwd, &source, true)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								return u, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log.Warn("Failed to login '%s' via '%s': %v", uname, source.Name, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, ErrUserNotExist{u.Id, u.Name}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ExternalUserLogin(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) {
 | 
				
			||||||
 | 
						if !source.IsActived {
 | 
				
			||||||
		return nil, ErrLoginSourceNotActived
 | 
							return nil, ErrLoginSourceNotActived
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch u.LoginType {
 | 
						switch source.Type {
 | 
				
			||||||
	case LDAP:
 | 
						case LDAP:
 | 
				
			||||||
		return LoginUserLdapSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*LDAPConfig), false)
 | 
							fallthrough
 | 
				
			||||||
 | 
						case DLDAP:
 | 
				
			||||||
 | 
							return LoginUserLdapSource(u, name, passwd, source, autoRegister)
 | 
				
			||||||
	case SMTP:
 | 
						case SMTP:
 | 
				
			||||||
		return LoginUserSMTPSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*SMTPConfig), false)
 | 
							return LoginUserSMTPSource(u, name, passwd, source.ID, source.Cfg.(*SMTPConfig), autoRegister)
 | 
				
			||||||
	case PAM:
 | 
						case PAM:
 | 
				
			||||||
		return LoginUserPAMSource(u, u.LoginName, passwd, source.ID, source.Cfg.(*PAMConfig), false)
 | 
							return LoginUserPAMSource(u, name, passwd, source.ID, source.Cfg.(*PAMConfig), autoRegister)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil, ErrUnsupportedLoginType
 | 
						return nil, ErrUnsupportedLoginType
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -256,8 +250,10 @@ func UserSignIn(uname, passwd string) (*User, error) {
 | 
				
			|||||||
// Create a local user if success
 | 
					// Create a local user if success
 | 
				
			||||||
// Return the same LoginUserPlain semantic
 | 
					// Return the same LoginUserPlain semantic
 | 
				
			||||||
// FIXME: https://github.com/gogits/gogs/issues/672
 | 
					// FIXME: https://github.com/gogits/gogs/issues/672
 | 
				
			||||||
func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAPConfig, autoRegister bool) (*User, error) {
 | 
					func LoginUserLdapSource(u *User, name, passwd string, source *LoginSource, autoRegister bool) (*User, error) {
 | 
				
			||||||
	fn, sn, mail, admin, logged := cfg.Ldapsource.SearchEntry(name, passwd)
 | 
						cfg := source.Cfg.(*LDAPConfig)
 | 
				
			||||||
 | 
						directBind := (source.Type == DLDAP)
 | 
				
			||||||
 | 
						fn, sn, mail, admin, logged := cfg.Ldapsource.SearchEntry(name, passwd, directBind)
 | 
				
			||||||
	if !logged {
 | 
						if !logged {
 | 
				
			||||||
		// User not in LDAP, do nothing
 | 
							// User not in LDAP, do nothing
 | 
				
			||||||
		return nil, ErrUserNotExist{0, name}
 | 
							return nil, ErrUserNotExist{0, name}
 | 
				
			||||||
@@ -276,8 +272,8 @@ func LoginUserLdapSource(u *User, name, passwd string, sourceId int64, cfg *LDAP
 | 
				
			|||||||
		LowerName:   strings.ToLower(name),
 | 
							LowerName:   strings.ToLower(name),
 | 
				
			||||||
		Name:        name,
 | 
							Name:        name,
 | 
				
			||||||
		FullName:    fn + " " + sn,
 | 
							FullName:    fn + " " + sn,
 | 
				
			||||||
		LoginType:   LDAP,
 | 
							LoginType:   source.Type,
 | 
				
			||||||
		LoginSource: sourceId,
 | 
							LoginSource: source.ID,
 | 
				
			||||||
		LoginName:   name,
 | 
							LoginName:   name,
 | 
				
			||||||
		Passwd:      passwd,
 | 
							Passwd:      passwd,
 | 
				
			||||||
		Email:       mail,
 | 
							Email:       mail,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ type AuthenticationForm struct {
 | 
				
			|||||||
	BindDN            string `form:"bind_dn"`
 | 
						BindDN            string `form:"bind_dn"`
 | 
				
			||||||
	BindPassword      string
 | 
						BindPassword      string
 | 
				
			||||||
	UserBase          string
 | 
						UserBase          string
 | 
				
			||||||
 | 
						UserDN            string `form:"user_dn"`
 | 
				
			||||||
	AttributeName     string
 | 
						AttributeName     string
 | 
				
			||||||
	AttributeSurname  string
 | 
						AttributeSurname  string
 | 
				
			||||||
	AttributeMail     string
 | 
						AttributeMail     string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,61 +4,98 @@ Gogs LDAP Authentication Module
 | 
				
			|||||||
## About
 | 
					## About
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This authentication module attempts to authorize and authenticate a user
 | 
					This authentication module attempts to authorize and authenticate a user
 | 
				
			||||||
against an LDAP server. Like most LDAP authentication systems, this module does
 | 
					against an LDAP server. It provides two methods of authentication: LDAP via
 | 
				
			||||||
this in two steps. First, it queries the LDAP server using a Bind DN and
 | 
					BindDN, and LDAP simple authentication.
 | 
				
			||||||
searches for the user that is attempting to sign in. If the user is found, the
 | 
					
 | 
				
			||||||
module attempts to bind to the server using the user's supplied credentials. If
 | 
					LDAP via BindDN functions like most LDAP authentication systems. First, it
 | 
				
			||||||
this succeeds, the user has been authenticated, and his account information is
 | 
					queries the LDAP server using a Bind DN and searches for the user that is
 | 
				
			||||||
retrieved and passed to the Gogs login infrastructure.
 | 
					attempting to sign in. If the user is found, the module attempts to bind to the
 | 
				
			||||||
 | 
					server using the user's supplied credentials. If this succeeds, the user has
 | 
				
			||||||
 | 
					been authenticated, and his account information is retrieved and passed to the
 | 
				
			||||||
 | 
					Gogs login infrastructure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LDAP simple authentication does not utilize a Bind DN. Instead, it binds
 | 
				
			||||||
 | 
					directly with the LDAP server using the user's supplied credentials. If the bind
 | 
				
			||||||
 | 
					succeeds and no filter rules out the user, the user is authenticated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LDAP via BindDN is recommended for most users. By using a Bind DN, the server
 | 
				
			||||||
 | 
					can perform authorization by restricting which entries the Bind DN account can
 | 
				
			||||||
 | 
					read. Further, using a Bind DN with reduced permissions can reduce security risk
 | 
				
			||||||
 | 
					in the face of application bugs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Usage
 | 
					## Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To use this module, add an LDAP authentication source via the Authentications
 | 
					To use this module, add an LDAP authentication source via the Authentications
 | 
				
			||||||
section in the admin panel. The fields should be set as follows:
 | 
					section in the admin panel. Both the LDAP via BindDN and the simple auth LDAP
 | 
				
			||||||
 | 
					share the following fields:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Authorization Name **(required)**
 | 
					* Authorization Name **(required)**
 | 
				
			||||||
	* A name to assign to the new method of authorization.
 | 
					    * A name to assign to the new method of authorization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Host **(required)**
 | 
					* Host **(required)**
 | 
				
			||||||
	* The address where the LDAP server can be reached.
 | 
					    * The address where the LDAP server can be reached.
 | 
				
			||||||
	* Example: mydomain.com
 | 
					    * Example: mydomain.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Port **(required)**
 | 
					* Port **(required)**
 | 
				
			||||||
	* The port to use when connecting to the server.
 | 
					    * The port to use when connecting to the server.
 | 
				
			||||||
	* Example: 636
 | 
					    * Example: 636
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Enable TLS Encryption (optional)
 | 
					* Enable TLS Encryption (optional)
 | 
				
			||||||
	* Whether to use TLS when connecting to the LDAP server.
 | 
					    * Whether to use TLS when connecting to the LDAP server.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Bind DN (optional)
 | 
					* Admin Filter (optional)
 | 
				
			||||||
	* The DN to bind to the LDAP server with when searching for the user.
 | 
					    * An LDAP filter specifying if a user should be given administrator
 | 
				
			||||||
	This may be left blank to perform an anonymous search.
 | 
					      privileges. If a user accounts passes the filter, the user will be
 | 
				
			||||||
	* Example: cn=Search,dc=mydomain,dc=com
 | 
					      privileged as an administrator.
 | 
				
			||||||
 | 
					    * Example: (objectClass=adminAccount)
 | 
				
			||||||
* Bind Password (optional)
 | 
					 | 
				
			||||||
	* The password for the Bind DN specified above, if any.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* User Search Base **(required)**
 | 
					 | 
				
			||||||
	* The LDAP base at which user accounts will be searched for.
 | 
					 | 
				
			||||||
	* Example: ou=Users,dc=mydomain,dc=com
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* User Filter **(required)**
 | 
					 | 
				
			||||||
	* An LDAP filter declaring how to find the user record that is attempting
 | 
					 | 
				
			||||||
	to authenticate. The '%s' matching parameter will be substituted with
 | 
					 | 
				
			||||||
	the user's username.
 | 
					 | 
				
			||||||
	* Example: (&(objectClass=posixAccount)(uid=%s))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
* First name attribute (optional)
 | 
					* First name attribute (optional)
 | 
				
			||||||
	* The attribute of the user's LDAP record containing the user's first
 | 
					    * The attribute of the user's LDAP record containing the user's first name.
 | 
				
			||||||
	name. This will be used to populate their account information.
 | 
					      This will be used to populate their account information.
 | 
				
			||||||
	* Example: givenName
 | 
					    * Example: givenName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Surname name attribute (optional)
 | 
					* Surname attribute (optional)
 | 
				
			||||||
	* The attribute of the user's LDAP record containing the user's surname
 | 
					    * The attribute of the user's LDAP record containing the user's surname This
 | 
				
			||||||
	This will be used to populate their account information.
 | 
					      will be used to populate their account information.
 | 
				
			||||||
	* Example: sn
 | 
					    * Example: sn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* E-mail attribute **(required)**
 | 
					* E-mail attribute **(required)**
 | 
				
			||||||
	* The attribute of the user's LDAP record containing the user's email
 | 
					    * The attribute of the user's LDAP record containing the user's email
 | 
				
			||||||
	address. This will be used to populate their account information.
 | 
					      address. This will be used to populate their account information.
 | 
				
			||||||
	* Example: mail
 | 
					    * Example: mail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**LDAP via BindDN** adds the following fields:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Bind DN (optional)
 | 
				
			||||||
 | 
					    * The DN to bind to the LDAP server with when searching for the user. This
 | 
				
			||||||
 | 
					      may be left blank to perform an anonymous search.
 | 
				
			||||||
 | 
					    * Example: cn=Search,dc=mydomain,dc=com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Bind Password (optional)
 | 
				
			||||||
 | 
					    * The password for the Bind DN specified above, if any. _Note: The password
 | 
				
			||||||
 | 
					      is stored in plaintext at the server. As such, ensure that your Bind DN
 | 
				
			||||||
 | 
					      has as few privileges as possible._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* User Search Base **(required)**
 | 
				
			||||||
 | 
					    * The LDAP base at which user accounts will be searched for.
 | 
				
			||||||
 | 
					    * Example: ou=Users,dc=mydomain,dc=com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* User Filter **(required)**
 | 
				
			||||||
 | 
					    * An LDAP filter declaring how to find the user record that is attempting to
 | 
				
			||||||
 | 
					      authenticate. The '%s' matching parameter will be substituted with the
 | 
				
			||||||
 | 
					      user's username.
 | 
				
			||||||
 | 
					    * Example: (&(objectClass=posixAccount)(uid=%s))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**LDAP using simple auth** adds the following fields:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* User DN **(required)**
 | 
				
			||||||
 | 
					    * A template to use as the user's DN. The `%s` matching parameter will be
 | 
				
			||||||
 | 
					      substituted with the user's username.
 | 
				
			||||||
 | 
					    * Example: cn=%s,ou=Users,dc=mydomain,dc=com
 | 
				
			||||||
 | 
					    * Example: uid=%s,ou=Users,dc=mydomain,dc=com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* User Filter **(required)**
 | 
				
			||||||
 | 
					    * An LDAP filter declaring when a user should be allowed to log in. The `%s`
 | 
				
			||||||
 | 
					      matching parameter will be substituted with the user's username.
 | 
				
			||||||
 | 
					    * Example: (&(objectClass=posixAccount)(cn=%s))
 | 
				
			||||||
 | 
					    * Example: (&(objectClass=posixAccount)(uid=%s))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ type Ldapsource struct {
 | 
				
			|||||||
	BindDN           string // DN to bind with
 | 
						BindDN           string // DN to bind with
 | 
				
			||||||
	BindPassword     string // Bind DN password
 | 
						BindPassword     string // Bind DN password
 | 
				
			||||||
	UserBase         string // Base search path for users
 | 
						UserBase         string // Base search path for users
 | 
				
			||||||
 | 
						UserDN           string // Template for the DN of the user for simple auth
 | 
				
			||||||
	AttributeName    string // First name attribute
 | 
						AttributeName    string // First name attribute
 | 
				
			||||||
	AttributeSurname string // Surname attribute
 | 
						AttributeSurname string // Surname attribute
 | 
				
			||||||
	AttributeMail    string // E-mail attribute
 | 
						AttributeMail    string // E-mail attribute
 | 
				
			||||||
@@ -78,10 +79,19 @@ func (ls Ldapsource) FindUserDN(name string) (string, bool) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
 | 
					// searchEntry : search an LDAP source if an entry (name, passwd) is valid and in the specific filter
 | 
				
			||||||
func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, bool, bool) {
 | 
					func (ls Ldapsource) SearchEntry(name, passwd string, directBind bool) (string, string, string, bool, bool) {
 | 
				
			||||||
	userDN, found := ls.FindUserDN(name)
 | 
						var userDN string
 | 
				
			||||||
	if !found {
 | 
						if directBind {
 | 
				
			||||||
		return "", "", "", false, false
 | 
							log.Trace("LDAP will bind directly via UserDN template: %s", ls.UserDN)
 | 
				
			||||||
 | 
							userDN = fmt.Sprintf(ls.UserDN, name)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							log.Trace("LDAP will use BindDN.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var found bool
 | 
				
			||||||
 | 
							userDN, found = ls.FindUserDN(name)
 | 
				
			||||||
 | 
							if !found {
 | 
				
			||||||
 | 
								return "", "", "", false, false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	l, err := ldapDial(ls)
 | 
						l, err := ldapDial(ls)
 | 
				
			||||||
@@ -112,7 +122,12 @@ func (ls Ldapsource) SearchEntry(name, passwd string) (string, string, string, b
 | 
				
			|||||||
		log.Error(4, "LDAP Search failed unexpectedly! (%v)", err)
 | 
							log.Error(4, "LDAP Search failed unexpectedly! (%v)", err)
 | 
				
			||||||
		return "", "", "", false, false
 | 
							return "", "", "", false, false
 | 
				
			||||||
	} else if len(sr.Entries) < 1 {
 | 
						} else if len(sr.Entries) < 1 {
 | 
				
			||||||
		log.Error(4, "LDAP Search failed unexpectedly! (0 entries)")
 | 
							if directBind {
 | 
				
			||||||
 | 
								log.Error(4, "User filter inhibited user login.")
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								log.Error(4, "LDAP Search failed unexpectedly! (0 entries)")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return "", "", "", false, false
 | 
							return "", "", "", false, false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -57,10 +57,10 @@ var Gogs = {};
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    $.fn.extend({
 | 
					    $.fn.extend({
 | 
				
			||||||
        toggleHide: function () {
 | 
					        toggleHide: function () {
 | 
				
			||||||
            $(this).addClass("hidden");
 | 
					            $(this).each(function(n, v) { $(v).addClass("hidden"); });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        toggleShow: function () {
 | 
					        toggleShow: function () {
 | 
				
			||||||
            $(this).removeClass("hidden");
 | 
					            $(this).each(function(n, v) { $(v).removeClass("hidden"); });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        toggleAjax: function (successCallback, errorCallback) {
 | 
					        toggleAjax: function (successCallback, errorCallback) {
 | 
				
			||||||
            var url = $(this).data("ajax");
 | 
					            var url = $(this).data("ajax");
 | 
				
			||||||
@@ -775,24 +775,20 @@ function initAdmin() {
 | 
				
			|||||||
        $form.attr('action', $form.data('delete-url'));
 | 
					        $form.attr('action', $form.data('delete-url'));
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create authorization.
 | 
					    // Create authorization. Keep list in sync with models/login.go.
 | 
				
			||||||
 | 
					    var all_auths = ['none', 'plain', 'ldap', 'dldap', 'smtp', 'pam'];
 | 
				
			||||||
    $('#auth-type').on("change", function () {
 | 
					    $('#auth-type').on("change", function () {
 | 
				
			||||||
        var v = $(this).val();
 | 
					        var v = $(this).val();
 | 
				
			||||||
        if (v == 2) {
 | 
					        if (v >= all_auths.length) return;
 | 
				
			||||||
            $('.ldap').toggleShow();
 | 
					
 | 
				
			||||||
            $('.smtp').toggleHide();
 | 
					        // Hide all through their class names.
 | 
				
			||||||
            $('.pam').toggleHide();
 | 
					        $.each(all_auths, function(i, type) {
 | 
				
			||||||
        }
 | 
					          $('.' + type).toggleHide();
 | 
				
			||||||
        if (v == 3) {
 | 
					        });
 | 
				
			||||||
            $('.smtp').toggleShow();
 | 
					
 | 
				
			||||||
            $('.ldap').toggleHide();
 | 
					        // Show the selected one.
 | 
				
			||||||
            $('.pam').toggleHide();
 | 
					        var selected = all_auths[v];
 | 
				
			||||||
        }
 | 
					        $('.' + selected).toggleShow();
 | 
				
			||||||
        if (v == 4) {
 | 
					 | 
				
			||||||
            $('.pam').toggleShow();
 | 
					 | 
				
			||||||
            $('.smtp').toggleHide();
 | 
					 | 
				
			||||||
            $('.ldap').toggleHide();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Delete authorization.
 | 
					    // Delete authorization.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,6 +61,8 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
	var u core.Conversion
 | 
						var u core.Conversion
 | 
				
			||||||
	switch models.LoginType(form.Type) {
 | 
						switch models.LoginType(form.Type) {
 | 
				
			||||||
	case models.LDAP:
 | 
						case models.LDAP:
 | 
				
			||||||
 | 
						  fallthrough
 | 
				
			||||||
 | 
						case models.DLDAP:
 | 
				
			||||||
		u = &models.LDAPConfig{
 | 
							u = &models.LDAPConfig{
 | 
				
			||||||
			Ldapsource: ldap.Ldapsource{
 | 
								Ldapsource: ldap.Ldapsource{
 | 
				
			||||||
				Name:             form.Name,
 | 
									Name:             form.Name,
 | 
				
			||||||
@@ -68,13 +70,14 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
				Port:             form.Port,
 | 
									Port:             form.Port,
 | 
				
			||||||
				UseSSL:           form.UseSSL,
 | 
									UseSSL:           form.UseSSL,
 | 
				
			||||||
				BindDN:           form.BindDN,
 | 
									BindDN:           form.BindDN,
 | 
				
			||||||
 | 
									UserDN:           form.UserDN,
 | 
				
			||||||
				BindPassword:     form.BindPassword,
 | 
									BindPassword:     form.BindPassword,
 | 
				
			||||||
				UserBase:         form.UserBase,
 | 
									UserBase:         form.UserBase,
 | 
				
			||||||
				Filter:           form.Filter,
 | 
					 | 
				
			||||||
				AdminFilter:      form.AdminFilter,
 | 
					 | 
				
			||||||
				AttributeName:    form.AttributeName,
 | 
									AttributeName:    form.AttributeName,
 | 
				
			||||||
				AttributeSurname: form.AttributeSurname,
 | 
									AttributeSurname: form.AttributeSurname,
 | 
				
			||||||
				AttributeMail:    form.AttributeMail,
 | 
									AttributeMail:    form.AttributeMail,
 | 
				
			||||||
 | 
									Filter:           form.Filter,
 | 
				
			||||||
 | 
									AdminFilter:      form.AdminFilter,
 | 
				
			||||||
				Enabled:          true,
 | 
									Enabled:          true,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -149,6 +152,8 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
	var config core.Conversion
 | 
						var config core.Conversion
 | 
				
			||||||
	switch models.LoginType(form.Type) {
 | 
						switch models.LoginType(form.Type) {
 | 
				
			||||||
	case models.LDAP:
 | 
						case models.LDAP:
 | 
				
			||||||
 | 
						  fallthrough
 | 
				
			||||||
 | 
						case models.DLDAP:
 | 
				
			||||||
		config = &models.LDAPConfig{
 | 
							config = &models.LDAPConfig{
 | 
				
			||||||
			Ldapsource: ldap.Ldapsource{
 | 
								Ldapsource: ldap.Ldapsource{
 | 
				
			||||||
				Name:             form.Name,
 | 
									Name:             form.Name,
 | 
				
			||||||
@@ -156,6 +161,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
 | 
				
			|||||||
				Port:             form.Port,
 | 
									Port:             form.Port,
 | 
				
			||||||
				UseSSL:           form.UseSSL,
 | 
									UseSSL:           form.UseSSL,
 | 
				
			||||||
				BindDN:           form.BindDN,
 | 
									BindDN:           form.BindDN,
 | 
				
			||||||
 | 
									UserDN:           form.UserDN,
 | 
				
			||||||
				BindPassword:     form.BindPassword,
 | 
									BindPassword:     form.BindPassword,
 | 
				
			||||||
				UserBase:         form.UserBase,
 | 
									UserBase:         form.UserBase,
 | 
				
			||||||
				AttributeName:    form.AttributeName,
 | 
									AttributeName:    form.AttributeName,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@
 | 
				
			|||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.Source.Name}}" required />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.Source.Name}}" required />
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                {{if eq $type 2}}
 | 
					                                {{if eq $type 2 3}}
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
					                                    <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.Source.LDAP.Host}}" required />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.Source.LDAP.Host}}" required />
 | 
				
			||||||
@@ -43,6 +43,7 @@
 | 
				
			|||||||
                                    <label for="use_ssl">{{.i18n.Tr "admin.auths.enable_tls"}}</label>
 | 
					                                    <label for="use_ssl">{{.i18n.Tr "admin.auths.enable_tls"}}</label>
 | 
				
			||||||
                                    <input name="use_ssl" type="checkbox" {{if .Source.LDAP.UseSSL}}checked{{end}}>
 | 
					                                    <input name="use_ssl" type="checkbox" {{if .Source.LDAP.UseSSL}}checked{{end}}>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{if eq $type 2}}
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    <label for="bind_dn">{{.i18n.Tr "admin.auths.bind_dn"}}</label>
 | 
					                                    <label for="bind_dn">{{.i18n.Tr "admin.auths.bind_dn"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_BindDN}}ipt-error{{end}}" id="bind_dn" name="bind_dn" value="{{.Source.LDAP.BindDN}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_BindDN}}ipt-error{{end}}" id="bind_dn" name="bind_dn" value="{{.Source.LDAP.BindDN}}" />
 | 
				
			||||||
@@ -55,6 +56,13 @@
 | 
				
			|||||||
                                    <label class="req" for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
 | 
					                                    <label class="req" for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_UserBase}}ipt-error{{end}}" id="user_base" name="user_base" value="{{.Source.LDAP.UserBase}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_UserBase}}ipt-error{{end}}" id="user_base" name="user_base" value="{{.Source.LDAP.UserBase}}" />
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{end}}
 | 
				
			||||||
 | 
					                                {{if eq $type 3}}
 | 
				
			||||||
 | 
					                                <div class="field">
 | 
				
			||||||
 | 
					                                    <label class="req" for="user_dn">{{.i18n.Tr "admin.auths.user_dn"}}</label>
 | 
				
			||||||
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_UserDN}}ipt-error{{end}}" id="user_dn" name="user_dn" value="{{.Source.LDAP.UserDN}}" />
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{end}}
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
 | 
					                                    <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.Source.LDAP.Filter}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.Source.LDAP.Filter}}" />
 | 
				
			||||||
@@ -76,7 +84,8 @@
 | 
				
			|||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_mail" name="attribute_mail" value="{{.Source.LDAP.AttributeMail}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_Attributes}}ipt-error{{end}}" id="attribute_mail" name="attribute_mail" value="{{.Source.LDAP.AttributeMail}}" />
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                {{else if eq $type 3}}
 | 
					
 | 
				
			||||||
 | 
					                                {{else if eq $type 4}}
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    <label class="req">{{.i18n.Tr "admin.auths.smtp_auth"}}</label>
 | 
					                                    <label class="req">{{.i18n.Tr "admin.auths.smtp_auth"}}</label>
 | 
				
			||||||
                                    <select name="smtp_auth">
 | 
					                                    <select name="smtp_auth">
 | 
				
			||||||
@@ -96,7 +105,7 @@
 | 
				
			|||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.Source.SMTP.Port}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_SmtpPort}}ipt-error{{end}}" id="smtp_port" name="smtp_port" value="{{.Source.SMTP.Port}}" />
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                {{else if eq $type 4}}
 | 
					                                {{else if eq $type 5}}
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    <label class="req" for="pam_service_name">{{.i18n.Tr "admin.auths.pam_service_name"}}</label>
 | 
					                                    <label class="req" for="pam_service_name">{{.i18n.Tr "admin.auths.pam_service_name"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_PAMServiceName}}ipt-error{{end}}" id="pam_service_name" name="pam_service_name" value="{{.Source.PAM.ServiceName}}" />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_PAMServiceName}}ipt-error{{end}}" id="pam_service_name" name="pam_service_name" value="{{.Source.PAM.ServiceName}}" />
 | 
				
			||||||
@@ -104,7 +113,7 @@
 | 
				
			|||||||
                                {{end}}
 | 
					                                {{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                <div class="field">
 | 
					                                <div class="field">
 | 
				
			||||||
                                    {{if eq $type 3}}
 | 
					                                    {{if eq $type 4}}
 | 
				
			||||||
                                    <label></label>
 | 
					                                    <label></label>
 | 
				
			||||||
                                    <input name="tls" type="checkbox" {{if .Source.SMTP.TLS}}checked{{end}}>
 | 
					                                    <input name="tls" type="checkbox" {{if .Source.SMTP.TLS}}checked{{end}}>
 | 
				
			||||||
                                    <strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
 | 
					                                    <strong>{{.i18n.Tr "admin.auths.enable_tls"}}</strong>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,48 +26,52 @@
 | 
				
			|||||||
                                    <label class="req" for="name">{{.i18n.Tr "admin.auths.auth_name"}}</label>
 | 
					                                    <label class="req" for="name">{{.i18n.Tr "admin.auths.auth_name"}}</label>
 | 
				
			||||||
                                    <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.name}}" required />
 | 
					                                    <input class="ipt ipt-large ipt-radius {{if .Err_AuthName}}ipt-error{{end}}" id="name" name="name" value="{{.name}}" required />
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="ldap">
 | 
					                                <div class="dldap ldap">
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
					                                        <label class="req" for="host">{{.i18n.Tr "admin.auths.host"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.host}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_Host}}ipt-error{{end}}" id="host" name="host" value="{{.host}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label class="req" for="port">{{.i18n.Tr "admin.auths.port"}}</label>
 | 
					                                        <label class="req" for="port">{{.i18n.Tr "admin.auths.port"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_Port}}ipt-error{{end}}" id="port" name="port" value="{{.port}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_Port}}ipt-error{{end}}" id="port" name="port" value="{{.port}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label for="use_ssl">{{.i18n.Tr "admin.auths.enable_tls"}}</label>
 | 
					                                        <label for="use_ssl">{{.i18n.Tr "admin.auths.enable_tls"}}</label>
 | 
				
			||||||
                                        <input name="use_ssl" type="checkbox" {{if .use_ssl}}checked{{end}}>
 | 
					                                        <input name="use_ssl" type="checkbox" {{if .use_ssl}}checked{{end}}>
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="ldap field">
 | 
				
			||||||
                                        <label class="req" for="bind_dn">{{.i18n.Tr "admin.auths.bind_dn"}}</label>
 | 
					                                        <label class="req" for="bind_dn">{{.i18n.Tr "admin.auths.bind_dn"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_BindDN}}ipt-error{{end}}" id="bind_dn" name="bind_dn" value="{{.bind_dn}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_BindDN}}ipt-error{{end}}" id="bind_dn" name="bind_dn" value="{{.bind_dn}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="ldap field">
 | 
				
			||||||
                                        <label class="req" for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
 | 
					                                        <label class="req" for="bind_password">{{.i18n.Tr "admin.auths.bind_password"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_BindPassword}}ipt-error{{end}}" id="bind_password" name="bind_password" type="password" value="{{.bind_password}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_BindPassword}}ipt-error{{end}}" id="bind_password" name="bind_password" type="password" value="{{.bind_password}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="ldap field">
 | 
				
			||||||
                                        <label class="req" for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
 | 
					                                        <label class="req" for="user_base">{{.i18n.Tr "admin.auths.user_base"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_UserBase}}ipt-error{{end}}" id="user_base" name="user_base" value="{{.user_base}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_UserBase}}ipt-error{{end}}" id="user_base" name="user_base" value="{{.user_base}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap field hidden">
 | 
				
			||||||
 | 
					                                        <label class="req" for="user_dn">{{.i18n.Tr "admin.auths.user_dn"}}</label>
 | 
				
			||||||
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_UserDN}}ipt-error{{end}}" id="user_dn" name="user_dn" value="{{.user_dn}}" />
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
 | 
					                                        <label class="req" for="filter">{{.i18n.Tr "admin.auths.filter"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.filter}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_Filter}}ipt-error{{end}}" id="filter" name="filter" value="{{.filter}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label for="filter">{{.i18n.Tr "admin.auths.admin_filter"}}</label>
 | 
					                                        <label for="filter">{{.i18n.Tr "admin.auths.admin_filter"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_AdminFilter}}ipt-error{{end}}" id="admin_filter" name="admin_filter" value="{{.admin_filter}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_AdminFilter}}ipt-error{{end}}" id="admin_filter" name="admin_filter" value="{{.admin_filter}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label for="attribute_name">{{.i18n.Tr "admin.auths.attribute_name"}}</label>
 | 
					                                        <label for="attribute_name">{{.i18n.Tr "admin.auths.attribute_name"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeName}}ipt-error{{end}}" id="attribute_name" name="attribute_name" value="{{.attribute_name}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeName}}ipt-error{{end}}" id="attribute_name" name="attribute_name" value="{{.attribute_name}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label for="attribute_surname">{{.i18n.Tr "admin.auths.attribute_surname"}}</label>
 | 
					                                        <label for="attribute_surname">{{.i18n.Tr "admin.auths.attribute_surname"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeSurname}}ipt-error{{end}}" id="attribute_surname" name="attribute_surname" value="{{.attribute_surname}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeSurname}}ipt-error{{end}}" id="attribute_surname" name="attribute_surname" value="{{.attribute_surname}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
                                    <div class="field">
 | 
					                                    <div class="dldap ldap field">
 | 
				
			||||||
                                        <label class="req" for="attribute_mail">{{.i18n.Tr "admin.auths.attribute_mail"}}</label>
 | 
					                                        <label class="req" for="attribute_mail">{{.i18n.Tr "admin.auths.attribute_mail"}}</label>
 | 
				
			||||||
                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeMail}}ipt-error{{end}}" id="attribute_mail" name="attribute_mail" value="{{.attribute_mail}}" />
 | 
					                                        <input class="ipt ipt-large ipt-radius {{if .Err_AttributeMail}}ipt-error{{end}}" id="attribute_mail" name="attribute_mail" value="{{.attribute_mail}}" />
 | 
				
			||||||
                                    </div>
 | 
					                                    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user