package common import ( "errors" "strings" ) // 定义常见的SMB错误类型 var ( ErrAuthFailed = errors.New("认证失败") ErrAccountLocked = errors.New("账户锁定") ErrAccessDenied = errors.New("拒绝访问") ErrAccountDisabled = errors.New("账户禁用") ErrPasswordExpired = errors.New("密码过期") ErrConnectionFailed = errors.New("连接失败") ErrTimeout = errors.New("连接超时") ErrSessionDeleted = errors.New("会话断开") ) // ClassifySmbError 对SMB错误进行分类和标准化 func ClassifySmbError(err error) error { if err == nil { return nil } // 清理错误信息中的换行符和多余空格 errMsg := strings.TrimSpace(strings.ReplaceAll(err.Error(), "\n", " ")) errMsgLower := strings.ToLower(errMsg) // SMB1特定错误处理 if strings.Contains(errMsg, "NT Status Error") { switch { case strings.Contains(errMsg, "STATUS_LOGON_FAILURE"): return ErrAuthFailed case strings.Contains(errMsg, "STATUS_ACCOUNT_LOCKED_OUT"): return ErrAccountLocked case strings.Contains(errMsg, "STATUS_ACCESS_DENIED"): return ErrAccessDenied case strings.Contains(errMsg, "STATUS_ACCOUNT_DISABLED"): return ErrAccountDisabled case strings.Contains(errMsg, "STATUS_PASSWORD_EXPIRED"): return ErrPasswordExpired case strings.Contains(errMsg, "STATUS_USER_SESSION_DELETED"): return ErrSessionDeleted default: return ErrAuthFailed } } // SMB2特定错误处理 switch { case strings.Contains(errMsgLower, "account has been automatically locked") || strings.Contains(errMsgLower, "account has been locked") || strings.Contains(errMsgLower, "user account has been automatically locked"): return ErrAccountLocked case strings.Contains(errMsgLower, "access denied") || strings.Contains(errMsgLower, "access is denied"): return ErrAccessDenied case strings.Contains(errMsgLower, "account disabled") || strings.Contains(errMsgLower, "account is disabled"): return ErrAccountDisabled case strings.Contains(errMsgLower, "password expired") || strings.Contains(errMsgLower, "password has expired"): return ErrPasswordExpired case strings.Contains(errMsgLower, "connection refused") || strings.Contains(errMsgLower, "connection failed") || strings.Contains(errMsgLower, "no connection could be made"): return ErrConnectionFailed case strings.Contains(errMsgLower, "timeout") || strings.Contains(errMsgLower, "timed out"): return ErrTimeout case strings.Contains(errMsgLower, "session") && strings.Contains(errMsgLower, "deleted"): return ErrSessionDeleted case strings.Contains(errMsgLower, "logon failure") || strings.Contains(errMsgLower, "authentication failed") || strings.Contains(errMsgLower, "login failed"): return ErrAuthFailed } // 默认返回原始错误 return err } // IsAccountLockError 判断是否为账户锁定错误 func IsAccountLockError(err error) bool { return errors.Is(err, ErrAccountLocked) || strings.Contains(strings.ToLower(err.Error()), "locked") } // IsFatalError 判断是否为致命错误(应该停止尝试该用户) func IsFatalError(err error) bool { return errors.Is(err, ErrAccountLocked) || errors.Is(err, ErrAccountDisabled) || errors.Is(err, ErrPasswordExpired) }