Conversation
eb3fed6 to
dfb2353
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1165 +/- ##
==========================================
- Coverage 87.64% 86.08% -1.56%
==========================================
Files 90 97 +7
Lines 6222 6682 +460
Branches 111 111
==========================================
+ Hits 5453 5752 +299
- Misses 713 874 +161
Partials 56 56 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
dfb2353 to
ee39e97
Compare
ee39e97 to
5911ade
Compare
4380115 to
e564efe
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1165 +/- ##
==========================================
+ Coverage 86.26% 87.17% +0.90%
==========================================
Files 99 102 +3
Lines 6685 6798 +113
Branches 111 111
==========================================
+ Hits 5767 5926 +159
+ Misses 862 816 -46
Partials 56 56 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
342adc9 to
5b82500
Compare
0d9d00c to
a1048eb
Compare
internal/services/user/user.go
Outdated
| if err := s.permissionManager.CheckRequestIsFromRootOrUID(ctx, user.UID); err != nil { | ||
| return nil, status.Error(codes.PermissionDenied, err.Error()) |
There was a problem hiding this comment.
I noticed that in case the request is from the non-root user, chsh requires the user to authenticate in order to change the shell.
We should also be able to do that by letting the user authenticate to the broker. Implementing that seems like quite a lot of effort though, so I would postpone that and only allow root to set user shells for now.
There was a problem hiding this comment.
only allow root to set user shells for now
I implemented that
There was a problem hiding this comment.
We should also be able to do that by letting the user authenticate to the broker. Implementing that seems like quite a lot of effort though
Can't we do it in the client-side for now, by just re-exec with sudo if any or (better) using polkit?
There was a problem hiding this comment.
My understanding is that requiring the user to authenticate is meant to improve security. If we would do that client-side, it would just make it more cumbersome for the user without improving security at all, because user processes could still change the user's shell without authentication by talking to the server directly instead of using authctl.
There was a problem hiding this comment.
If we would do that client-side, it would just make it more cumbersome for the user without improving security at all, because user processes could still change the user's shell without authentication by talking to the server directly instead of using authctl.
How that? The server will still only allows request from root. So basically the client has just to do if $UID != 0; then exec pkexec "$0" ${@}; fi or something.
Then ideally, we could do it with proper polkit rules too, so that any user can change it's own password, even if not root or if they have not sudo permissions.
There was a problem hiding this comment.
ah, I misunderstood your proposal. yes, we can add polkit support but I think that's mostly orthogonal to this PR, so I would still do it as a follow-up.
The function that's tested is CheckRequestIsFromRoot.
Also renames peerCredsInfo to peerAuthInfo because the field in peer.Peer is named AuthInfo. Also improves the comment of WithUnixPeerCreds.
a1048eb to
f19e238
Compare
The envutils package provides utilities for manipulating string slices representing environment variables.
We have to pass the GOCOVERDIR environment variable to the authctl binary.
The grpc.NewClient does not actually try to connect to authd, it just sets up the client but doesn't do any I/O.
The original plan was to allow users to change their own shell without root permissions, like chsh does. However, chsh requires the user to authenticate before it allows change the shell. We should also be able to do that by letting the user authenticate to the broker. That's a lot more effort than originally planned though, so for now we only allow root to change user shells.
But display a warning, similar to the behavior of chsh.
The warning message in the golden file still didn't have the "Warning:" prefix we now add to most of our warnings. That's because the tests replaced the entire warning message. Fix by only replacing the parts which need to be replaced.
f19e238 to
ee00943
Compare
|
|
||
| // CheckRequestIsFromRootOrUID checks if the current gRPC request is from a root | ||
| // user or a specified user and returns an error if not. | ||
| func (m Manager) CheckRequestIsFromRootOrUID(ctx context.Context, uid uint32) (err error) { |
There was a problem hiding this comment.
I think this change should stay in a separate commit
There was a problem hiding this comment.
A per 93315ac#r2852397294 do we still need this change though or can we post-pone it?
internal/services/user/user.go
Outdated
| if err := s.permissionManager.CheckRequestIsFromRootOrUID(ctx, user.UID); err != nil { | ||
| return nil, status.Error(codes.PermissionDenied, err.Error()) |
There was a problem hiding this comment.
We should also be able to do that by letting the user authenticate to the broker. Implementing that seems like quite a lot of effort though
Can't we do it in the client-side for now, by just re-exec with sudo if any or (better) using polkit?
|
|
||
| // Check if the shell is in the list of allowed shells in /etc/shells | ||
| shells, err := os.ReadFile("/etc/shells") | ||
| if err != nil { |
There was a problem hiding this comment.
Do we want to skip the check if the file does not exist?
Also, wondering if for testing purposes we should allow some kind of overriding via a test-time variable.
internal/users/userutils.go
Outdated
| return err | ||
| } | ||
| for _, allowedShell := range strings.Split(string(shells), "\n") { | ||
| if allowedShell[0] == '#' { |
There was a problem hiding this comment.
line := strings.TrimSpace(allowedShell)
if line == "" || line[0] == '#' {
But I'd actually swap the definition of allowedShell and line.
| if err != nil { | ||
| return err | ||
| } | ||
| for _, allowedShell := range strings.Split(string(shells), "\n") { |
There was a problem hiding this comment.
What about using bufio.NewScanner()
| if strings.HasPrefix(kv, key+"=") { | ||
| return strings.TrimPrefix(kv, key+"=") | ||
| } |
| if strings.ContainsRune(value, '\x00') { | ||
| return nil, fmt.Errorf("invalid value: %q", value) | ||
| } | ||
|
|
There was a problem hiding this comment.
Maybe also check for valid utf value?
| @@ -0,0 +1,46 @@ | |||
| // Package envutils provides utilities for manipulating string slices representing environment variables. | |||
| package envutils | |||
There was a problem hiding this comment.
Wondering if we could make this a struct that holds the env variables in a map and we can create it from a []string and it can generate one on request.
|
|
||
| //nolint:gosec // G204 it's safe to use exec.Command with a variable here | ||
| cmd := exec.Command(authctlPath, append([]string{"group"}, tc.args...)...) | ||
| cmd.Env = []string{testutils.CoverDirEnv()} |
There was a problem hiding this comment.
Oh, I thought this was addressed already as part of #782 (comment) :)
| } | ||
|
|
||
| message SetShellResponse { | ||
| repeated string warnings = 1; |
There was a problem hiding this comment.
This not a new thing, but I feel that we should try to return error / warning codes instead to clients, so that clients can in case localize them depending on the local configuration (while the daemon may know the locale set by the user, we also need to be able to follow LC_ALL or LANG).
Important
This is based on #1271, please review and merge that first.
Allow users to change their shell.
Closes #939
UDENG-7089