func (s *Server) users() string {
	logger.Info("Getting users.")
	users, err := s.Provider.Users()
	if err != nil {
		return marshalError(err)
	}
	var buf bytes.Buffer
	buf.WriteString("200")
	for _, u := range users {
		buf.WriteString("\n")
		buf.WriteString(marshalUser(u))
	}
	logger.Info("Request succeeded.")
	return buf.String()
}
func (s *Server) groups() string {
	logger.Info("Getting groups.")
	groups, err := s.Provider.Groups()
	if err != nil {
		return marshalError(err)
	}
	var buf bytes.Buffer
	buf.WriteString("200")
	for _, g := range groups {
		buf.WriteString("\n")
		buf.WriteString(marshalGroup(g))
	}
	logger.Info("Request succeeded.")
	return buf.String()
}
func (s *Server) names() string {
	logger.Info("Getting names.")
	names, err := s.Provider.Names()
	if err != nil {
		return marshalError(err)
	}
	var buf bytes.Buffer
	buf.WriteString("200")
	for _, n := range names {
		buf.WriteString("\n")
		buf.WriteString(n)
	}
	logger.Info("Request succeeded.")
	return buf.String()
}
func main() {
	flag.Parse()
	logger.Info("Starting daemon.")
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM)
	api, err := apiclient.New(&apiclient.Config{
		APIBase:      *apiBase,
		InstanceBase: *instanceBase,
		UserAgent:    userAgent,
		Timeout:      apiTimeout,
	})
	if err != nil {
		logger.Fatalf("Init failed: %v.", err)
	}
	srv := &server.Server{store.New(api, &store.Config{
		AccountRefreshFrequency: accountRefreshFrequency,
		AccountRefreshCooldown:  accountRefreshCooldown,
		KeyRefreshFrequency:     keyRefreshFrequency,
		KeyRefreshCooldown:      keyRefreshCooldown,
	})}
	go func() {
		err := srv.Serve()
		logger.Fatalf("Server failed: %v.", err)
	}()

	for {
		select {
		case sig := <-interrupt:
			logger.Fatalf("Got interrupt: %v.", sig)
		}
	}
}
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"
	}
}
// GroupByName satisfies AccountProvider.
func (s *cachingStore) GroupByName(name string) (*accounts.Group, error) {
	s.RLock()
	defer s.RUnlock()
	g, ok := s.groupsByName[name]
	if ok {
		return g, nil
	}
	ch := make(chan struct{})
	logger.Info("Triggering refresh due to missing group.")
	go func() { s.updateWaiters <- ch }()
	// Do not block on update.
	return nil, accounts.GroupNameNotFound(name)
}
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)
	}
	logger.Info("Request succeeded.")
	return fmt.Sprintf("200\n%v", marshalUser(user))
}
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)
	}
	logger.Info("Request succeeded.")
	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)
	}
	logger.Info("Request succeeded.")
	return fmt.Sprintf("200\n%v", marshalGroup(group))
}
Beispiel #10
0
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)
	}
	logger.Info("Request succeeded.")
	return fmt.Sprintf("200\n%v", marshalUser(user))
}
Beispiel #11
0
// GroupByName satisfies AccountProvider.
func (s *cachingStore) GroupByName(name string) (*accounts.Group, error) {
	s.RLock()
	defer s.RUnlock()
	if name == sudoersGroupName {
		return s.sudoersGroup(), nil
	}
	g, ok := s.groupsByName[name]
	if ok {
		return g, nil
	}
	logger.Info("Triggering refresh due to missing group.")
	// Do not block on update.
	go func() { s.updateWaiters <- nil }()
	return nil, accounts.GroupNameNotFound(name)
}
// UsersAndGroups satisfies APIClient.
func (c *googleAPIClient) UsersAndGroups() ([]*cua.LinuxUserView, []*cua.LinuxGroupView, error) {
	logger.Info("Fetching users and groups.")
	p, z, i, err := c.instanceInfo()
	if err != nil {
		return nil, nil, err
	}
	view, err := c.service.Linux.GetLinuxAccountViews(p, z, i).Do()
	if err != nil {
		return nil, nil, err
	} else if view.Resource == nil {
		// No users or groups.
		return nil, nil, nil
	} else {
		return view.Resource.UserViews, view.Resource.GroupViews, nil
	}
}
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)
	}
	logger.Info("Request completed.")
}
Beispiel #14
0
func updateTask(s *cachingStore) {
	var lastRefresh time.Time
	for {
		var ch chan struct{}
		select {
		case ch = <-s.updateWaiters:
		case <-timeAfter(s.config.AccountRefreshFrequency):
		}
		if nowOutsideTimespan(lastRefresh, s.config.AccountRefreshCooldown) {
			logger.Info("Refreshing users and groups.")
			updateAccounts(s)
			lastRefresh = timeNow()
		}
		go updateKeys(s)
		if ch != nil {
			close(ch)
		}
	}
}
Beispiel #15
0
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.")
}
Beispiel #16
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)
	}
}
Beispiel #17
0
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)
	}
	logger.Info("Request succeeded.")
	return buf.String()
}