Compare commits
4 Commits
v0.10.0
...
95e85e8b45
Author | SHA1 | Date | |
---|---|---|---|
95e85e8b45 | |||
1a48c7bca5 | |||
5d21764ef1 | |||
c7302f0e17 |
3
.changes/unreleased/Changed-20250311-145410.yaml
Normal file
3
.changes/unreleased/Changed-20250311-145410.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
kind: Changed
|
||||
body: 'UserCommands: create temp file when modifing password over SSH'
|
||||
time: 2025-03-11T14:54:10.720370135-05:00
|
@ -6,16 +6,16 @@ description: This is dedicated to user commands.
|
||||
|
||||
This is dedicated to `user` commands. The command `type` field must be `user`. User is a type that allows one to perform user operations. There are several additional options available when `type` is `user`:
|
||||
|
||||
| name | notes | type | required |
|
||||
| --- | --- | --- | --- |
|
||||
| `userName` | The name of a user to be configured. | `string` | yes |
|
||||
| `userOperation` | The type of operation to perform. | `string` | yes |
|
||||
| `userID` | The user ID to use. | `string` | no |
|
||||
| `userGroups` | The groups the user should be added to. | `[]string` | no |
|
||||
| `userSshPubKeys` | The keys to add to the user's authorized keys. | `[]string` | no |
|
||||
| `userShell` | The shell for the user. | `string` | no |
|
||||
| `userHome` | The user's home directory. | `string` | no |
|
||||
| `userPassword` | The new password value when using the `password` operation. Can be specified by using external directive. | `string` | no |
|
||||
| name | notes | type | required | External directive support
|
||||
| ----------------| -------------------------------------------------------------| ---------- | ---------| --------------------------|
|
||||
| `userName` | The name of a user to be configured. | `string` | yes | no |
|
||||
| `userOperation` | The type of operation to perform. | `string` | yes | no |
|
||||
| `userID` | The user ID to use. | `string` | no | no |
|
||||
| `userGroups` | The groups the user should be added to. | `[]string` | no | no |
|
||||
| `userSshPubKeys`| The keys to add to the user's authorized keys. | `[]string` | no | yes |
|
||||
| `userShell` | The shell for the user. | `string` | no | no |
|
||||
| `userHome` | The user's home directory. | `string` | no | no |
|
||||
| `userPassword` | The new password value when using the `password` operation. | `string` | no | yes |
|
||||
|
||||
|
||||
#### example
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"embed"
|
||||
@ -194,6 +195,60 @@ func (command *Command) RunCmd(cmdCtxLogger zerolog.Logger, opts *ConfigOpts) ([
|
||||
cmdCtxLogger.Error().Err(fmt.Errorf("error when running cmd %s: %w", command.Name, err)).Send()
|
||||
return outputArr, err
|
||||
}
|
||||
|
||||
if command.Type == UserCT {
|
||||
|
||||
if command.UserOperation == "add" {
|
||||
if command.UserSshPubKeys != nil {
|
||||
var (
|
||||
f *os.File
|
||||
err error
|
||||
userHome []byte
|
||||
)
|
||||
|
||||
cmdCtxLogger.Info().Msg("adding SSH Keys")
|
||||
|
||||
localCMD := exec.Command(fmt.Sprintf("grep \"%s\" /etc/passwd | cut -d: -f6", command.Username))
|
||||
userHome, err = localCMD.CombinedOutput()
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error finding user home from /etc/passwd: %v", err)
|
||||
}
|
||||
|
||||
command.UserHome = strings.TrimSpace(string(userHome))
|
||||
userSshDir := fmt.Sprintf("%s/.ssh", command.UserHome)
|
||||
|
||||
os.MkdirAll(userSshDir, 0700)
|
||||
if _, err := os.Stat(fmt.Sprintf("%s/authorized_keys", userSshDir)); os.IsNotExist(err) {
|
||||
_, err := os.Create(fmt.Sprintf("%s/authorized_keys", userSshDir))
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error creating file %s/authorized_keys: %v", userSshDir, err)
|
||||
}
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error opening file %s/authorized_keys: %v", userSshDir, err)
|
||||
}
|
||||
f, err = os.OpenFile(fmt.Sprintf("%s/authorized_keys", userSshDir), 0700, os.ModeAppend)
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error opening file %s/authorized_keys: %v", userSshDir, err)
|
||||
}
|
||||
defer f.Close()
|
||||
for _, k := range command.UserSshPubKeys {
|
||||
buf := bytes.NewBufferString(k)
|
||||
cmdCtxLogger.Info().Str("key", k).Msg("adding SSH key")
|
||||
if _, err := f.ReadFrom(buf); err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error adding to authorized keys: %v", err)
|
||||
}
|
||||
}
|
||||
localCMD = exec.Command(fmt.Sprintf("chown -R %s:%s %s", command.Username, command.Username, userHome))
|
||||
_, err = localCMD.CombinedOutput()
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputArr, nil
|
||||
}
|
||||
|
@ -248,6 +248,9 @@ func unmarshalConfig(k *koanf.Koanf, key string, target interface{}, log zerolog
|
||||
|
||||
func getCommandEnvironments(opts *ConfigOpts) {
|
||||
for cmdName, cmdConf := range opts.Cmds {
|
||||
if cmdConf.Env == "" {
|
||||
continue
|
||||
}
|
||||
opts.Logger.Debug().Str("env file", cmdConf.Env).Str("cmd", cmdName).Send()
|
||||
if err := testFile(cmdConf.Env); err != nil {
|
||||
logging.ExitWithMSG("Could not open file"+cmdConf.Env+": "+err.Error(), 1, &opts.Logger)
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/kevinburke/ssh_config"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pkg/sftp"
|
||||
@ -509,9 +510,25 @@ func (command *Command) RunCmdSSH(cmdCtxLogger zerolog.Logger, opts *ConfigOpts)
|
||||
|
||||
if command.Type == UserCT && command.UserOperation == "password" {
|
||||
// cmdCtxLogger.Debug().Msgf("adding stdin")
|
||||
userNamePass := fmt.Sprintf("%s:%s", command.Username, command.UserPassword)
|
||||
ArgsStr = fmt.Sprintf("echo %s | chpasswd", userNamePass)
|
||||
|
||||
userNamePass := fmt.Sprintf("%s:%s", command.Username, command.UserPassword)
|
||||
client, err := sftp.NewClient(command.RemoteHost.SshClient)
|
||||
if err != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error creating sftp client: %v", err)
|
||||
}
|
||||
uuidFile := uuid.New()
|
||||
passFilePath := fmt.Sprintf("/tmp/%s", uuidFile.String())
|
||||
passFile, passFileErr := client.Create(passFilePath)
|
||||
if passFileErr != nil {
|
||||
return collectOutput(&cmdOutBuf, command.Name, cmdCtxLogger, command.OutputToLog), fmt.Errorf("error creating file /tmp/%s: %v", uuidFile.String(), passFileErr)
|
||||
}
|
||||
|
||||
passFile.Write([]byte(userNamePass))
|
||||
|
||||
ArgsStr = fmt.Sprintf("cat %s | chpasswd", passFilePath)
|
||||
defer passFile.Close()
|
||||
|
||||
defer client.Remove(passFilePath)
|
||||
// commandSession.Stdin = command.stdin
|
||||
}
|
||||
if err := commandSession.Run(ArgsStr); err != nil {
|
||||
|
Reference in New Issue
Block a user