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))
}
Example #5
0
// AuthorizedKeys satisfies AccountProvider.
func (s *cachingStore) AuthorizedKeys(username string) ([]string, error) {
	cu, ok := s.userByNameImpl(username)
	if !ok {
		return nil, accounts.UsernameNotFound(username)
	} else if !nowOutsideTimespan(cu.keyRefreshTime, s.config.KeyRefreshCooldown) {
		logger.Infof("Returning cached keys for %v due to cooldown.", username)
		return cu.keys, nil
	}
	view, err := s.apiClient.AuthorizedKeys(username)
	if err != nil {
		return cu.keys, nil
	}
	go s.updateCachedKeys(username, view.Keys, view.Sudoer, timeNow())
	return view.Keys, nil
}
Example #6
0
// UserByName satisfies AccountProvider.
func (s *cachingStore) UserByName(name string) (*accounts.User, error) {
	cu, ok := s.userByNameImpl(name)
	if ok {
		return cu.user, nil
	}
	ch := make(chan struct{})
	logger.Infof("Triggering refresh due to missing user %v.", name)
	s.updateWaiters <- ch
	// Block on update.
	<-ch
	cu, ok = s.userByNameImpl(name)
	if ok {
		return cu.user, nil
	}
	return nil, accounts.UsernameNotFound(name)
}
Example #7
0
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()
}
Example #9
0
// 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)
	}
}
Example #10
0
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)
}
// AuthorizedKeys satisfies APIClient.
func (c *googleAPIClient) AuthorizedKeys(username string) (*cua.AuthorizedKeysView, error) {
	logger.Infof("Fetching authorized keys for %v.", username)
	p, z, i, err := c.instanceInfo()
	if err != nil {
		return nil, err
	}
	view, err := c.service.Linux.GetAuthorizedKeysView(p, z, username, i).Do()
	switch e := err.(type) {
	case nil:
		if view.Resource == nil {
			return nil, fmt.Errorf("Invalid authorized keys returned for %v.", username)
		}
		return view.Resource, nil
	case *googleapi.Error:
		if e.Code == 404 {
			logger.Noticef("User %v does not exist.", username)
			return nil, nil
		}
		return nil, err
	default:
		return nil, err
	}
}