summaryrefslogtreecommitdiff
path: root/libshouldbeinlibc/ugids.h
blob: 10e7a2429704210b6a16cdce46ef5a21abe92594 (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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/* Uid/gid parsing/frobbing

   Copyright (C) 1997,2001 Free Software Foundation, Inc.

   Written by Miles Bader <miles@gnu.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2, or (at
   your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */

#ifndef __UGIDS_H__
#define __UGIDS_H__

#include <stdlib.h>		/* For inline function stuff.  */
#include <idvec.h>
#include <features.h>

#ifdef UGIDS_DEFINE_EI
#define UGIDS_EI
#else
#define UGIDS_EI __extern_inline
#endif

/* A structure holding a set of the common various types of ids.  */
struct ugids
{
  struct idvec eff_uids;	/* Effective UIDs */
  struct idvec eff_gids;	/* Effective GIDs */
  struct idvec avail_uids;	/* Available UIDs */
  struct idvec avail_gids;	/* Available GIDs */

  /* These should be a subset of EFF/AVAIL_GIDS, containing those gids which
     are present only by implication from uids in EFF/AVAIL_UIDS.  */
  struct idvec imp_eff_gids;
  struct idvec imp_avail_gids;
};

#define UGIDS_INIT { IDVEC_INIT, IDVEC_INIT, IDVEC_INIT, IDVEC_INIT, IDVEC_INIT, IDVEC_INIT }

/* Return a new ugids structure, or 0 if an allocation error occurs.  */
struct ugids *make_ugids ();

extern void ugids_fini (struct ugids *ugids);

extern void ugids_free (struct ugids *ugids);

extern int ugids_is_empty (const struct ugids *ugids);

extern int ugids_equal (const struct ugids *ugids1, const struct ugids *ugids2);

#if defined(__USE_EXTERN_INLINES) || defined(UGIDS_DEFINE_EI)

/* Free all resources used by UGIDS except UGIDS itself.  */
UGIDS_EI void
ugids_fini (struct ugids *ugids)
{
  idvec_fini (&ugids->eff_uids);
  idvec_fini (&ugids->eff_gids);
  idvec_fini (&ugids->avail_uids);
  idvec_fini (&ugids->avail_gids);
  idvec_fini (&ugids->imp_eff_gids);
  idvec_fini (&ugids->imp_avail_gids);
}

/* Free all resources used by UGIDS.  */
UGIDS_EI void
ugids_free (struct ugids *ugids)
{
  ugids_fini (ugids);
  free (ugids);
}

/* Return true if UGIDS contains no ids.  */
UGIDS_EI int
ugids_is_empty (const struct ugids *ugids)
{
  /* We needn't test the imp_*_gids vectors because they are subsets of the
     corresponding *_gids vectors.  */
  return
    idvec_is_empty (&ugids->eff_uids)
    && idvec_is_empty (&ugids->eff_gids)
    && idvec_is_empty (&ugids->avail_uids)
    && idvec_is_empty (&ugids->avail_gids);
}

/* Free all resources used by UGIDS except UGIDS itself.  */
UGIDS_EI int
ugids_equal (const struct ugids *ugids1, const struct ugids *ugids2)
{
  return
    idvec_equal (&ugids1->eff_uids, &ugids2->eff_uids)
    && idvec_equal (&ugids1->eff_gids, &ugids2->eff_gids)
    && idvec_equal (&ugids1->avail_uids, &ugids2->avail_uids)
    && idvec_equal (&ugids1->avail_gids, &ugids2->avail_gids)
    && idvec_equal (&ugids1->imp_eff_gids, &ugids2->imp_eff_gids)
    && idvec_equal (&ugids1->imp_avail_gids, &ugids2->imp_avail_gids);
}

#endif /* Use extern inlines.  */

/* Add all ids in NEW to UGIDS.  */
error_t ugids_merge (struct ugids *ugids, const struct ugids *new);

/* Set the ids in UGIDS to those in NEW.  */
error_t ugids_set (struct ugids *ugids, const struct ugids *new);

/* Remove the ids in SUB from those in UGIDS.  */
error_t ugids_subtract (struct ugids *ugids, const struct ugids *sub);

/* Mark as implied all gids in UGIDS that can be implied from its uids.  */
error_t ugids_imply_all (struct ugids *ugids);

/* Save any effective ids in UGIDS by merging them into the available ids,
   and removing them from the effective ones.  */
error_t ugids_save (struct ugids *ugids);

/* Verify that we have the right to the ids in UGIDS, given that we already
   possess those in HAVE_UIDS and HAVE_GIDS, asking for passwords where
   necessary.  0 is returned if access should be allowed, otherwise
   EINVAL if an incorrect password was entered, or an error relating to
   resource failure.  The GETPASS_FN, GETPASS_HOOK, VERIFY_FN, and
   VERIFY_HOOK arguments are as for the idvec_verify function (in <idvec.h>).  */
error_t ugids_verify (const struct ugids *ugids,
		      const struct idvec *have_uids,
		      const struct idvec *have_gids,
		      char *(*getpass_fn) (const char *prompt,
					   uid_t id, int is_group,
					   void *pwd_or_grp, void *hook),
		      void *getpass_hook,
		      error_t (*verify_fn) (const char *password,
					    uid_t id, int is_group,
					    void *pwd_or_grp, void *hook),
		      void *verify_hook);

/* Make an auth port from UGIDS and return it in AUTH, using authority in
   both the auth port FROM and the current auth port.  */
error_t ugids_make_auth (const struct ugids *ugids,
			 const auth_t *from, size_t num_from,
			 auth_t *auth);

/* Verify that we have the right to the ids in UGIDS, given that we already
   possess those in HAVE_UIDS and HAVE_GIDS (asking for passwords where
   necessary), and return corresponding authentication in AUTH; the auth
   ports in FROM, of length NUM_FROM, are used to supplement the auth port of
   the current process if necessary.  0 is returned if access should be
   allowed, otherwise EINVAL if an incorrect password was entered, or an
   error relating to resource failure.  GETPASS_FN and GETPASS_HOOK are as
   for the idvec_verify function in <idvec.h>.  */
error_t ugids_verify_make_auth (const struct ugids *ugids,
				const struct idvec *have_uids,
				const struct idvec *have_gids,
				char *(*getpass_fn) (const char *prompt,
						     uid_t id, int is_group,
						     void *pwd_or_grp,
						     void *hook),
				void *getpass_hook,
				const auth_t *from, size_t num_from,
				auth_t *auth);

/* Merge the ids from the auth port  AUTH into UGIDS.  */
error_t ugids_merge_auth (struct ugids *ugids, auth_t auth);

/* Return a string representation of the ids in UGIDS.  SHOW_VALUES and
   SHOW_NAMES reflect how each id is printed (if SHOW_NAMES is true values
   are used where names aren't available); if both are true, the
   `VALUE(NAME)' format is used.  ID_SEP, TYPE_SEP, and HDR_SEP contain the
   strings that separate, respectively, multiple ids of a particular type
   (default ","), the various types of ids (default ", "), and the name of
   each type from its ids (default ": ").  The empty string is returned for
   an empty list, and 0 for an allocation error.  */
char *ugids_rep (const struct ugids *ugids, int show_values, int show_names,
		 const char *id_sep, const char *type_sep,
		 const char *hdr_sep);

/* Add a new uid to UGIDS.  If AVAIL is true, it's added to the avail uids
   instead of the effective ones.  */
error_t ugids_add_uid (struct ugids *ugids, uid_t uid, int avail);

/* Add a new gid to UGIDS.  If AVAIL is true, it's added to the avail gids
   instead of the effective ones.  */
error_t ugids_add_gid (struct ugids *ugids, gid_t gid, int avail);

/* Add UID to UGIDS, plus any gids to which that user belongs.  If AVAIL is
   true, the are added to the avail gids instead of the effective ones.  */
error_t ugids_add_user (struct ugids *ugids, uid_t uid, int avail);

/* Install UID into UGIDS as the main user, making sure that the posix
   `real' and `saved' uid slots are filled in, and similarly add all
   groups to which UID belongs.  */
error_t ugids_set_posix_user (struct ugids *ugids, uid_t uid);

/* Params to be passed as the input when parsing UGIDS_ARGP.  */
struct ugids_argp_params
{
  /* Parsed ids should be added here.  */
  struct ugids *ugids;

  /* If true, parse multiple args as user otherwise, parse none.  */
  int parse_user_args;

  /* If true, and PARSE_USER_ARGS is true, add user args to the available
     ids, not the effective ones.  If both are true, add them to both.
     If both are false, use the special ugids_set_posix_user instead (which
     sets both, in a particular way).  */
  int user_args_are_effective;
  int user_args_are_available;

  /* If >= 0, a user that should be added if none are specified on the
     command line (following the same rules).  */
  int default_user;

  /* If true, at least one id has to be specified.  */
  int require_ids;
};

/* A parser for selecting a set of ugids.  */
extern struct argp ugids_argp;

#endif /* __UGIDS_H__ */