diff --git a/tool/tctl/common/resource_command.go b/tool/tctl/common/resource_command.go index 671c4999a51a5..888151aee73f4 100644 --- a/tool/tctl/common/resource_command.go +++ b/tool/tctl/common/resource_command.go @@ -362,6 +362,13 @@ func (rc *ResourceCommand) Create(ctx context.Context, client *authclient.Client var reader io.Reader if rc.filename == "" { + stat, err := os.Stdin.Stat() + if err != nil { + return trace.Wrap(err) + } + if (stat.Mode() & os.ModeCharDevice) != 0 { + return trace.BadParameter("no file specified or input via stdin") + } reader = os.Stdin } else { f, err := utils.OpenFileAllowingUnsafeLinks(rc.filename) diff --git a/tool/tctl/common/resource_command_test.go b/tool/tctl/common/resource_command_test.go index fe2d59fdd52b0..030c84712dcfb 100644 --- a/tool/tctl/common/resource_command_test.go +++ b/tool/tctl/common/resource_command_test.go @@ -2489,6 +2489,10 @@ func TestCreateResources(t *testing.T) { kind: "empty-doc", create: testCreateWithEmptyDocument, }, + { + kind: "no-file-or-input", + create: testCreateWithNoFileOrInput, + }, { kind: types.KindDatabaseObjectImportRule, create: testCreateDatabaseObjectImportRule, @@ -2780,6 +2784,15 @@ spec: require.NoError(t, err) } +func testCreateWithNoFileOrInput(t *testing.T, clt *authclient.Client) { + prevStdin := os.Stdin + os.Stdin, _ = os.Open(os.DevNull) + t.Cleanup(func() { os.Stdin = prevStdin }) + + _, err := runResourceCommand(t, clt, []string{"create"}) + require.ErrorContains(t, err, "no file specified or input via stdin") +} + func testCreateUser(t *testing.T, clt *authclient.Client) { // Ensure that our test user does not exist _, err := runResourceCommand(t, clt, []string{"get", types.KindUser + "/llama", "--format=json"})