-
Notifications
You must be signed in to change notification settings - Fork 0
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
os/user: add users groups iteration functionality #1
base: master
Are you sure you want to change the base?
Conversation
589be3e
to
8e513f5
Compare
It would be also helpful if you listed the exact OS versions you have tested this with, and which commands did you run when testing. For bonus points, write a small application in Go compatible to
|
ca4f26b
to
2806be2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like
cec9b7a
to
6ed0451
Compare
In order to add users and groups iterators for os/user, ReadSubKeyNames must be changed. Instead of returning a full slice of all subkey names, it can be changed to accept callback function, which receives sequentially iterated subkey names. As such, ReadSubKeyNames becomes an iterator and will use less memory for larger sets of data.
Plan9 operating system stores users and groups information in /adm/users file. This file is similar in strucuture to unix based /etc/passwd and /etc/group. Since readColonFile resides in lookup_unix.go file, extracting it makes it possible to reuse the functionality across all os targets that can can utilize the function.
6ed0451
to
70eed7b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does upstream know about these new API proposals?
A ListUsers
type API might be more amenable than a callback-based API
// iterateSIDS iterates through _profileListKey sub keys and calls provided | ||
// fn with enumerated sub key name as parameter. If fn returns non-nil error, | ||
// iteration is terminated. | ||
func iterateSIDS(fn func(string) error) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iterateSIDs
should probably accept a callback that accepts the SID.
func iterateSIDs(fn func(*syscall.SID) error) error
// IterateUsers iterates over user entries. For each retrieved *User entry provided NextUserFunc is called. | ||
// | ||
// On UNIX, if CGO is enabled, getpwent(3) is used in the underlying implementation. Since getpwent(3) is not thread-safe, | ||
// locking is strongly advised. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What needs locking in this case? Maybe provide some examples or checks to make sure it is locked?
result, err := userIterator.get() | ||
|
||
// If result is nil - getpwent iterated through entire users database or there was an error | ||
if result == nil { | ||
return err | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return of err should be based off of what err
actually is instead of the value, result
.
result, err := userIterator.get()
// If result is nil - getpwent iterated through entire users database or there was an error
if err != nil {
return err
}
...
if result == nil {
...
}
if user, ok := v.(*User); ok { | ||
err := fn(user) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
return nil, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if user, ok := v.(*User); ok { | |
err := fn(user) | |
if err != nil { | |
return nil, err | |
} | |
} | |
return nil, nil | |
if user, ok := v.(*User); !ok { | |
return nil, nil | |
} | |
if err := fn(user); err != nil { | |
return nil, err | |
} |
Go standard library has os/user package which allows to lookup user or group records via either user/group name or id. This commit extends capabilities of os/user package by introducing iteration functionality for users and groups. Users and groups iteration functionality might be useful in cases where a full or partial list of all available users/groups is required in an application.
70eed7b
to
e3a4b4f
Compare
Proposal link: golang#47907
Go native users/groups iteration functionality.
Go standard library has os/user package which allows to lookup user
or group records via either user/group name or id. This pull request
extends capabilities of os/user package by introducing iteration
functionality for users and groups.
Users and groups iteration functionality might be useful in cases where
a full or partial list of all available users/groups is required in an
application.
On unix, iteration functionality relies
on two internal implementations: one that does not use cgo and parses
contents of /etc/passwd and /etc/group files for users and groups
respectively, and another one that does use cgo and utilizes POSIX
compliant libc library routines getpwent and getgrent for users and
groups respectively. On windows,
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
registry key is iterated for SID values, each SID value represents either
a user or a group.
Tested on Debian GNU/Linux 10 (buster), macOS 11.5.1, freebsd 13.0,
plan9 fourth edition, windows 10 version 21H1.