mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-11 22:49:54 +00:00
Linux: fix potential deadlock/segfault when calling into libnss for user mgmt (#295)
Export-Source-Commit: 12f28f2b1aa27c84df9f608557b8dc6f0de6cbb2
This commit is contained in:
committed by
Gus Rivera
parent
6d906dc57b
commit
6dbccdd8ad
@@ -393,6 +393,9 @@ linters:
|
||||
- pattern: ^ssh\.(Dial|NewClient|NewClientConn)$
|
||||
pkg: ^golang\.org/x/crypto/ssh$
|
||||
msg: Use api/ssh package to construct SSH clients with proper defaults
|
||||
- pkg: '^os/user$'
|
||||
pattern: '^user\.(Lookup|LookupId|LookupGroup|LookupGroupId|Current|User\.GroupIds)$'
|
||||
msg: 'os/user lookup APIs potentially unsafe; use the session/host/user wrapper instead'
|
||||
- pattern: ^ssh\.(Dial|NewClientWithTimeout|NewClientConnWithTimeout)$
|
||||
pkg: ^github\.com/gravitational/teleport/api/observability/tracing/ssh$
|
||||
msg: Use api/ssh package to construct SSH clients with proper defaults
|
||||
@@ -567,6 +570,12 @@ linters:
|
||||
path: ^api/ssh/
|
||||
text: tracessh.NewClientConnWithTimeout
|
||||
|
||||
# Allow session/host/user and tests to use os/user functions directly.
|
||||
- path: '(_test\.go$|^api/|^integration/helpers/|^lib/utils/testutils|^session/host/user/)'
|
||||
text: "session/host/user"
|
||||
linters:
|
||||
- forbidigo
|
||||
|
||||
# TODO: Fix forced type assertions in the rest of the codebase and remove this exclusion so that the linter can
|
||||
# enforce this rule everywhere.
|
||||
- linters:
|
||||
|
||||
+2
-2
@@ -32,7 +32,6 @@ import (
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"slices"
|
||||
@@ -103,6 +102,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
logutils "github.com/gravitational/teleport/lib/utils/log"
|
||||
"github.com/gravitational/teleport/lib/utils/set"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -5012,7 +5012,7 @@ func loopbackPool(proxyAddr string) *x509.CertPool {
|
||||
|
||||
// Username returns the current user's username
|
||||
func Username() (string, error) {
|
||||
u, err := user.Current()
|
||||
u, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package mysql
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -29,6 +28,7 @@ import (
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/gravitational/teleport/lib/client/db/profile"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -51,7 +51,7 @@ type OptionFile struct {
|
||||
func DefaultConfigPath() (string, error) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil || home == "" {
|
||||
usr, err := user.Current()
|
||||
usr, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return "", trace.ConvertSystemError(err)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ package postgres
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -29,6 +28,7 @@ import (
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/gravitational/teleport/lib/client/db/profile"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -52,7 +52,7 @@ func defaultConfigPath() (string, error) {
|
||||
// TODO(r0mant): Check PGSERVICEFILE and PGSYSCONFDIR env vars as well.
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil || home == "" {
|
||||
usr, err := user.Current()
|
||||
usr, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return "", trace.ConvertSystemError(err)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import (
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"strings"
|
||||
"sync"
|
||||
"unsafe"
|
||||
@@ -46,6 +45,7 @@ import (
|
||||
|
||||
devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1"
|
||||
"github.com/gravitational/teleport/lib/darwin"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
func enrollDeviceInit() (*devicepb.EnrollDeviceInit, error) {
|
||||
@@ -115,7 +115,7 @@ func collectDeviceData(_ CollectDataMode) (*devicepb.DeviceCollectedData, error)
|
||||
return nil, trace.Wrap(statusErrorFromC(res))
|
||||
}
|
||||
|
||||
osUser, err := user.Current()
|
||||
osUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "reading current user")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-attestation/attest"
|
||||
@@ -39,6 +38,7 @@ import (
|
||||
"github.com/gravitational/teleport"
|
||||
devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1"
|
||||
"github.com/gravitational/teleport/lib/linux"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// deviceStateFolderName starts without a "." on Linux systems.
|
||||
@@ -167,7 +167,7 @@ func collectDeviceData(mode CollectDataMode) (*devicepb.DeviceCollectedData, err
|
||||
baseBoardSerialNumber = dmiInfo.BoardSerial
|
||||
}
|
||||
|
||||
u, err := user.Current()
|
||||
u, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -34,6 +33,7 @@ import (
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport/lib/defaults"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
type msalTokenCache struct {
|
||||
@@ -51,7 +51,7 @@ type exchangeResponse struct {
|
||||
|
||||
// getRefreshTokens returns all current refresh tokens from the Azure CLI token cache.
|
||||
func getRefreshTokens() ([]msalToken, error) {
|
||||
usr, err := user.Current()
|
||||
usr, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport/lib/msgraph"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// createGraphClient creates a new graph client from ambient credentials (Azure CLI credentials cache).
|
||||
@@ -60,7 +60,7 @@ func EnsureAZLogin(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func getAzureDir() (string, error) {
|
||||
usr, err := user.Current()
|
||||
usr, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -43,11 +43,7 @@ import (
|
||||
clusterconfigpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/clusterconfig/v1"
|
||||
"github.com/gravitational/teleport/api/types/accessgraph"
|
||||
"github.com/gravitational/teleport/api/utils/retryutils"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUnsupportedPlatform is returned when the operating system is not supported.
|
||||
ErrUnsupportedPlatform = errors.New("unsupported platform")
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// Watcher watches for changes to authorized_keys files
|
||||
@@ -96,7 +92,7 @@ func NewWatcher(ctx context.Context, config WatcherConfig) (*Watcher, error) {
|
||||
switch platform := getOS(config); platform {
|
||||
case constants.LinuxOS, constants.DarwinOS:
|
||||
default:
|
||||
return nil, trace.Wrap(ErrUnsupportedPlatform)
|
||||
return nil, trace.Wrap(hostuser.ErrUnsupportedPlatform)
|
||||
}
|
||||
|
||||
if config.HostID == "" {
|
||||
@@ -112,7 +108,7 @@ func NewWatcher(ctx context.Context, config WatcherConfig) (*Watcher, error) {
|
||||
config.Clock = clockwork.NewRealClock()
|
||||
}
|
||||
if config.getHostUsers == nil {
|
||||
config.getHostUsers = getHostUsers
|
||||
config.getHostUsers = hostuser.GetHostUsers
|
||||
}
|
||||
|
||||
w := &Watcher{
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Teleport
|
||||
* Copyright (C) 2024 Gravitational, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package authorizedkeys
|
||||
|
||||
/*
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <pwd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
// pwentLock should be acquired when using MT-Unsafe race:pwent functions (i.e.
|
||||
// setpwent/getpwent/endpwent).
|
||||
var pwentLock sync.Mutex
|
||||
|
||||
// getHostUsers returns the list of all users on the host from the user
|
||||
// directory (depending on system configuration this can be /etc/passwd,
|
||||
// LDAP...).
|
||||
func getHostUsers() ([]user.User, error) {
|
||||
pwentLock.Lock()
|
||||
defer pwentLock.Unlock()
|
||||
|
||||
C.setpwent()
|
||||
defer C.endpwent()
|
||||
|
||||
var results []user.User
|
||||
for {
|
||||
result, err := C.getpwent()
|
||||
// cgo error convention, check the return value before errno
|
||||
if result != nil {
|
||||
results = append(results, passwdC2Go(result))
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
}
|
||||
|
||||
// passwdC2Go converts `passwd` struct from C to golang native struct
|
||||
func passwdC2Go(passwdC *C.struct_passwd) user.User {
|
||||
name := C.GoString(passwdC.pw_name)
|
||||
return user.User{
|
||||
Name: name,
|
||||
Username: name,
|
||||
Uid: strconv.FormatUint(uint64(passwdC.pw_uid), 10),
|
||||
Gid: strconv.FormatUint(uint64(passwdC.pw_gid), 10),
|
||||
HomeDir: C.GoString(passwdC.pw_dir),
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"maps"
|
||||
"net"
|
||||
"os"
|
||||
"os/user"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
@@ -65,6 +64,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/tlsca"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
logutils "github.com/gravitational/teleport/lib/utils/log"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/reexec"
|
||||
)
|
||||
|
||||
@@ -749,11 +749,11 @@ func (sess *linuxSession) handleClientHello(m *tdpb.ClientHello) error {
|
||||
}
|
||||
|
||||
func (sess *linuxSession) changeAuthorityFileOwnership(m *tdpb.ClientHello) error {
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed to get current user")
|
||||
}
|
||||
targetUser, err := user.Lookup(m.Username)
|
||||
targetUser, err := hostuser.Lookup(m.Username)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed to lookup user %s", m.Username)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -36,6 +35,7 @@ import (
|
||||
reexecutils "github.com/gravitational/teleport/lib/sshutils/reexec"
|
||||
logutils "github.com/gravitational/teleport/lib/utils/log"
|
||||
"github.com/gravitational/teleport/session/envutils"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/reexec"
|
||||
"github.com/gravitational/teleport/session/reexec/reexecconstants"
|
||||
)
|
||||
@@ -126,7 +126,7 @@ func StartTeleportExecXSession(ctx context.Context, cfg *XSessionConfig) (*reexe
|
||||
return nil, trace.BadParameter("missing parameter ChildLogConfig")
|
||||
}
|
||||
|
||||
if _, err := user.Lookup(cfg.Login); err != nil {
|
||||
if _, err := hostuser.Lookup(cfg.Login); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
@@ -36,6 +35,7 @@ import (
|
||||
|
||||
"github.com/gravitational/teleport/lib/utils/mcputils"
|
||||
hostutils "github.com/gravitational/teleport/session/host"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// handleAuthErrStdio starts a stdio message reader and replies with the auth
|
||||
@@ -238,7 +238,7 @@ func makeExecServerRunner(ctx context.Context, session *sessionHandler) (stdioSe
|
||||
}
|
||||
|
||||
// Set host user.
|
||||
hostUser, err := user.Lookup(mcpSpec.RunAsHostUser)
|
||||
hostUser, err := hostuser.Lookup(mcpSpec.RunAsHostUser)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/sshutils"
|
||||
reexecutils "github.com/gravitational/teleport/lib/sshutils/reexec"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/networking"
|
||||
"github.com/gravitational/teleport/session/networking/x11"
|
||||
"github.com/gravitational/teleport/session/pam/pamcfg"
|
||||
@@ -1103,7 +1104,7 @@ func (s *Server) startAuthorizedKeysManager(ctx context.Context, auth authclient
|
||||
Clock: s.clock,
|
||||
},
|
||||
)
|
||||
if errors.Is(err, authorizedkeysreporter.ErrUnsupportedPlatform) {
|
||||
if errors.Is(err, hostuser.ErrUnsupportedPlatform) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return trace.Wrap(err)
|
||||
|
||||
+2
-1
@@ -41,6 +41,7 @@ import (
|
||||
tracessh "github.com/gravitational/teleport/api/observability/tracing/ssh"
|
||||
rsession "github.com/gravitational/teleport/lib/session"
|
||||
reexecutils "github.com/gravitational/teleport/lib/sshutils/reexec"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/reexec"
|
||||
"github.com/gravitational/teleport/session/reexec/reexecconstants"
|
||||
)
|
||||
@@ -535,7 +536,7 @@ func getOwner(login string, lookupUser LookupUser, lookupGroup LookupGroup) (int
|
||||
|
||||
// setOwner changes the owner and mode of the TTY.
|
||||
func (t *terminal) setOwner() error {
|
||||
uid, gid, mode, err := getOwner(t.serverContext.Identity.Login, user.Lookup, user.LookupGroup)
|
||||
uid, gid, mode, err := getOwner(t.serverContext.Identity.Login, hostuser.Lookup, hostuser.LookupGroup)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
"github.com/gravitational/teleport/session/host"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// HostUsersProvisioningBackend is used to implement HostUsersBackend
|
||||
@@ -74,7 +75,7 @@ func newHostSudoersBackend(uuid string) (HostSudoersBackend, error) {
|
||||
|
||||
// Lookup implements host user information lookup
|
||||
func (*HostUsersProvisioningBackend) Lookup(username string) (*user.User, error) {
|
||||
usr, err := user.Lookup(username)
|
||||
usr, err := hostuser.Lookup(username)
|
||||
if err != nil {
|
||||
if !errors.Is(err, user.UnknownUserError(username)) && strings.Contains(err.Error(), "no such file or directory") {
|
||||
return nil, trace.Wrap(err, "looking up user %q, sources configured for passwd in host's /etc/nsswitch.conf may be misconfigured", username)
|
||||
@@ -88,17 +89,17 @@ func (*HostUsersProvisioningBackend) Lookup(username string) (*user.User, error)
|
||||
|
||||
// UserGIDs returns the list of group IDs for a user
|
||||
func (*HostUsersProvisioningBackend) UserGIDs(u *user.User) ([]string, error) {
|
||||
return u.GroupIds()
|
||||
return hostuser.GroupIds(u)
|
||||
}
|
||||
|
||||
// LookupGroup host group information lookup
|
||||
func (*HostUsersProvisioningBackend) LookupGroup(name string) (*user.Group, error) {
|
||||
return user.LookupGroup(name)
|
||||
return hostuser.LookupGroup(name)
|
||||
}
|
||||
|
||||
// LookupGroup host group information lookup by GID
|
||||
func (*HostUsersProvisioningBackend) LookupGroupByID(gid string) (*user.Group, error) {
|
||||
return user.LookupGroupId(gid)
|
||||
return hostuser.LookupGroupId(gid)
|
||||
}
|
||||
|
||||
// UpdateUser sets a user's groups and default shell, replacing their existing groups.
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
decisionpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/decision/v1alpha1"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// ErrorContext contains context used to enrich child process launch errors.
|
||||
@@ -65,7 +66,7 @@ func ChildErrorWithContext(errMsg string, context *ErrorContext) string {
|
||||
unknownUserError := user.UnknownUserError(context.Login)
|
||||
switch {
|
||||
case strings.Contains(errMsg, "failed to open PAM context"): // PAM errors are often cause by an unknown user.
|
||||
if _, err := user.Lookup(context.Login); errors.Is(err, unknownUserError) {
|
||||
if _, err := hostuser.Lookup(context.Login); errors.Is(err, unknownUserError) {
|
||||
if ambiguousHostUserDenial {
|
||||
return ambiguousHostUserError()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -37,6 +36,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/tbot/botfs"
|
||||
"github.com/gravitational/teleport/lib/tbot/internal/encoding"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
const DirectoryType = "directory"
|
||||
@@ -233,7 +233,7 @@ func (dd *Directory) ACLsEnabled() bool {
|
||||
// This will not attempt to correct any issues, but will cause a hard failure if
|
||||
// `acls: required` is configured and issues are detected.
|
||||
func (dd *Directory) verifyLegacyACLs(keys []string) error {
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
// user.Current will fail if the user id does not exist in /etc/passwd
|
||||
// as is the case with some containerized environments.
|
||||
|
||||
@@ -39,6 +39,7 @@ import (
|
||||
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
"github.com/gravitational/teleport/lib/utils/set"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// mostACLRead is a permission mode granting readonly access to a file.
|
||||
@@ -485,7 +486,7 @@ func resolveACLReaderSelector(s *ACLSelector, dir bool) (acl.Entry, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
user, err := user.Lookup(s.User)
|
||||
user, err := hostuser.Lookup(s.User)
|
||||
if err != nil {
|
||||
return acl.Entry{}, trace.Wrap(err)
|
||||
}
|
||||
@@ -506,7 +507,7 @@ func resolveACLReaderSelector(s *ACLSelector, dir bool) (acl.Entry, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
group, err := user.LookupGroup(s.Group)
|
||||
group, err := hostuser.LookupGroup(s.Group)
|
||||
if err != nil {
|
||||
return acl.Entry{}, trace.Wrap(err)
|
||||
}
|
||||
@@ -711,7 +712,7 @@ func GetOwner(fileInfo fs.FileInfo) (*user.User, error) {
|
||||
return nil, trace.NotImplemented("Cannot verify file ownership on this platform.")
|
||||
}
|
||||
|
||||
user, err := user.LookupId(strconv.Itoa(int(info.Uid)))
|
||||
user, err := hostuser.LookupId(strconv.Itoa(int(info.Uid)))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
@@ -42,6 +41,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/teleterm/clusters"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
"github.com/gravitational/teleport/lib/utils/hostid"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
type RoleSetup struct {
|
||||
@@ -98,7 +98,7 @@ func (s *RoleSetup) Run(ctx context.Context, accessAndIdentity AccessAndIdentity
|
||||
}
|
||||
}
|
||||
|
||||
systemUser, err := user.Current()
|
||||
systemUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return noCertsReloaded, trace.Wrap(err)
|
||||
}
|
||||
|
||||
+5
-3
@@ -30,6 +30,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// PercentUsed returns percentage of disk space used. The percentage of disk
|
||||
@@ -93,12 +95,12 @@ func CanUserWriteTo(path string) (bool, error) {
|
||||
|
||||
var usr *user.User
|
||||
if ogUser := os.Getenv("SUDO_USER"); ogUser != "" {
|
||||
usr, err = user.Lookup(ogUser)
|
||||
usr, err = hostuser.Lookup(ogUser)
|
||||
if err != nil {
|
||||
return false, trace.NotFound("could not determine original user: %+v", err)
|
||||
}
|
||||
} else {
|
||||
usr, err = user.Current()
|
||||
usr, err = hostuser.Current()
|
||||
if err != nil {
|
||||
return false, trace.NotFound("could not determine current user: %+v", err)
|
||||
}
|
||||
@@ -116,7 +118,7 @@ func CanUserWriteTo(path string) (bool, error) {
|
||||
}
|
||||
|
||||
// file and user have a group in common
|
||||
groupIDs, err := usr.GroupIds()
|
||||
groupIDs, err := hostuser.GroupIds(usr)
|
||||
if err != nil {
|
||||
return false, trace.NotFound("could not determine current user group ids: %+v", err)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// man GROUPADD(8), exit codes section
|
||||
@@ -181,7 +183,7 @@ func UserDel(username string) (exitCode int, err error) {
|
||||
if err != nil {
|
||||
return -1, trace.NotFound("cant find userdel binary: %s", err)
|
||||
}
|
||||
u, err := user.Lookup(username)
|
||||
u, err := hostuser.Lookup(username)
|
||||
if err != nil {
|
||||
return -1, trace.Wrap(err)
|
||||
}
|
||||
@@ -390,7 +392,7 @@ func GetHostUserCredential(localUser *user.User) (*syscall.Credential, error) {
|
||||
}
|
||||
|
||||
// Lookup supplementary groups for the user.
|
||||
userGroups, err := localUser.GroupIds()
|
||||
userGroups, err := hostuser.GroupIds(localUser)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package user
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrUnsupportedPlatform is returned when the operating system is not supported.
|
||||
var ErrUnsupportedPlatform = errors.New("unsupported platform")
|
||||
@@ -0,0 +1,42 @@
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Package user provides a thin concurrency safe wrapper around the
|
||||
// `os/user` APIs for Linux when CGO is enabled.
|
||||
//
|
||||
// On Linux, the `os/user` package may call into C-based NSS backends via cgo.
|
||||
// Some NSS implementations (or configurations) are not safe for concurrent
|
||||
// use and can deadlock or crash when lookups are performed concurrently.
|
||||
//
|
||||
// To avoid such failures, this package serializes calls to a small set of `os/user`
|
||||
// APIs on linux+cgo builds.
|
||||
// Non-Linux or non-cgo builds forward calls to the stdlib without locking.
|
||||
//
|
||||
// References:
|
||||
//
|
||||
// - Debian bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=831390
|
||||
// - Teleport issue: https://github.com/gravitational/teleport/issues/69662
|
||||
//
|
||||
// Note that this package is placed in `session/host` specifically because the `session` tree
|
||||
// is effectively a submodule within Teleport which guards against any imports from Teleport itself.
|
||||
// This was done to optimize the session helper load times and avoid bleeding runtime dependencies into the
|
||||
// session helper which would incease the load time and degrade latency. Since Teleport still calls
|
||||
// into the session helper code in the same process for which a mutex must be shared, the user package
|
||||
// is placed here despite less than ideal code organization.
|
||||
package user
|
||||
|
||||
// TODO(okraport): revisit this module placement and investigate moving it to lib/utils/user if possible.
|
||||
// TODO(okraport): revisit this module to consider replacement with getent process shell out to avoid the mutex.
|
||||
+3
-3
@@ -16,7 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package authorizedkeys
|
||||
package user
|
||||
|
||||
/*
|
||||
#include <pwd.h>
|
||||
@@ -31,10 +31,10 @@ import (
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
// getHostUsers returns the list of all users on the host from the user
|
||||
// GetHostUsers returns the list of all users on the host from the user
|
||||
// directory (depending on system configuration this can be /etc/passwd,
|
||||
// LDAP...).
|
||||
func getHostUsers() ([]user.User, error) {
|
||||
func GetHostUsers() ([]user.User, error) {
|
||||
// on darwin the setpwent/getpwent/endpwent functions use thread-local
|
||||
// storage so there's no need for a global lock but we must call the whole
|
||||
// sequence from the same thread
|
||||
@@ -0,0 +1,48 @@
|
||||
//go:build !linux || !cgo
|
||||
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package user
|
||||
|
||||
import (
|
||||
osu "os/user"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
// Lookup wraps [os/user.Lookup].
|
||||
func Lookup(username string) (*osu.User, error) { return osu.Lookup(username) }
|
||||
|
||||
// LookupId wraps [os/user.LookupId].
|
||||
func LookupId(id string) (*osu.User, error) { return osu.LookupId(id) }
|
||||
|
||||
// LookupGroup wraps [os/user.LookupGroup].
|
||||
func LookupGroup(name string) (*osu.Group, error) { return osu.LookupGroup(name) }
|
||||
|
||||
// LookupGroupId wraps [os/user.LookupGroupId].
|
||||
func LookupGroupId(id string) (*osu.Group, error) { return osu.LookupGroupId(id) }
|
||||
|
||||
// Current wraps [os/user.Current].
|
||||
func Current() (*osu.User, error) { return osu.Current() }
|
||||
|
||||
// GroupIds wraps [os/user.User.GroupIds].
|
||||
func GroupIds(u *osu.User) ([]string, error) {
|
||||
if u == nil {
|
||||
return nil, trace.BadParameter("user cannot be nil")
|
||||
}
|
||||
return u.GroupIds()
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//go:build linux && cgo
|
||||
|
||||
// Teleport
|
||||
// Copyright (C) 2026 Gravitational, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package user
|
||||
|
||||
/*
|
||||
#define _XOPEN_SOURCE 500
|
||||
#include <pwd.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
osuser "os/user"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
var packageMU sync.Mutex
|
||||
|
||||
// Lookup wraps [os/user.Lookup] with process-wide serialization.
|
||||
func Lookup(username string) (*osuser.User, error) {
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return osuser.Lookup(username)
|
||||
}
|
||||
|
||||
// LookupId wraps [os/user.LookupId] with process-wide serialization.
|
||||
func LookupId(id string) (*osuser.User, error) {
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return osuser.LookupId(id)
|
||||
}
|
||||
|
||||
// LookupGroup wraps [os/user.LookupGroup] with process-wide serialization.
|
||||
func LookupGroup(name string) (*osuser.Group, error) {
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return osuser.LookupGroup(name)
|
||||
}
|
||||
|
||||
// LookupGroupId wraps [os/user.LookupGroupId] with process-wide serialization.
|
||||
func LookupGroupId(id string) (*osuser.Group, error) {
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return osuser.LookupGroupId(id)
|
||||
}
|
||||
|
||||
// Current wraps [os/user.Current] with process-wide serialization.
|
||||
func Current() (*osuser.User, error) {
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return osuser.Current()
|
||||
}
|
||||
|
||||
// LookGroupIdsup wraps [os/user.User.GroupIds] with process-wide serialization.
|
||||
func GroupIds(u *osuser.User) ([]string, error) {
|
||||
if u == nil {
|
||||
return nil, trace.BadParameter("user cannot be nil")
|
||||
}
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
return u.GroupIds()
|
||||
}
|
||||
|
||||
// GetHostUsers returns the list of all users on the host from the user
|
||||
// directory (depending on system configuration this can be /etc/passwd,
|
||||
// LDAP...).
|
||||
func GetHostUsers() ([]osuser.User, error) {
|
||||
// A lock should be acquired when using MT-Unsafe race:pwent functions (i.e.
|
||||
// setpwent/getpwent/endpwent). Since `getpwent` can follow the same path
|
||||
// into libnss we take the package lock.
|
||||
packageMU.Lock()
|
||||
defer packageMU.Unlock()
|
||||
|
||||
C.setpwent()
|
||||
defer C.endpwent()
|
||||
|
||||
var results []osuser.User
|
||||
for {
|
||||
result, err := C.getpwent()
|
||||
// cgo error convention, check the return value before errno
|
||||
if result != nil {
|
||||
results = append(results, passwdC2Go(result))
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return results, nil
|
||||
}
|
||||
}
|
||||
|
||||
// passwdC2Go converts `passwd` struct from C to golang native struct
|
||||
func passwdC2Go(passwdC *C.struct_passwd) osuser.User {
|
||||
name := C.GoString(passwdC.pw_name)
|
||||
return osuser.User{
|
||||
Name: name,
|
||||
Username: name,
|
||||
Uid: strconv.FormatUint(uint64(passwdC.pw_uid), 10),
|
||||
Gid: strconv.FormatUint(uint64(passwdC.pw_gid), 10),
|
||||
HomeDir: C.GoString(passwdC.pw_dir),
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -16,7 +16,7 @@
|
||||
|
||||
//go:build !darwin && !linux
|
||||
|
||||
package authorizedkeys
|
||||
package user
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
@@ -29,7 +29,7 @@ var alwaysFalse bool
|
||||
// getHostUsers returns ErrUnsupportedPlatform because this platform is not
|
||||
// supported. On supported platforms, it returns the list of all users on the
|
||||
// host from the user directory.
|
||||
func getHostUsers() ([]user.User, error) {
|
||||
func GetHostUsers() ([]user.User, error) {
|
||||
if alwaysFalse {
|
||||
// thwart the well-meaning intentions of staticcheck
|
||||
return nil, nil
|
||||
@@ -48,6 +48,7 @@ import (
|
||||
"github.com/gravitational/teleport/session/auditd"
|
||||
"github.com/gravitational/teleport/session/envutils"
|
||||
"github.com/gravitational/teleport/session/host"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/logconstants"
|
||||
"github.com/gravitational/teleport/session/loginuid"
|
||||
"github.com/gravitational/teleport/session/networking"
|
||||
@@ -468,7 +469,7 @@ func RunCommand() (exitErr error, err error) {
|
||||
WtmpdbFile: c.UaccMetadata.WtmpdbPath,
|
||||
})
|
||||
|
||||
localUser, err := user.Lookup(c.Login)
|
||||
localUser, err := hostuser.Lookup(c.Login)
|
||||
if err != nil {
|
||||
if uaccErr := uaccHandler.FailedLogin(c.Login, &c.UaccMetadata.RemoteAddr); uaccErr != nil {
|
||||
slog.DebugContext(ctx, "unable to write failed login attempt to uacc", "error", uaccErr)
|
||||
@@ -671,8 +672,8 @@ type osWrapper struct {
|
||||
|
||||
func newOsWrapper() *osWrapper {
|
||||
return &osWrapper{
|
||||
LookupGroup: user.LookupGroup,
|
||||
LookupUser: user.Lookup,
|
||||
LookupGroup: hostuser.LookupGroup,
|
||||
LookupUser: hostuser.Lookup,
|
||||
CommandContext: exec.CommandContext,
|
||||
}
|
||||
}
|
||||
@@ -698,7 +699,7 @@ func (s *systemUser) UID() string {
|
||||
}
|
||||
|
||||
func (s *systemUser) GroupIds() ([]string, error) {
|
||||
return s.u.GroupIds()
|
||||
return hostuser.GroupIds(s.u)
|
||||
}
|
||||
|
||||
// startNewParker starts a new parker process only if the requested user has been created
|
||||
@@ -810,7 +811,7 @@ func RunNetworking() (code int, err error) {
|
||||
// Once the PAM stack is called with parent process permissions, set the process uid
|
||||
// and gid to the requested user. This way, the user's networking requests will be
|
||||
// done with the user's permissions.
|
||||
localUser, err := user.Lookup(c.Login)
|
||||
localUser, err := hostuser.Lookup(c.Login)
|
||||
if err != nil {
|
||||
return reexecconstants.RemoteCommandFailure, trace.NotFound("%s", err)
|
||||
}
|
||||
@@ -1231,7 +1232,7 @@ func openFileAsUser(localUser *user.User, path string) (file *os.File, err error
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
strIDs, err := localUser.GroupIds()
|
||||
strIDs, err := hostuser.GroupIds(localUser)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
@@ -1480,7 +1481,7 @@ var accessibleHomeDirMu sync.Mutex
|
||||
// hasAccessibleHomeDir checks if the current user has access to an existing home directory.
|
||||
func hasAccessibleHomeDir() error {
|
||||
// this should usually be fetching a cached value
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
@@ -1522,7 +1523,7 @@ func hasAccessibleHomeDir() error {
|
||||
// errors will be returned, which means a missing, inaccessible, or otherwise invalid home directory will result
|
||||
// in a return of (false, nil)
|
||||
func checkHomeDir(localUser *user.User) (bool, error) {
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import (
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -38,6 +37,7 @@ import (
|
||||
"github.com/pkg/sftp"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/reexec/safefile"
|
||||
"github.com/gravitational/teleport/session/sftputils"
|
||||
)
|
||||
@@ -305,7 +305,7 @@ func RunSFTP(logger *slog.Logger) error {
|
||||
}
|
||||
defer auditFile.Close()
|
||||
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -37,18 +37,19 @@ import "C"
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os/user"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// getLoginShell determines the login shell for a given username
|
||||
func getLoginShell(username string) (string, error) {
|
||||
// See if the username is valid.
|
||||
_, err := user.Lookup(username)
|
||||
_, err := hostuser.Lookup(username)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
+9
-8
@@ -37,6 +37,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/tbot/cli"
|
||||
"github.com/gravitational/teleport/lib/tbot/config"
|
||||
"github.com/gravitational/teleport/lib/tbot/identity"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
)
|
||||
|
||||
// RootUID is the UID of the root user
|
||||
@@ -207,7 +208,7 @@ func ensurePermissions(
|
||||
return trace.BadParameter("File %s is expected to be a file but is a directory", path)
|
||||
}
|
||||
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
@@ -319,12 +320,12 @@ func parseOwnerString(owner string) (*user.User, *user.Group, error) {
|
||||
return nil, nil, trace.BadParameter("invalid owner string: %q", owner)
|
||||
}
|
||||
|
||||
ownerUser, err := user.Lookup(ownerParts[0])
|
||||
ownerUser, err := hostuser.Lookup(ownerParts[0])
|
||||
if err != nil {
|
||||
return nil, nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
ownerGroup, err := user.LookupGroup(ownerParts[1])
|
||||
ownerGroup, err := hostuser.LookupGroup(ownerParts[1])
|
||||
if err != nil {
|
||||
return nil, nil, trace.Wrap(err)
|
||||
}
|
||||
@@ -358,12 +359,12 @@ func getOwner(cliOwner, defaultOwner string) (*user.User, *user.Group, error) {
|
||||
|
||||
log.DebugContext(context.TODO(), "Will use current user as owner")
|
||||
// Otherwise, return the current user and group
|
||||
currentUser, err := user.Current()
|
||||
currentUser, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return nil, nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
currentGroup, err := user.LookupGroupId(currentUser.Gid)
|
||||
currentGroup, err := hostuser.LookupGroupId(currentUser.Gid)
|
||||
if err != nil {
|
||||
return nil, nil, trace.Wrap(err)
|
||||
}
|
||||
@@ -383,17 +384,17 @@ func getAndTestACLOptions(initCmd *cli.InitCommand, destDir string) (*user.User,
|
||||
return nil, nil, nil, trace.BadParameter("--reader-user must be set")
|
||||
}
|
||||
|
||||
botUser, err := user.Lookup(initCmd.BotUser)
|
||||
botUser, err := hostuser.Lookup(initCmd.BotUser)
|
||||
if err != nil {
|
||||
return nil, nil, nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
botGroup, err := user.LookupGroupId(botUser.Gid)
|
||||
botGroup, err := hostuser.LookupGroupId(botUser.Gid)
|
||||
if err != nil {
|
||||
return nil, nil, nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
readerUser, err := user.Lookup(initCmd.ReaderUser)
|
||||
readerUser, err := hostuser.Lookup(initCmd.ReaderUser)
|
||||
if err != nil {
|
||||
return nil, nil, nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"maps"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -61,6 +60,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
logutils "github.com/gravitational/teleport/lib/utils/log"
|
||||
"github.com/gravitational/teleport/lib/versioncontrol"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/reexec"
|
||||
"github.com/gravitational/teleport/session/reexec/reexecconstants"
|
||||
"github.com/gravitational/teleport/session/selinux"
|
||||
@@ -1230,7 +1230,7 @@ func onSCP(scpFlags *scp.Flags) error {
|
||||
}
|
||||
|
||||
// get user's home dir (it serves as a default destination)
|
||||
user, err := user.Current()
|
||||
user, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@@ -106,6 +105,7 @@ import (
|
||||
"github.com/gravitational/teleport/lib/utils/mlock"
|
||||
"github.com/gravitational/teleport/lib/utils/parse"
|
||||
stacksignal "github.com/gravitational/teleport/lib/utils/signal"
|
||||
hostuser "github.com/gravitational/teleport/session/host/user"
|
||||
"github.com/gravitational/teleport/session/networking/x11"
|
||||
"github.com/gravitational/teleport/session/shell"
|
||||
"github.com/gravitational/teleport/tool/common"
|
||||
@@ -4453,7 +4453,7 @@ func onSSHLatency(cf *CLIConf) error {
|
||||
func runLocalCommand(hostLogin string, command []string) error {
|
||||
if len(command) == 0 {
|
||||
if hostLogin == "" {
|
||||
user, err := user.Current()
|
||||
user, err := hostuser.Current()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user