From b581561a63efe427b8da64bdcf2967eaef0bf6fa Mon Sep 17 00:00:00 2001 From: penguinehis Date: Fri, 29 May 2026 17:13:42 -0300 Subject: [PATCH] Fix test --- main.go | 74 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/main.go b/main.go index 1718e06..71b118f 100644 --- a/main.go +++ b/main.go @@ -608,32 +608,66 @@ func linuxExpiryForAccount(expiresAt time.Time) time.Time { } func runUserAdd(args []string) error { - out, err := exec.Command("useradd", args...).CombinedOutput() - if err == nil { - return nil - } - firstErr := fmt.Errorf("useradd: %v: %s", err, strings.TrimSpace(string(out))) - text := strings.ToLower(string(out)) - nameRejected := strings.Contains(text, "invalid user name") || - strings.Contains(text, "invalid username") || - strings.Contains(text, "bad name") || - strings.Contains(text, "does not match") - if !nameRejected { - return firstErr + username := "" + if len(args) > 0 { + username = args[len(args)-1] } - // DragonCore test usernames can start with numbers, for example 820etl. - // Some Linux distributions reject those by default. Debian/Ubuntu shadow-utils - // accept --badname; a few adduser wrappers use --force-badname. Try both as a - // compatibility fallback, keeping the same password, shell and expiry args. - for _, opt := range []string{"--badname", "--force-badname"} { - retryArgs := append([]string{opt}, args...) - out, err = exec.Command("useradd", retryArgs...).CombinedOutput() + attempts := [][]string{} + // DragonCore test usernames are intentionally short and can start with digits + // like 820etl/897blb. Several distros reject those unless --badname is passed. + // Try the permissive flags first for numeric-start names, then fall back to the + // plain useradd call for distros that do not support those options. + if username != "" && username[0] >= '0' && username[0] <= '9' { + attempts = append(attempts, + append([]string{"--badname"}, args...), + append([]string{"--force-badname"}, args...), + ) + } + attempts = append(attempts, args) + + var firstErr error + var firstOut string + var lastErr error + var lastOut string + for _, tryArgs := range attempts { + out, err := exec.Command("useradd", tryArgs...).CombinedOutput() if err == nil { return nil } + if firstErr == nil { + firstErr = err + firstOut = strings.TrimSpace(string(out)) + } + lastErr = err + lastOut = strings.TrimSpace(string(out)) } - return firstErr + + // If the plain call failed because of username policy, retry permissive flags + // even for non-numeric names. This keeps compatibility with strict distros. + if firstErr != nil && len(attempts) == 1 { + text := strings.ToLower(firstOut) + nameRejected := strings.Contains(text, "invalid user name") || + strings.Contains(text, "invalid username") || + strings.Contains(text, "bad name") || + strings.Contains(text, "does not match") + if nameRejected { + for _, opt := range []string{"--badname", "--force-badname"} { + retryArgs := append([]string{opt}, args...) + out, err := exec.Command("useradd", retryArgs...).CombinedOutput() + if err == nil { + return nil + } + lastErr = err + lastOut = strings.TrimSpace(string(out)) + } + } + } + + if lastErr != nil { + return fmt.Errorf("useradd: %v: %s", lastErr, lastOut) + } + return fmt.Errorf("useradd failed: %v: %s", firstErr, firstOut) } func (a *App) deleteSSH(username, uuid string) error {