package ldapmdl import ( "crypto/tls" "errors" "strings" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/configmdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl" ldap "gopkg.in/ldap.v2" ) /* Author : RahulS LDAP authentication module - Authenticates the user with given LDAP server Requires : loginID (string), password (string) Returns : 0 - If any error occurs, error - respective error object. Will occur if in following conditions a. Blank loginID b. Blank password c. Error connecting to LDAP server d. Error reconnecting to LDAP using TSL e. Error binding admin username and password with LDAP f. Error searhin user on LDAP server 1 - If user does not exist on LDAP server, error - nil 2 - If multiple entries found against loginID, error - nil 3 - If user enters wrong password, error - nil 4 - Successful authentication, error - nil */ //LDAPConfig to get read and store LDAP server configuration type LDAPConfig struct { BaseDN string LDAPServerIPWithPort string FilterDN string LDAPUsername string LDAPPassword string } var ldapConfig LDAPConfig //InitLDAP get LDAP server configuration func InitLDAP(configFilePath string) error { _, configError := configmdl.InitConfig(configFilePath, &ldapConfig) if errormdl.CheckErr(configError) != nil { return configError } return nil } //AuthenticateOnLDAP authenticates user with LDAP server func AuthenticateOnLDAP(loginID, password string) (int, error) { if strings.TrimSpace(loginID) == "" { loggermdl.LogError("ldapmdl : loginID required") return 0, errors.New("ldapmdl : loginID required") } else if strings.TrimSpace(password) == "" { loggermdl.LogError("ldapmdl : password required") return 0, errors.New("ldapmdl : password required") } //Check if LDAP configuration is properly set through config file. (Call InitLDAP() to set configuration) ldapInitConfigError := CheckLDAPConfig() if ldapInitConfigError != nil { return 0, ldapInitConfigError } //Create connection to LDAP server ldapConnection, ldapConnectionError := ldap.Dial("tcp", ldapConfig.LDAPServerIPWithPort) if errormdl.CheckErr(ldapConnectionError) != nil { loggermdl.LogError("ldapmdl connectionError : ", ldapConnectionError) return 0, ldapConnectionError } defer ldapConnection.Close() //Reconnect with TLS(Transport Layer Security Protocol) startTLSError := ldapConnection.StartTLS(&tls.Config{InsecureSkipVerify: true}) if errormdl.CheckErr1(startTLSError) != nil { loggermdl.LogError("ldapmdl startTLSError : ", startTLSError) return 0, startTLSError } //Bind with administrator user who has credentials to operation like 'search' ldapBindError := ldapConnection.Bind(ldapConfig.LDAPUsername, ldapConfig.LDAPPassword) if errormdl.CheckErr2(ldapBindError) != nil { loggermdl.LogInfo("ldapmdl ldapBindError: ", ldapBindError) return 0, ldapBindError } //Search for required username which is to be authenticated result, searchError := ldapConnection.Search(ldap.NewSearchRequest( ldapConfig.BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, filter(loginID, ldapConfig.FilterDN), []string{"dn"}, nil, )) //Hand search error if errormdl.CheckErr3(searchError) != nil { loggermdl.LogError("ldapmdl searchError : ", searchError) return 0, searchError } //Return 1 if user does not exist on LDAP server if len(result.Entries) < 1 { return 1, nil } //Return 2 if multiple entries found against one userId if errormdl.CheckBool(len(result.Entries) > 1) { return 2, nil } //Bind the password with given userId if errors occurs while binding, user has entered wrong password if userCredentialsBindError := ldapConnection.Bind(result.Entries[0].DN, password); userCredentialsBindError != nil { return 3, nil } //return 4 if authentication is successful loggermdl.LogDebug("ldapmdl : Authentication successful") return 4, nil } func filter(needle string, filterDN string) string { res := strings.Replace(filterDN, "{username}", needle, -1) return res } //CheckLDAPConfig checks of LDAP configuration is initialized or not func CheckLDAPConfig() error { if strings.TrimSpace(ldapConfig.BaseDN) == "" { return errors.New("LDAP baseDN not found") } else if strings.TrimSpace(ldapConfig.FilterDN) == "" { return errors.New("LDAP filterDN not found") } else if strings.TrimSpace(ldapConfig.LDAPPassword) == "" { return errors.New("LDAP password not found") } else if strings.TrimSpace(ldapConfig.LDAPServerIPWithPort) == "" { return errors.New("LDAP IPAddress not found IPAdress should be with port") } else if strings.TrimSpace(ldapConfig.LDAPUsername) == "" { return errors.New("LDAP username not found") } return nil }