Exemple #1
0
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()
	}
}
Exemple #5
0
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
}
Exemple #6
0
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
}
Exemple #7
0
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)
			}
		}
	}
}
Exemple #8
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)))
}
Exemple #9
0
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)))
	}
}
Exemple #10
0
// 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()
}
Exemple #11
0
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()))
	}
}
Exemple #12
0
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()
	}
}