func GetUserForLogin(loginId string, onlyLdap bool) (*model.User, *model.AppError) { ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil && utils.IsLicensed && *utils.License.Features.LDAP if result := <-Srv.Store.User().GetForLogin( loginId, *utils.Cfg.EmailSettings.EnableSignInWithUsername && !onlyLdap, *utils.Cfg.EmailSettings.EnableSignInWithEmail && !onlyLdap, ldapAvailable, ); result.Err != nil && result.Err.Id == "store.sql_user.get_for_login.multiple_users" { // don't fall back to LDAP in this case since we already know there's an LDAP user, but that it shouldn't work result.Err.StatusCode = http.StatusBadRequest return nil, result.Err } else if result.Err != nil { if !ldapAvailable { // failed to find user and no LDAP server to fall back on result.Err.StatusCode = http.StatusBadRequest return nil, result.Err } // fall back to LDAP server to see if we can find a user if ldapUser, ldapErr := einterfaces.GetLdapInterface().GetUser(loginId); ldapErr != nil { ldapErr.StatusCode = http.StatusBadRequest return nil, ldapErr } else { return ldapUser, nil } } else { return result.Data.(*model.User), nil } }
func checkLdapUserPasswordAndAllCriteria(ldapId *string, password string, mfaToken string) (*model.User, *model.AppError) { ldapInterface := einterfaces.GetLdapInterface() if ldapInterface == nil || ldapId == nil { err := model.NewLocAppError("doLdapAuthentication", "api.user.login_ldap.not_available.app_error", nil, "") err.StatusCode = http.StatusNotImplemented return nil, err } var user *model.User if ldapUser, err := ldapInterface.DoLogin(*ldapId, password); err != nil { err.StatusCode = http.StatusUnauthorized return nil, err } else { user = ldapUser } if err := checkUserAdditionalAuthenticationCriteria(user, mfaToken); err != nil { err.StatusCode = http.StatusUnauthorized return user, err } // user successfully authenticated return user, nil }
func authenticateUser(user *model.User, password, mfaToken string) (*model.User, *model.AppError) { ldapAvailable := *utils.Cfg.LdapSettings.Enable && einterfaces.GetLdapInterface() != nil if user.AuthService == model.USER_AUTH_SERVICE_LDAP { if !ldapAvailable { err := model.NewLocAppError("login", "api.user.login_ldap.not_available.app_error", nil, "") err.StatusCode = http.StatusNotImplemented return user, err } else if ldapUser, err := checkLdapUserPasswordAndAllCriteria(user.AuthData, password, mfaToken); err != nil { err.StatusCode = http.StatusUnauthorized return user, err } else { // slightly redundant to get the user again, but we need to get it from the LDAP server return ldapUser, nil } } else if user.AuthService != "" { err := model.NewLocAppError("login", "api.user.login.use_auth_service.app_error", map[string]interface{}{"AuthService": user.AuthService}, "") err.StatusCode = http.StatusBadRequest return user, err } else { if err := checkPasswordAndAllCriteria(user, password, mfaToken); err != nil { err.StatusCode = http.StatusUnauthorized return user, err } else { return user, nil } } }
// LoadConfig will try to search around for the corresponding config file. // It will search /tmp/fileName then attempt ./config/fileName, // then ../config/fileName and last it will look at fileName func LoadConfig(fileName string) { fileName = FindConfigFile(fileName) file, err := os.Open(fileName) if err != nil { panic(T("utils.config.load_config.opening.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } decoder := json.NewDecoder(file) config := model.Config{} err = decoder.Decode(&config) if err != nil { panic(T("utils.config.load_config.decoding.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } if info, err := file.Stat(); err != nil { panic(T("utils.config.load_config.getting.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } else { CfgLastModified = info.ModTime().Unix() CfgFileName = fileName } config.SetDefaults() if err := config.IsValid(); err != nil { panic(err.Error()) } if err := ValidateLdapFilter(&config); err != nil { panic(err.Error()) } configureLog(&config.LogSettings) if config.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL { dir := config.FileSettings.Directory if len(dir) > 0 && dir[len(dir)-1:] != "/" { config.FileSettings.Directory += "/" } } Cfg = &config ClientCfg = getClientConfig(Cfg) // Actions that need to run every time the config is loaded if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { // This restarts the job if nessisary (works for config reloads) ldapI.StartLdapSyncJob() } if samlI := einterfaces.GetSamlInterface(); samlI != nil { samlI.ConfigureSP() } }
func ValidateLdapFilter(cfg *model.Config) *model.AppError { ldapInterface := einterfaces.GetLdapInterface() if *cfg.LdapSettings.Enable && ldapInterface != nil && *cfg.LdapSettings.UserFilter != "" { if err := ldapInterface.ValidateFilter(*cfg.LdapSettings.UserFilter); err != nil { return err } } return nil }
func ldapSyncCmdF(cmd *cobra.Command, args []string) error { if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { if err := ldapI.Syncronize(); err != nil { CommandPrintErrorln("ERROR: AD/LDAP Synchronization Failed") } else { CommandPrettyPrintln("SUCCESS: AD/LDAP Synchronization Complete") } } return nil }
func cmdRunLdapSync() { if flagCmdRunLdapSync { if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { if err := ldapI.Syncronize(); err != nil { fmt.Println("ERROR: AD/LDAP Syncronization Failed") l4g.Error("%v", err.Error()) flushLogAndExit(1) } else { fmt.Println("SUCCESS: AD/LDAP Syncronization Complete") flushLogAndExit(0) } } } }
func ldapSyncNow(c *Context, w http.ResponseWriter, r *http.Request) { go func() { if utils.IsLicensed && *utils.License.Features.LDAP && *utils.Cfg.LdapSettings.Enable { if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { ldapI.SyncNow() } else { l4g.Error("%v", model.NewLocAppError("ldapSyncNow", "ent.ldap.disabled.app_error", nil, "").Error()) } } }() rdata := map[string]string{} rdata["status"] = "ok" w.Write([]byte(model.MapToJson(rdata))) }
func ldapTest(c *Context, w http.ResponseWriter, r *http.Request) { if ldapI := einterfaces.GetLdapInterface(); ldapI != nil && utils.IsLicensed && *utils.License.Features.LDAP && *utils.Cfg.LdapSettings.Enable { if err := ldapI.RunTest(); err != nil { c.Err = err c.Err.StatusCode = 500 } } else { c.Err = model.NewLocAppError("ldapTest", "ent.ldap.disabled.app_error", nil, "") c.Err.StatusCode = http.StatusNotImplemented } if c.Err == nil { rdata := map[string]string{} rdata["status"] = "ok" w.Write([]byte(model.MapToJson(rdata))) } }
// LoadConfig will try to search around for the corresponding config file. // It will search /tmp/fileName then attempt ./config/fileName, // then ../config/fileName and last it will look at fileName func LoadConfig(fileName string) { fileName = FindConfigFile(fileName) file, err := os.Open(fileName) if err != nil { panic(T("utils.config.load_config.opening.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } decoder := json.NewDecoder(file) config := model.Config{} err = decoder.Decode(&config) if err != nil { panic(T("utils.config.load_config.decoding.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } if _, err := file.Stat(); err != nil { panic(T("utils.config.load_config.getting.panic", map[string]interface{}{"Filename": fileName, "Error": err.Error()})) } else { CfgFileName = fileName } needSave := len(config.SqlSettings.AtRestEncryptKey) == 0 || len(*config.FileSettings.PublicLinkSalt) == 0 || len(config.EmailSettings.InviteSalt) == 0 || len(config.EmailSettings.PasswordResetSalt) == 0 config.SetDefaults() if err := config.IsValid(); err != nil { panic(T(err.Id)) } if needSave { if err := SaveConfig(fileName, &config); err != nil { l4g.Warn(T(err.Id)) } } if err := ValidateLdapFilter(&config); err != nil { panic(T(err.Id)) } configureLog(&config.LogSettings) if config.FileSettings.DriverName == model.IMAGE_DRIVER_LOCAL { dir := config.FileSettings.Directory if len(dir) > 0 && dir[len(dir)-1:] != "/" { config.FileSettings.Directory += "/" } } Cfg = &config CfgHash = fmt.Sprintf("%x", md5.Sum([]byte(Cfg.ToJson()))) ClientCfg = getClientConfig(Cfg) // Actions that need to run every time the config is loaded if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { // This restarts the job if nessisary (works for config reloads) ldapI.StartLdapSyncJob() } if samlI := einterfaces.GetSamlInterface(); samlI != nil { samlI.ConfigureSP() } SetDefaultRolesBasedOnConfig() }
func createTeamWithLdap(c *Context, w http.ResponseWriter, r *http.Request) { ldap := einterfaces.GetLdapInterface() if ldap == nil { c.Err = model.NewLocAppError("createTeamWithLdap", "ent.ldap.do_login.licence_disable.app_error", nil, "") return } teamSignup := model.TeamSignupFromJson(r.Body) if teamSignup == nil { c.SetInvalidParam("createTeam", "teamSignup") return } teamSignup.Team.PreSave() if err := teamSignup.Team.IsValid(*utils.Cfg.TeamSettings.RestrictTeamNames); err != nil { c.Err = err return } if !isTeamCreationAllowed(c, teamSignup.Team.Email) { return } teamSignup.Team.Id = "" found := FindTeamByName(c, teamSignup.Team.Name, "true") if c.Err != nil { return } if found { c.Err = model.NewLocAppError("createTeamFromSignup", "api.team.create_team_from_signup.unavailable.app_error", nil, "d="+teamSignup.Team.Name) return } user, err := ldap.GetUser(teamSignup.User.Username) if err != nil { c.Err = err return } err = ldap.CheckPassword(teamSignup.User.Username, teamSignup.User.Password) if err != nil { c.Err = err return } if result := <-Srv.Store.Team().Save(&teamSignup.Team); result.Err != nil { c.Err = result.Err return } else { rteam := result.Data.(*model.Team) if _, err := CreateDefaultChannels(c, rteam.Id); err != nil { c.Err = nil return } user.TeamId = rteam.Id ruser, err := CreateUser(rteam, user) if err != nil { c.Err = err return } teamSignup.Team = *rteam teamSignup.User = *ruser w.Write([]byte(teamSignup.ToJson())) } }
func main() { parseCmds() if errstr := doLoadConfig(flagConfigFile); errstr != "" { l4g.Exit("Unable to load mattermost configuration file:", errstr) return } if flagRunCmds { utils.ConfigureCmdLineLog() } utils.InitTranslations(utils.Cfg.LocalizationSettings) utils.TestConnection(utils.Cfg) pwd, _ := os.Getwd() l4g.Info(utils.T("mattermost.current_version"), model.CurrentVersion, model.BuildNumber, model.BuildDate, model.BuildHash, model.BuildHashEnterprise) l4g.Info(utils.T("mattermost.entreprise_enabled"), model.BuildEnterpriseReady) l4g.Info(utils.T("mattermost.working_dir"), pwd) l4g.Info(utils.T("mattermost.config_file"), utils.FindConfigFile(flagConfigFile)) // Special case for upgrading the db to 3.0 // ADDED for 3.0 REMOVE for 3.4 cmdUpdateDb30() api.NewServer() api.InitApi() web.InitWeb() if model.BuildEnterpriseReady == "true" { api.LoadLicense() } if !utils.IsLicensed && len(utils.Cfg.SqlSettings.DataSourceReplicas) > 1 { l4g.Critical(utils.T("store.sql.read_replicas_not_licensed.critical")) return } if flagRunCmds { runCmds() } else { api.StartServer() // If we allow testing then listen for manual testing URL hits if utils.Cfg.ServiceSettings.EnableTesting { manualtesting.InitManualTesting() } setDiagnosticId() go runSecurityAndDiagnosticsJob() if complianceI := einterfaces.GetComplianceInterface(); complianceI != nil { complianceI.StartComplianceDailyJob() } if ldapI := einterfaces.GetLdapInterface(); ldapI != nil { ldapI.StartLdapSyncJob() } // wait for kill signal before attempting to gracefully shutdown // the running service c := make(chan os.Signal) signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) <-c api.StopServer() } }