github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/util/fs/files/passwd.go (about)

     1  // Copyright (c) 2018, Sylabs Inc. All rights reserved.
     2  // This software is licensed under a 3-clause BSD license. Please consult the
     3  // LICENSE.md file distributed with the sources of this project regarding your
     4  // rights to use or distribute this software.
     5  
     6  package files
     7  
     8  import (
     9  	"fmt"
    10  	"io/ioutil"
    11  	"os"
    12  
    13  	"github.com/sylabs/singularity/internal/pkg/sylog"
    14  	"github.com/sylabs/singularity/internal/pkg/util/fs"
    15  	"github.com/sylabs/singularity/internal/pkg/util/user"
    16  )
    17  
    18  // Passwd creates a passwd template based on content of file provided in path,
    19  // updates content with current user information and returns content
    20  func Passwd(path string, home string, uid int) (content []byte, err error) {
    21  	sylog.Verbosef("Checking for template passwd file: %s\n", path)
    22  	if fs.IsFile(path) == false {
    23  		return content, fmt.Errorf("passwd file doesn't exist in container, not updating")
    24  	}
    25  
    26  	sylog.Verbosef("Creating passwd content\n")
    27  	passwdFile, err := os.Open(path)
    28  	if err != nil {
    29  		return content, fmt.Errorf("failed to open passwd file in container: %s", err)
    30  	}
    31  	defer passwdFile.Close()
    32  
    33  	content, err = ioutil.ReadAll(passwdFile)
    34  	if err != nil {
    35  		return content, fmt.Errorf("failed to read passwd file content in container: %s", err)
    36  	}
    37  
    38  	pwInfo, err := user.GetPwUID(uint32(uid))
    39  	if err != nil {
    40  		return content, err
    41  	}
    42  
    43  	homeDir := pwInfo.Dir
    44  	if home != "" {
    45  		homeDir = home
    46  	}
    47  	userInfo := fmt.Sprintf("%s:x:%d:%d:%s:%s:%s\n", pwInfo.Name, pwInfo.UID, pwInfo.GID, pwInfo.Gecos, homeDir, pwInfo.Shell)
    48  
    49  	if len(content) > 0 && content[len(content)-1] != '\n' {
    50  		content = append(content, '\n')
    51  	}
    52  
    53  	sylog.Verbosef("Creating template passwd file and appending user data: %s\n", path)
    54  	content = append(content, []byte(userInfo)...)
    55  
    56  	return content, nil
    57  }