user/shadow.go
func (s *Shadow) Add(key []byte) (err error) {
	loadConfig()

	shadow, err := LookupShadow(s.Name)
	if err != nil {
		if _, ok := err.(NoFoundError); !ok {
			return
		}
	}
	if shadow != nil {
		return ErrUserExist
	}

	if s.Name == "" {
		return RequiredError("Name")
	}
	if s.Max == 0 {
		return RequiredError("Max")
	}
	if s.Warn == 0 {
		return RequiredError("Warn")
	}

	// Backup
	if err = backup(_SHADOW_FILE); err != nil {
		return
	}

	db, err := openDBFile(_SHADOW_FILE, os.O_WRONLY|os.O_APPEND)
	if err != nil {
		return
	}
	defer func() {
		e := db.close()
		if e != nil && err == nil {
			err = e
		}
	}()

	if key != nil {
		s.password, _ = config.crypter.Generate(key, nil)
		if s.changed == _ENABLE_AGING {
			s.setChange()
		}
	} else {
		s.password = "*" // Password disabled.
	}

	_, err = db.file.WriteString(s.String())
	return
}
func (s *Shadow) Add(key []byte) (err error) {
	loadConfig()

	shadow, err := LookupShadow(s.Name)
	if err != nil {
		if _, ok := err.(NoFoundError); !ok {
			return
		}
	}
	if shadow != nil {
		return ErrUserExist
	}

	if s.Name == "" {
		return RequiredError("Name")
	}
	if s.Max == 0 {
		return RequiredError("Max")
	}
	if s.Warn == 0 {
		return RequiredError("Warn")
	}

	// Backup
	if err = backup(_SHADOW_FILE); err != nil {
		return
	}

	db, err := openDBFile(_SHADOW_FILE, os.O_WRONLY|os.O_APPEND)
	if err != nil {
		return
	}
	defer func() {
		e := db.close()
		if e != nil && err == nil {
			err = e
		}
	}()

	if key != nil {
		s.password, _ = config.crypter.Generate(key, nil)
		if s.changed == _ENABLE_AGING {
			s.setChange()
		}
	} else {
		s.password = "*" // Password disabled.
	}

	_, err = db.file.WriteString(s.String())
	return
}
// == Editing
//
// Add adds a new shadowed user.
// If the key is not nil, generates a hashed password.
//
// It is created a backup before of modify the original file.