func send(req string, extendTimeout bool) ([]string, error) {
	conn, err := net.DialUnix("unix", nil, &net.UnixAddr{socketPath, "unix"})
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	writeDeadline := time.Now().Add(clientTimeout)
	conn.SetWriteDeadline(writeDeadline)
	_, err = conn.Write([]byte(req))
	if err != nil {
		logger.Errorf("Failed to write request: %v.", err)
		return nil, err
	}
	readDeadline := time.Now().Add(clientTimeout)
	if extendTimeout {
		readDeadline = time.Now().Add(extendedTimeout)
	}
	conn.SetReadDeadline(readDeadline)
	data, err := ioutil.ReadAll(conn)
	if err != nil {
		logger.Errorf("Failed to read response: %v.", err)
		return nil, err
	}
	resp := strings.Split(string(data), "\n")
	err = checkHeader(resp)
	if err != nil {
		logger.Errorf("Request failed: %v.", err)
		return nil, err
	}
	return resp[1:], nil
}
func (s *Server) respond(req string) string {
	parts := strings.Split(req, " ")
	cmd := parts[0]
	args := parts[1:]
	switch cmd {
	case "user_by_name":
		return s.userByName(args)
	case "user_by_uid":
		return s.userByUID(args)
	case "users":
		return s.users()
	case "group_by_name":
		return s.groupByName(args)
	case "group_by_gid":
		return s.groupByGID(args)
	case "groups":
		return s.groups()
	case "names":
		return s.names()
	case "is_name":
		return s.isName(args)
	case "keys":
		return s.authorizedKeys(args)
	default:
		logger.Errorf("Invalid request: %v.", req)
		return "400"
	}
}
func (s *Server) handle(conn net.Conn) {
	defer conn.Close()
	deadline := time.Now().Add(serverTimeout)
	conn.SetReadDeadline(deadline)
	data := make([]byte, maxRequestSize)
	n, err := conn.Read(data)
	if err != nil {
		logger.Errorf("Failed to read request: %v.", err)
		return
	}
	resp := s.respond(string(data[:n]))
	deadline = time.Now().Add(serverTimeout)
	conn.SetWriteDeadline(deadline)
	_, err = conn.Write([]byte(resp))
	if err != nil {
		logger.Errorf("Failed to write response: %v.", err)
	}
}
func (s *Server) groupByGID(args []string) string {
	gid, err := parseID(args)
	if err != nil {
		logger.Errorf("Invalid GID for group: %v.", err)
		return "400"
	}
	logger.Infof("Getting group by GID: %v.", gid)
	group, err := s.Provider.GroupByGID(gid)
	if err != nil {
		return marshalError(err)
	}
	return fmt.Sprintf("200\n%v", marshalGroup(group))
}
func (s *Server) groupByName(args []string) string {
	name, err := parseName(args)
	if err != nil {
		logger.Errorf("Invalid name for group: %v.", err)
		return "400"
	}
	logger.Infof("Getting group by name: %v.", name)
	group, err := s.Provider.GroupByName(name)
	if err != nil {
		return marshalError(err)
	}
	return fmt.Sprintf("200\n%v", marshalGroup(group))
}
func (s *Server) userByUID(args []string) string {
	uid, err := parseID(args)
	if err != nil {
		logger.Errorf("Invalid UID for user: %v.", err)
		return "400"
	}
	logger.Infof("Getting user by UID: %v.", uid)
	user, err := s.Provider.UserByUID(uid)
	if err != nil {
		return marshalError(err)
	}
	return fmt.Sprintf("200\n%v", marshalUser(user))
}
func (s *Server) userByName(args []string) string {
	name, err := parseName(args)
	if err != nil {
		logger.Errorf("Invalid name for user: %v.", err)
		return "400"
	}
	logger.Infof("Getting user by name: %v.", name)
	user, err := s.Provider.UserByName(name)
	if err != nil {
		return marshalError(err)
	}
	return fmt.Sprintf("200\n%v", marshalUser(user))
}
func (s *Server) isName(args []string) string {
	name, err := parseName(args)
	if err != nil {
		logger.Errorf("Invalid name: %v.", err)
		return "400"
	}
	logger.Infof("Checking name: %v.", name)
	is, err := s.Provider.IsName(name)
	if err != nil {
		return marshalError(err)
	} else if is {
		logger.Info("Valid name.")
		return "200"
	} else {
		logger.Info("Invalid name.")
		return "404"
	}
}
func (s *Server) authorizedKeys(args []string) string {
	username, err := parseName(args)
	if err != nil {
		logger.Errorf("Invalid username for keys: %v.", err)
		return "400"
	}
	logger.Infof("Getting keys for user: %v.", username)
	keys, err := s.Provider.AuthorizedKeys(username)
	if err != nil {
		return marshalError(err)
	}
	var buf bytes.Buffer
	buf.WriteString("200")
	for _, k := range keys {
		buf.WriteString("\n")
		buf.WriteString(k)
	}
	return buf.String()
}
func updateAccounts(s *cachingStore) {
	users, groups, err := s.apiClient.UsersAndGroups()
	if err != nil {
		logger.Errorf("Failed refresh: %v.", err)
		return
	}
	s.Lock()
	defer s.Unlock()
	oldUsers := s.usersByName
	s.usersByName = make(map[string]*cachedUser)
	s.usersByUID = make(map[uint32]*cachedUser)
	s.groupsByName = make(map[string]*accounts.Group)
	s.groupsByGID = make(map[uint32]*accounts.Group)
	for _, u := range users {
		user := &accounts.User{
			Name:          u.Username,
			UID:           uint32(u.Uid),
			GID:           uint32(u.Gid),
			Gecos:         u.Gecos,
			HomeDirectory: u.HomeDirectory,
			Shell:         u.Shell,
		}
		cu := &cachedUser{user: user}
		if old, ok := oldUsers[user.Name]; ok {
			cu.keyRefreshTime = old.keyRefreshTime
			cu.keys = old.keys
			cu.sudoer = old.sudoer
		}
		s.usersByName[user.Name] = cu
		s.usersByUID[user.UID] = cu
	}
	for _, g := range groups {
		group := &accounts.Group{
			Name:    g.GroupName,
			GID:     uint32(g.Gid),
			Members: g.Members,
		}
		s.groupsByName[group.Name] = group
		s.groupsByGID[group.GID] = group
	}
	logger.Info("Refreshing users and groups succeeded.")
}
// Serve begins serving accounts information through a socket forever.
func (s *Server) Serve() error {
	os.Remove(socketPath)
	sock, err := net.ListenUnix("unix", &net.UnixAddr{socketPath, "unix"})
	if err != nil {
		return err
	}
	// Make the socket readable and writeable by all.
	os.Chmod(socketPath, os.ModePerm)
	listeningCallback()
	logger.Infof("Listening for connections at %v.", socketPath)
	for {
		conn, err := sock.Accept()
		if err != nil {
			logger.Errorf("Failed to accept connection: %v.", err)
			continue
		}
		logger.Info("Accepted connection.")
		go s.handle(conn)
	}
}
func updateKeys(s *cachingStore) {
	type update struct {
		name string
		view *cua.AuthorizedKeysView
		err  error
		time time.Time
	}
	ch := make(chan update)
	workers := 0
	for _, name := range keysRequiringRefresh(s) {
		go func(n string) {
			view, err := s.apiClient.AuthorizedKeys(n)
			ch <- update{n, view, err, timeNow()}
		}(name)
		workers += 1
	}
	refreshedKeys := make([]update, workers)
	for workers != 0 {
		up := <-ch
		workers -= 1
		if up.err != nil {
			logger.Errorf("Failed key refresh for %v: %v.", up.name, up.err)
			continue
		}
		logger.Infof("Refreshed keys for %v.", up.name)
		refreshedKeys = append(refreshedKeys, up)
	}
	s.Lock()
	defer s.Unlock()
	for _, rk := range refreshedKeys {
		if cu, ok := s.usersByName[rk.name]; ok {
			cu.keys = rk.view.Keys
			cu.sudoer = rk.view.Sudoer
			cu.keyRefreshTime = rk.time
		}
	}
	refreshCallback(s.config)
}