-
Notifications
You must be signed in to change notification settings - Fork 248
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrite chuser() for simplicity and correctness (#1203)
- Use unambiguous variable names (w/o package name conflict). - Fail on invalid input such as the empty string or `:`. - Do not change group without user, i.e. fail on `:group`. - Parse input using mnemonic APIs. - Do not juggle between integer types. - Unset supplementary groups. - Use set[ug]id(2) to follow the idiom of OpenBSD base programs. (cannot use setres[ug]id(2) as macOS does not have them.) Includes/Supersedes #1202. Fixes #927. I only tested on OpenBSD (so far), but other systems should just work.
- Loading branch information
Showing
2 changed files
with
111 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris | ||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris | ||
|
||
package main | ||
|
||
import ( | ||
"testing" | ||
"os/user" | ||
) | ||
|
||
// Usernames must not contain a number sign. | ||
func TestEmptyString (t *testing.T) { | ||
if chuser("") == nil { | ||
t.Fatal("the empty string is not a valid user") | ||
} | ||
} | ||
|
||
// Either omit delimiter and group, or omit both. | ||
func TestEmptyGroup (t *testing.T) { | ||
if chuser("0:") == nil { | ||
t.Fatal("the empty group is not allowed") | ||
} | ||
} | ||
|
||
// Either user only or user and group. | ||
func TestGroupOnly (t *testing.T) { | ||
if chuser(":0") == nil { | ||
t.Fatal("group only is not allowed") | ||
} | ||
} | ||
|
||
// Usenames must not contain the number sign. | ||
func TestInvalidUsername (t *testing.T) { | ||
const username = "#user" | ||
if chuser(username) == nil { | ||
t.Fatalf("'%s' is not a valid username", username) | ||
} | ||
} | ||
|
||
// User IDs must be non-negative. | ||
func TestInvalidUserid (t *testing.T) { | ||
if chuser("-1") == nil { | ||
t.Fatal("User ID cannot be negative") | ||
} | ||
} | ||
|
||
// Change to the current user by ID. | ||
func TestCurrentUserid (t *testing.T) { | ||
usr, err := user.Current() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if usr.Uid != "0" { | ||
t.Skip("setgroups(2): Only the superuser may set new groups.") | ||
} | ||
|
||
if err = chuser(usr.Uid); err != nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
// Change to a common user by name. | ||
func TestCommonUsername (t *testing.T) { | ||
usr, err := user.Current() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if usr.Uid != "0" { | ||
t.Skip("setgroups(2): Only the superuser may set new groups.") | ||
} | ||
|
||
if err := chuser("nobody"); err != nil { | ||
if _, ok := err.(user.UnknownUserError); ok { | ||
t.Skip(err) | ||
} | ||
t.Fatal(err) | ||
} | ||
} |