Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/proto/teleport/legacy/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,9 @@ message RoleOptions {
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];

// CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.
string CreateHostUserDefaultShell = 31 [(gogoproto.jsontag) = "create_host_user_default_shell,omitempty"];
}

message RecordSession {
Expand Down
3,547 changes: 1,798 additions & 1,749 deletions api/types/types.pb.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator.
|create_db_user_mode|string or integer|CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop". Can be either the string or the integer representation of each option.|
|create_desktop_user|boolean|CreateDesktopUser allows users to be automatically created on a Windows desktop|
|create_host_user|boolean|CreateHostUser allows users to be automatically created on a host|
|create_host_user_default_shell|string|CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.|
|create_host_user_mode|string or integer|CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop". Can be either the string or the integer representation of each option.|
|desktop_clipboard|boolean|DesktopClipboard indicates whether clipboard sharing is allowed between the user's workstation and the remote desktop. It defaults to true unless explicitly set to false.|
|desktop_directory_sharing|boolean|DesktopDirectorySharing indicates whether directory sharing is allowed between the user's workstation and the remote desktop. It defaults to false unless explicitly set to true.|
Expand Down Expand Up @@ -723,6 +724,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator.
|create_db_user_mode|string or integer|CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop". Can be either the string or the integer representation of each option.|
|create_desktop_user|boolean|CreateDesktopUser allows users to be automatically created on a Windows desktop|
|create_host_user|boolean|CreateHostUser allows users to be automatically created on a host|
|create_host_user_default_shell|string|CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.|
|create_host_user_mode|string or integer|CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop". Can be either the string or the integer representation of each option.|
|desktop_clipboard|boolean|DesktopClipboard indicates whether clipboard sharing is allowed between the user's workstation and the remote desktop. It defaults to true unless explicitly set to false.|
|desktop_directory_sharing|boolean|DesktopDirectorySharing indicates whether directory sharing is allowed between the user's workstation and the remote desktop. It defaults to false unless explicitly set to true.|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator.
|create_db_user_mode|string or integer|CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop". Can be either the string or the integer representation of each option.|
|create_desktop_user|boolean|CreateDesktopUser allows users to be automatically created on a Windows desktop|
|create_host_user|boolean|CreateHostUser allows users to be automatically created on a host|
|create_host_user_default_shell|string|CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.|
|create_host_user_mode|string or integer|CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop". Can be either the string or the integer representation of each option.|
|desktop_clipboard|boolean|DesktopClipboard indicates whether clipboard sharing is allowed between the user's workstation and the remote desktop. It defaults to true unless explicitly set to false.|
|desktop_directory_sharing|boolean|DesktopDirectorySharing indicates whether directory sharing is allowed between the user's workstation and the remote desktop. It defaults to false unless explicitly set to true.|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ resource, which you can apply after installing the Teleport Kubernetes operator.
|create_db_user_mode|string or integer|CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop". Can be either the string or the integer representation of each option.|
|create_desktop_user|boolean|CreateDesktopUser allows users to be automatically created on a Windows desktop|
|create_host_user|boolean|CreateHostUser allows users to be automatically created on a host|
|create_host_user_default_shell|string|CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.|
|create_host_user_mode|string or integer|CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop". Can be either the string or the integer representation of each option.|
|desktop_clipboard|boolean|DesktopClipboard indicates whether clipboard sharing is allowed between the user's workstation and the remote desktop. It defaults to true unless explicitly set to false.|
|desktop_directory_sharing|boolean|DesktopDirectorySharing indicates whether directory sharing is allowed between the user's workstation and the remote desktop. It defaults to false unless explicitly set to true.|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ Optional:
- `create_db_user_mode` (Number) CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop".
- `create_desktop_user` (Boolean)
- `create_host_user` (Boolean)
- `create_host_user_default_shell` (String) CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.
- `create_host_user_mode` (Number) CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop".
- `desktop_clipboard` (Boolean)
- `desktop_directory_sharing` (Boolean)
Expand Down
1 change: 1 addition & 0 deletions docs/pages/reference/terraform-provider/resources/role.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ Optional:
- `create_db_user_mode` (Number) CreateDatabaseUserMode allows users to be automatically created on a database when not set to off. 0 is "unspecified", 1 is "off", 2 is "keep", 3 is "best_effort_drop".
- `create_desktop_user` (Boolean)
- `create_host_user` (Boolean)
- `create_host_user_default_shell` (String) CreateHostUserDefaultShell is used to configure the default shell for newly provisioned host users.
- `create_host_user_mode` (Number) CreateHostUserMode allows users to be automatically created on a host when not set to off. 0 is "unspecified"; 1 is "off"; 2 is "drop" (removed for v15 and above), 3 is "keep"; 4 is "insecure-drop".
- `desktop_clipboard` (Boolean)
- `desktop_directory_sharing` (Boolean)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down Expand Up @@ -2464,6 +2468,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
92 changes: 87 additions & 5 deletions integration/hostuser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
package integration

import (
"bufio"
"bytes"
"context"
"fmt"
Expand All @@ -30,6 +31,7 @@ import (
"os/user"
"path/filepath"
"slices"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -58,6 +60,24 @@ import (
const testuser = "teleport-testuser"
const testgroup = "teleport-testgroup"

func getUserShells(path string) (map[string]string, error) {
f, err := os.Open(path)
Comment thread
rosstimothy marked this conversation as resolved.
if err != nil {
return nil, err
}
defer f.Close()

scanner := bufio.NewScanner(f)

userShells := make(map[string]string)
for scanner.Scan() {
parts := strings.Split(scanner.Text(), ":")
userShells[parts[0]] = parts[len(parts)-1]
}

return userShells, nil
}

func TestRootHostUsersBackend(t *testing.T) {
utils.RequireRoot(t)
sudoersTestDir := t.TempDir()
Expand Down Expand Up @@ -85,7 +105,7 @@ func TestRootHostUsersBackend(t *testing.T) {
require.NoError(t, err)

testHome := filepath.Join("/home", testuser)
err = usersbk.CreateUser(testuser, []string{testgroup}, testHome, "", "")
err = usersbk.CreateUser(testuser, []string{testgroup}, host.UserOpts{Home: testHome})
require.NoError(t, err)

tuser, err := usersbk.Lookup(testuser)
Expand All @@ -98,7 +118,7 @@ func TestRootHostUsersBackend(t *testing.T) {
require.NoError(t, err)
require.Contains(t, tuserGids, group.Gid)

err = usersbk.CreateUser(testuser, []string{}, testHome, "", "")
err = usersbk.CreateUser(testuser, []string{}, host.UserOpts{Home: testHome})
require.True(t, trace.IsAlreadyExists(err))

require.NoFileExists(t, testHome)
Expand All @@ -112,7 +132,7 @@ func TestRootHostUsersBackend(t *testing.T) {

t.Run("Test DeleteUser", func(t *testing.T) {
t.Cleanup(func() { cleanupUsersAndGroups([]string{testuser}, nil) })
err := usersbk.CreateUser(testuser, nil, "", "", "")
err := usersbk.CreateUser(testuser, nil, host.UserOpts{})
require.NoError(t, err)
_, err = usersbk.Lookup(testuser)
require.NoError(t, err)
Expand All @@ -129,7 +149,7 @@ func TestRootHostUsersBackend(t *testing.T) {
t.Cleanup(func() { cleanupUsersAndGroups(checkUsers, nil) })

for _, u := range checkUsers {
err := usersbk.CreateUser(u, []string{}, "", "", "")
err := usersbk.CreateUser(u, []string{}, host.UserOpts{})
require.NoError(t, err)
}

Expand Down Expand Up @@ -159,7 +179,7 @@ func TestRootHostUsersBackend(t *testing.T) {

t.Run("Test CreateHomeDirectory does not follow symlinks", func(t *testing.T) {
t.Cleanup(func() { cleanupUsersAndGroups([]string{testuser}, nil) })
err := usersbk.CreateUser(testuser, nil, "", "", "")
err := usersbk.CreateUser(testuser, nil, host.UserOpts{})
require.NoError(t, err)

tuser, err := usersbk.Lookup(testuser)
Expand Down Expand Up @@ -431,6 +451,68 @@ func TestRootHostUsers(t *testing.T) {
})
}
})

t.Run("Test default shell assignment", func(t *testing.T) {
defaultShellUser := "default-shell"
namedShellUser := "named-shell"
absoluteShellUser := "absolute-shell"

t.Cleanup(func() { cleanupUsersAndGroups([]string{defaultShellUser, namedShellUser, absoluteShellUser}, nil) })

// Create a user with a named shell expected to be available in the PATH
users := srv.NewHostUsers(context.Background(), presence, "host_uuid")
_, err := users.UpsertUser(namedShellUser, services.HostUsersInfo{
Mode: services.HostUserModeKeep,
Shell: "bash",
})
require.NoError(t, err)

// Create a user with an absolute path to a shell
_, err = users.UpsertUser(absoluteShellUser, services.HostUsersInfo{
Mode: services.HostUserModeKeep,
Shell: "/usr/bin/bash",
})
require.NoError(t, err)

// Create a user with the host default shell (default behavior)
_, err = users.UpsertUser(defaultShellUser, services.HostUsersInfo{
Mode: services.HostUserModeKeep,
Shell: "zsh",
})
require.NoError(t, err)

_, err = user.Lookup(namedShellUser)
require.NoError(t, err)

_, err = user.Lookup(absoluteShellUser)
require.NoError(t, err)

_, err = user.Lookup(defaultShellUser)
require.NoError(t, err)

// Verify users have the correct shell assigned
userShells, err := getUserShells("/etc/passwd")
require.NoError(t, err)
Comment on lines +493 to +495
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could run echo $SHELL as each user and validate the output matches our expectations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I considered this too 🤔 Would there be any benefits to doing one versus the other? Parsing the file seemed simpler to me than spinning up commands, but I'd be happy to swap for this if it's a more robust test

Copy link
Copy Markdown
Contributor

@rosstimothy rosstimothy Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it would also validate that a user with a custom shell provisioned is able to access the target host. I don't think there are any other tests that both set a custom shell and start an SSH session.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there are any other tests that both set a custom shell and start an SSH session.

There aren't, but I can take a look at adding one if you think we need the extra coverage. Although that seems like testing the behavior of the host moreso than the behavior of Teleport since how things are handled after updating /etc/passwd is up to the host


// Using bash and sh for this test because they should be present on predictable paths for most reasonable places we might
// be running integration tests
expectedShell := "/usr/bin/bash"

assert.Equal(t, expectedShell, userShells[namedShellUser])
assert.Equal(t, expectedShell, userShells[absoluteShellUser])
assert.NotEqual(t, expectedShell, userShells[defaultShellUser])

// User's shell should not be overwritten when updating, only when creating a new host user
_, err = users.UpsertUser(namedShellUser, services.HostUsersInfo{
Mode: services.HostUserModeKeep,
Shell: "sh",
})
require.NoError(t, err)

userShells, err = getUserShells("/etc/passwd")
require.NoError(t, err)
assert.Equal(t, expectedShell, userShells[namedShellUser])
})
}

func TestRootLoginAsHostUser(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down Expand Up @@ -2464,6 +2468,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ spec:
description: CreateHostUser allows users to be automatically created
on a host
type: boolean
create_host_user_default_shell:
description: CreateHostUserDefaultShell is used to configure the
default shell for newly provisioned host users.
type: string
create_host_user_mode:
description: CreateHostUserMode allows users to be automatically
created on a host when not set to off. 0 is "unspecified"; 1
Expand Down
Loading