Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ImageCustomizer: Add Support for Configuring User Sudoers File #11196

Draft
wants to merge 1 commit into
base: 3.0-dev
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions toolkit/tools/imagecustomizerapi/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type User struct {
SecondaryGroups []string `yaml:"secondaryGroups"`
StartupCommand string `yaml:"startupCommand"`
HomeDirectory string `yaml:"homeDirectory"`
Sudo bool `yaml:"sudo"`
Copy link
Member

Choose a reason for hiding this comment

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

Is this setting specifically enabling no-password sudo? If that's the case, then could we make the setting name appropriately specific to that? Given that this is a security-impacting setting, I think we should be as clear as we can about what the image owner is opening up.

}

func (u *User) IsValid() error {
Expand Down
4 changes: 2 additions & 2 deletions toolkit/tools/pkg/imagecustomizerlib/customizefiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const (
defaultFilePermissions = 0o755
)

func copyAdditionalFiles(baseConfigPath string, additionalFiles imagecustomizerapi.AdditionalFileList,
imageChroot *safechroot.Chroot,
func CopyAdditionalFiles(baseConfigPath string, additionalFiles imagecustomizerapi.AdditionalFileList,
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to make a function public if you are accessing it from the same package/directory.

imageChroot safechroot.ChrootInterface,
) error {
for _, additionalFile := range additionalFiles {
logger.Log.Infof("Copying: %s", additionalFile.Destination)
Expand Down
4 changes: 2 additions & 2 deletions toolkit/tools/pkg/imagecustomizerlib/customizefiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestCopyAdditionalFiles(t *testing.T) {
copy_2_filemode := os.FileMode(0o777)

// Copy a file.
err = copyAdditionalFiles(baseConfigPath, imagecustomizerapi.AdditionalFileList{
err = CopyAdditionalFiles(baseConfigPath, imagecustomizerapi.AdditionalFileList{
{
Source: "files/a.txt",
Destination: "/copy_1.txt",
Expand All @@ -56,7 +56,7 @@ func TestCopyAdditionalFiles(t *testing.T) {
verifyFileContentsSame(t, a_orig_path, copy_2_path)

// Copy a different file to the same location.
err = copyAdditionalFiles(baseConfigPath, imagecustomizerapi.AdditionalFileList{
err = CopyAdditionalFiles(baseConfigPath, imagecustomizerapi.AdditionalFileList{
{
Source: "files/b.txt",
Destination: "/copy_1.txt",
Expand Down
2 changes: 1 addition & 1 deletion toolkit/tools/pkg/imagecustomizerlib/customizeos.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func doOsCustomizations(buildDir string, baseConfigPath string, config *imagecus
return err
}

err = copyAdditionalFiles(baseConfigPath, config.OS.AdditionalFiles, imageChroot)
err = CopyAdditionalFiles(baseConfigPath, config.OS.AdditionalFiles, imageChroot)
if err != nil {
return err
}
Expand Down
35 changes: 35 additions & 0 deletions toolkit/tools/pkg/imagecustomizerlib/customizeusers.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,40 @@ func addOrUpdateUser(user imagecustomizerapi.User, baseConfigPath string, imageC
return err
}

// Set user's sudo access.
err = UpdateSudoAccess(imageChroot, user.Name, user.Sudo)
if err != nil {
return err
}

return nil
}

func UpdateSudoAccess(installChroot safechroot.ChrootInterface, username string, enableSudo bool) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was trying to put this function inside userutils.py but will create cyclic dependency issue.

if enableSudo {

// Define the sudo configuration file path for the user
sudoersFile := fmt.Sprintf("/etc/sudoers.d/%s", username)

// Content for sudo configuration
content := fmt.Sprintf("%s ALL=(ALL) NOPASSWD:ALL", username)

// Permissions for the sudoers file (read-only for root)
permissions := imagecustomizerapi.FilePermissions(0440)

// Create the AdditionalFile object
additionalFiles := imagecustomizerapi.AdditionalFileList{
imagecustomizerapi.AdditionalFile{
Destination: fmt.Sprintf("/etc/sudoers.d/%s", username),
Content: &content,
Permissions: &permissions,
},
}

err := CopyAdditionalFiles(sudoersFile, additionalFiles, installChroot)
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need to use CopyAdditionalFiles. Just write to the file using file.Write. (You can use installChroot .RootDir() to get the rootfs directory.)

if err != nil {
return err
}
}
return nil
}
Loading