1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package user
6
7import "sync"
8
9const (
10	userFile  = "/etc/passwd"
11	groupFile = "/etc/group"
12)
13
14var colon = []byte{':'}
15
16// Current returns the current user.
17//
18// The first call will cache the current user information.
19// Subsequent calls will return the cached value and will not reflect
20// changes to the current user.
21func Current() (*User, error) {
22	cache.Do(func() { cache.u, cache.err = current() })
23	if cache.err != nil {
24		return nil, cache.err
25	}
26	u := *cache.u // copy
27	return &u, nil
28}
29
30// cache of the current user
31var cache struct {
32	sync.Once
33	u   *User
34	err error
35}
36
37// Lookup looks up a user by username. If the user cannot be found, the
38// returned error is of type [UnknownUserError].
39func Lookup(username string) (*User, error) {
40	if u, err := Current(); err == nil && u.Username == username {
41		return u, err
42	}
43	return lookupUser(username)
44}
45
46// LookupId looks up a user by userid. If the user cannot be found, the
47// returned error is of type [UnknownUserIdError].
48func LookupId(uid string) (*User, error) {
49	if u, err := Current(); err == nil && u.Uid == uid {
50		return u, err
51	}
52	return lookupUserId(uid)
53}
54
55// LookupGroup looks up a group by name. If the group cannot be found, the
56// returned error is of type [UnknownGroupError].
57func LookupGroup(name string) (*Group, error) {
58	return lookupGroup(name)
59}
60
61// LookupGroupId looks up a group by groupid. If the group cannot be found, the
62// returned error is of type [UnknownGroupIdError].
63func LookupGroupId(gid string) (*Group, error) {
64	return lookupGroupId(gid)
65}
66
67// GroupIds returns the list of group IDs that the user is a member of.
68func (u *User) GroupIds() ([]string, error) {
69	return listGroups(u)
70}
71