type EntryMap … type UsersAndGroups … type entry … type limits … const totalFieldsGroup … const totalFieldsUser … const klogLevel … const noshell … const fileEtcLoginDefs … const fileEtcPasswd … const fileEtcGroup … var usersToCreateSpec … var groupsToCreateSpec … var defaultLimits … // ID returns the ID for an entry based on the entry name. // In case of a user entry it returns the user UID. // In case of a group entry it returns the group GID. // It returns nil if no such entry exists. func (u *EntryMap) ID(name string) *int64 { … } // String converts an EntryMap object to a readable string. func (u *EntryMap) String() string { … } // AddUsersAndGroups is a public wrapper around addUsersAndGroupsImpl with default system file paths. func AddUsersAndGroups() (*UsersAndGroups, error) { … } // addUsersAndGroupsImpl adds the managed users and groups to the files specified // by pathUsers and pathGroups. It uses the file specified with pathLoginDef to // determine limits for UID and GID. If managed users and groups exist in these files // validation is performed on them. The function returns a pointer to a Users object // that can be used to return UID and GID of managed users. func addUsersAndGroupsImpl(pathLoginDef, pathUsers, pathGroups string) (*UsersAndGroups, error) { … } // RemoveUsersAndGroups is a public wrapper around removeUsersAndGroupsImpl with // default system file paths. func RemoveUsersAndGroups() error { … } // removeUsersAndGroupsImpl removes the managed users and groups from the files specified // by pathUsers and pathGroups. func removeUsersAndGroupsImpl(pathUsers, pathGroups string) error { … } // parseLoginDefs can be used to parse an /etc/login.defs file and obtain system ranges for UID and GID. // Passing an empty string will return the defaults. The defaults are 100-999 for both UID and GID. func parseLoginDefs(file string) (*limits, error) { … } // parseEntries can be used to parse an /etc/passwd or /etc/group file as their format is similar. // It returns a slice of entries obtained from the file. // https://www.cyberciti.biz/faq/understanding-etcpasswd-file-format/ // https://www.cyberciti.biz/faq/understanding-etcgroup-file/ func parseEntries(file string, totalFields int) ([]*entry, error) { … } // validateEntries takes user and group entries and validates if these entries are valid based on limits, // mapping between users and groups and specs. Returns slices of missing user and group entries that must be created. // Returns an error if existing users and groups do not match requirements. func validateEntries(users, groups []*entry, limits *limits) ([]*entry, []*entry, error) { … } // allocateIDs takes a list of entries and based on minimum and maximum ID allocates a "total" of IDs. func allocateIDs(entries []*entry, min, max int64, total int) ([]int64, error) { … } // addEntries takes /etc/passwd or /etc/group file content and appends entries to it based // on a createEntry function. Returns the updated contents of the file. func addEntries(file string, entries []*entry, createEntry func(*entry) string) string { … } // removeEntries takes /etc/passwd or /etc/group file content and deletes entries from them // by name matching. Returns the updated contents of the file and the number of entries removed. func removeEntries(file string, entries []*entry) (string, int) { … } // assignUserAndGroupIDs takes the list of existing groups, the users and groups to be created, // and assigns UIDs and GIDs to the users and groups to be created based on a list of provided UIDs and GIDs. // Returns an error if not enough UIDs or GIDs are passed. It does not perform any other validation. func assignUserAndGroupIDs(groups, usersToCreate, groupsToCreate []*entry, uids, gids []int64) error { … } // createGroup is a helper function to produce a group from entry. func createGroup(e *entry) string { … } // createUser is a helper function to produce a user from entry. func createUser(e *entry) string { … } // entriesToEntryMap takes a list of entries and prepares an EntryMap object. func entriesToEntryMap(entries, spec []*entry) (*EntryMap, error) { … } // entriesToString is a utility to convert a list of entries to string. func entriesToString(entries []*entry) string { … } // openFileWithLock opens the file at path by acquiring an exclusive write lock. // The returned close() function should be called to release the lock and close the file. // If a lock cannot be obtained the function fails after a period of time. func openFileWithLock(path string) (f *os.File, close func(), err error) { … } // readFile reads a File into a string. func readFile(f *os.File) (string, error) { … } // writeFile writes a string to a File. func writeFile(f *os.File, str string) error { … } // UpdatePathOwnerAndPermissions updates the owner and permissions of the given path. // If the path is a directory it is not recursively updated. func UpdatePathOwnerAndPermissions(path string, uid, gid int64, perms uint32) error { … } // UpdatePathOwner recursively updates the owners of a directory. // It is equivalent to calling `chown -R uid:gid /path/to/dir`. func UpdatePathOwner(dirPath string, uid, gid int64) error { … }