diff --git a/cmd/user/create.go b/cmd/user/create.go index dee6c40ee46eb1724411d9b6c232f1f2d0cc1735..cb799633bdd02983801604507650e3a16ee92794 100644 --- a/cmd/user/create.go +++ b/cmd/user/create.go @@ -5,10 +5,8 @@ import ( "os" "os/exec" "path/filepath" - "regexp" "strconv" "strings" - "time" "github.com/go-ldap/ldap/v3" "github.com/spf13/cobra" @@ -216,8 +214,8 @@ func genGecos(u model.User) model.User { gecos += u.GRR + "," gecos += u.Resp + "," gecos += u.Course + "," - gecos += u.Status + "," gecos += u.Expiry + "," + gecos += u.Status + "," gecos += u.Ltype + "," gecos += u.Webdir + "," gecos += u.Nobackup @@ -517,99 +515,6 @@ func createWeb(u model.User) error { return nil } -func validatePath(path string) error { - _, err := os.Stat(path) - if os.IsNotExist(err) { - return nil - } - return fmt.Errorf("Path \"%v\" already exists, please provide a new path", path) -} - -func validateExpiry(expiry string) error { - if expiry == "_" { - return nil - } - - parts := strings.Split(expiry, ".") - if !isValidDate(parts) { - err := fmt.Errorf("Malformed expiry date string, use \"dd.mm.yy\"") - return err - } - return nil -} - -func validateStatus(status string) error { - if status != "Blocked" && status != "Active" { - err := fmt.Errorf("User status can only be \"Active\" or \"Blocked\"") - return err - } - return nil -} - -func validateLtype(ltype string) error { - if ltype != "ini" && ltype != "first" && ltype != "last" { - err := fmt.Errorf("Login type can only be \"ini\", \"first\" or \"last\"") - return err - } - return nil -} - -func validateGRR(grr string) error { - // OK if empty, only "ini" login type requires it and we check :) - if grr == "_" { - return nil - } - - users, err := getUsers() - if err != nil { - return err - } - - isValid, _ := regexp.MatchString(`^\d{8}$`, grr) // is 8 digit number - if !isValid { - err := fmt.Errorf("Malformed GRR string, must be 8 digit number") - return err - } - - if grrExists(users, grr) { - err := fmt.Errorf(`The informed GRR already exists in LDAP database -Note: To search for the account use "useradm user show -r %s"`, grr) - return err - } - - return nil -} - -func validateGID(group string) error { - var err error - - groups, err := getGroups() - if err != nil { - return err - } - - for _, value := range groups { - if value == group { - return nil - } - } - err = fmt.Errorf("Could't find group \"%v\" in LDAP database", group) - return err -} - -func validateUID(login string) error { - users, err := getUsers() - if err != nil { - return err - } - res := searchUser(users, false, login, "", "", "", "", "") - if len(res) != 0 { - return fmt.Errorf(`The informed Login already exists in LDAP database -Note: To search for the account use "useradm user show -l %s"`, login) - } - return nil -} - func validateInputs(opts model.Opts) error { var err error @@ -648,35 +553,3 @@ func validateInputs(opts model.Opts) error { return nil } - -func isValidDate(arr []string) bool { - if len(arr) != 3 { - return false - } - - // convert to int - day, err1 := strconv.Atoi(arr[0]) - mth, err2 := strconv.Atoi(arr[1]) - year, err3 := strconv.Atoi(arr[2]) - - if err1 != nil || err2 != nil || err3 != nil { - return false - } - - // ensure year is two digits - if year < 0 || year > 99 { - return false - } - - // validate the date - fullYear := 2000 + year - t := time.Date(fullYear, time.Month(mth), day, 0, 0, 0, 0, time.UTC) - return t.Day() == day && t.Month() == time.Month(mth) -} - -func ifThenElse(condition bool, a string, b string) string { - if condition { - return a - } - return b -} diff --git a/cmd/user/mod.go b/cmd/user/mod.go index ded2fa745cf200b6fa522aaa3b53a7c93ee90f71..c53b005fc571221ef00987f2d0f8a1fca97ed9e8 100644 --- a/cmd/user/mod.go +++ b/cmd/user/mod.go @@ -1,5 +1,6 @@ package user +// TODO: fix group assignments import ( "bufio" "fmt" @@ -60,9 +61,11 @@ func modifyUserFunc(cmd *cobra.Command, args []string) error { changes, err := promptUserYaml(state) - err = validateGRR(changes.GRR) - if err != nil { - return err + if changes.GRR != curr.GRR { + err = validateGRR(changes.GRR) + if err != nil { + return err + } } err = validateGID(changes.Group) @@ -95,7 +98,14 @@ func modifyUserFunc(cmd *cobra.Command, args []string) error { return fmt.Errorf("Failed to update user attributes: %v", err) } - fmt.Printf("Changes applied!\n") + if err := clearCache(); err != nil { + fmt.Printf(`Failed to reload cache +all is ok but may take a while to apply +Output: %v`, err) + } else { + fmt.Printf("Changes applied!\n") + } + return nil } @@ -223,3 +233,17 @@ func confirmationPrompt(confirm bool, operation string) { } } } + +func clearCache() error { + cmd := exec.Command("nscd", "-i", "passwd") + + cmd.Stdout = nil + cmd.Stderr = nil + err := cmd.Run() + if err != nil { + return err + } + + cmd = exec.Command("nscd", "-i", "group") + return cmd.Run() +} diff --git a/cmd/user/reset.go b/cmd/user/reset.go index a84d944a94bde82206b9ee79c2cab15d53e9a0f6..1df6ea58e59bc72a7ef532157776ae77efe2e472 100644 --- a/cmd/user/reset.go +++ b/cmd/user/reset.go @@ -40,6 +40,7 @@ func resetPass(cmd *cobra.Command, args []string) error { pass = genPassword() } + confirmationPrompt(false, "password reset") err = modKerberosPassword(login, pass) if err != nil { return err @@ -64,15 +65,16 @@ func genPassword() string { } // command that changes the password >:D +// the command kadmin.local returns 0 if the password change +// fails, bruh. so we have to check differently. +// FIXME: maybe do the validation with regex? func modKerberosPassword(login, password string) error { cmd := exec.Command("kadmin.local", "-q", fmt.Sprintf("cpw -pw %s %s", password, login)) - cmd.Stdout = nil - cmd.Stderr = nil - output, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("Failed to change password for %s: %v\nOutput: %s", login, err, output) + output, _ := cmd.CombinedOutput() + if len(output) > 105 { + return fmt.Errorf("Error found changing password, output: \n%v", string(output[:])) } return nil diff --git a/cmd/user/validation.go b/cmd/user/validation.go new file mode 100644 index 0000000000000000000000000000000000000000..474cf8ead05e360220319f19fb69375c7c863faf --- /dev/null +++ b/cmd/user/validation.go @@ -0,0 +1,135 @@ +package user + +import ( + "fmt" + "os" + "regexp" + "strconv" + "strings" + "time" +) + +func validatePath(path string) error { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return nil + } + return fmt.Errorf("Path \"%v\" already exists, please provide a new path", path) +} + +func validateExpiry(expiry string) error { + if expiry == "_" { + return nil + } + + parts := strings.Split(expiry, ".") + if !isValidDate(parts) { + err := fmt.Errorf("Malformed expiry date string, use \"dd.mm.yy\"") + return err + } + return nil +} + +func validateStatus(status string) error { + if status != "Blocked" && status != "Active" { + err := fmt.Errorf("User status can only be \"Active\" or \"Blocked\"") + return err + } + return nil +} + +func validateLtype(ltype string) error { + if ltype != "ini" && ltype != "first" && ltype != "last" { + err := fmt.Errorf("Login type can only be \"ini\", \"first\" or \"last\"") + return err + } + return nil +} + +func validateGRR(grr string) error { + // OK if empty, only "ini" login type requires it and we check :) + if grr == "_" { + return nil + } + + users, err := getUsers() + if err != nil { + return err + } + + isValid, _ := regexp.MatchString(`^\d{8}$`, grr) // is 8 digit number + if !isValid { + err := fmt.Errorf("Malformed GRR string, must be 8 digit number") + return err + } + + if grrExists(users, grr) { + err := fmt.Errorf(`The informed GRR already exists in LDAP database +Note: To search for the account use "useradm user show -r %s"`, grr) + return err + } + + return nil +} + +func validateGID(group string) error { + var err error + + groups, err := getGroups() + if err != nil { + return err + } + + for _, value := range groups { + if value == group { + return nil + } + } + err = fmt.Errorf("Could't find group \"%v\" in LDAP database", group) + return err +} + +func validateUID(login string) error { + users, err := getUsers() + if err != nil { + return err + } + res := searchUser(users, false, login, "", "", "", "", "") + if len(res) != 0 { + return fmt.Errorf(`The informed Login already exists in LDAP database +Note: To search for the account use "useradm user show -l %s"`, login) + } + return nil +} + +func isValidDate(arr []string) bool { + if len(arr) != 3 { + return false + } + + // convert to int + day, err1 := strconv.Atoi(arr[0]) + mth, err2 := strconv.Atoi(arr[1]) + year, err3 := strconv.Atoi(arr[2]) + + if err1 != nil || err2 != nil || err3 != nil { + return false + } + + // ensure year is two digits + if year < 0 || year > 99 { + return false + } + + // validate the date + fullYear := 2000 + year + t := time.Date(fullYear, time.Month(mth), day, 0, 0, 0, 0, time.UTC) + return t.Day() == day && t.Month() == time.Month(mth) +} + +func ifThenElse(condition bool, a string, b string) string { + if condition { + return a + } + return b +}