summaryrefslogtreecommitdiffstats
path: root/libsubid/subid.h
blob: d13ee84aa53df9d07784a78c1327cb56b98610a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <sys/types.h>
#include <stdio.h>
#include <stdbool.h>

#ifndef SUBID_RANGE_DEFINED
#define SUBID_RANGE_DEFINED 1
#define SUBID_ABI_VERSION 4.0.0
#define SUBID_ABI_MAJOR 4
#define SUBID_ABI_MINOR 0
#define SUBID_ABI_MICRO 0

/* subid_range is just a starting point and size of a range */
struct subid_range {
	unsigned long start;
	unsigned long count;
};

/* subordinage_range is a subid_range plus an owner, representing
 * a range in /etc/subuid or /etc/subgid */
struct subordinate_range {
	const char *owner;
	unsigned long start;
	unsigned long count;
};

enum subid_type {
	ID_TYPE_UID = 1,
	ID_TYPE_GID = 2
};

enum subid_status {
	SUBID_STATUS_SUCCESS = 0,
	SUBID_STATUS_UNKNOWN_USER = 1,
	SUBID_STATUS_ERROR_CONN = 2,
	SUBID_STATUS_ERROR = 3,
};

#ifdef __cplusplus
extern "C" {
#endif

/*
 * subid_init: initialize libsubid
 *
 * @progname: Name to display as program.  If NULL, then "(libsubid)" will be
 *            shown in error messages.
 * @logfd:    Open file pointer to pass error messages to.  If NULL, then
 *            /dev/null will be opened and messages will be sent there.  The
 *            default if libsubid_init() is not called is stderr (2).
 *
 * This function does not need to be called.  If not called, then the defaults
 * will be used.
 *
 * Returns false if an error occurred.
 */
bool subid_init(const char *progname, FILE *logfd);

/*
 * subid_get_uid_ranges: return a list of UID ranges for a user
 *
 * @owner: username being queried
 * @ranges: a pointer to an array of subid_range structs in which the result
 *          will be returned.
 *
 * The caller must free(ranges) when done.
 *
 * returns: number of ranges found, ir < 0 on error.
 */
int subid_get_uid_ranges(const char *owner, struct subid_range **ranges);

/*
 * subid_get_gid_ranges: return a list of GID ranges for a user
 *
 * @owner: username being queried
 * @ranges: a pointer to an array of subid_range structs in which the result
 *          will be returned.
 *
 * The caller must free(ranges) when done.
 *
 * returns: number of ranges found, ir < 0 on error.
 */
int subid_get_gid_ranges(const char *owner, struct subid_range **ranges);

/*
 * subid_get_uid_owners: return a list of uids to which the given uid has been
 *                    delegated.
 *
 * @uid: The subuid being queried
 * @owners: a pointer to an array of uids into which the results are placed.
 *          The returned array must be freed by the caller.
 *
 * Returns the number of uids returned, or < 0 on error.
 */
int subid_get_uid_owners(uid_t uid, uid_t **owner);

/*
 * subid_get_gid_owners: return a list of uids to which the given gid has been
 *                    delegated.
 *
 * @uid: The subgid being queried
 * @owners: a pointer to an array of uids into which the results are placed.
 *          The returned array must be freed by the caller.
 *
 * Returns the number of uids returned, or < 0 on error.
 */
int subid_get_gid_owners(gid_t gid, uid_t **owner);

/*
 * subid_grant_uid_range: assign a subuid range to a user
 *
 * @range: pointer to a struct subordinate_range detailing the UID range
 *         to allocate.  ->owner must be the username, and ->count must be
 *         filled in.  ->start is ignored, and will contain the start
 *         of the newly allocated range, upon success.
 *
 * Returns true if the delegation succeeded, false otherwise.  If true,
 * then the range from (range->start, range->start + range->count) will
 * be delegated to range->owner.
 */
bool subid_grant_uid_range(struct subordinate_range *range, bool reuse);

/*
 * subid_grant_gid_range: assign a subgid range to a user
 *
 * @range: pointer to a struct subordinate_range detailing the GID range
 *         to allocate.  ->owner must be the username, and ->count must be
 *         filled in.  ->start is ignored, and will contain the start
 *         of the newly allocated range, upon success.
 *
 * Returns true if the delegation succeeded, false otherwise.  If true,
 * then the range from (range->start, range->start + range->count) will
 * be delegated to range->owner.
 */
bool subid_grant_gid_range(struct subordinate_range *range, bool reuse);

/*
 * subid_ungrant_uid_range: remove a subuid allocation.
 *
 * @range: pointer to a struct subordinate_range detailing the UID allocation
 *         to remove.
 *
 * Returns true if successful, false if it failed, for instance if the
 * delegation did not exist.
 */
bool subid_ungrant_uid_range(struct subordinate_range *range);

/*
 * subid_ungrant_gid_range: remove a subgid allocation.
 *
 * @range: pointer to a struct subordinate_range detailing the GID allocation
 *         to remove.
 *
 * Returns true if successful, false if it failed, for instance if the
 * delegation did not exist.
 */
bool subid_ungrant_gid_range(struct subordinate_range *range);

#ifdef __cplusplus
}
#endif

#define SUBID_NFIELDS 3
#endif