summaryrefslogtreecommitdiffstats
path: root/lib/subordinateio.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/subordinateio.c')
-rw-r--r--lib/subordinateio.c135
1 files changed, 78 insertions, 57 deletions
diff --git a/lib/subordinateio.c b/lib/subordinateio.c
index bd1af26..e7cd4b4 100644
--- a/lib/subordinateio.c
+++ b/lib/subordinateio.c
@@ -16,6 +16,12 @@
#include <pwd.h>
#include <ctype.h>
#include <fcntl.h>
+#include <string.h>
+
+#include "alloc.h"
+#include "atoi/str2i.h"
+#include "string/sprintf.h"
+
#define ID_SIZE 31
@@ -32,7 +38,7 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
const struct subordinate_range *rangeent = ent;
struct subordinate_range *range;
- range = (struct subordinate_range *) malloc (sizeof *range);
+ range = MALLOC(1, struct subordinate_range);
if (NULL == range) {
return NULL;
}
@@ -52,7 +58,8 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
*
* @ent: pointer to a subordinate_range struct to free.
*/
-static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
+static void
+subordinate_free(/*@only@*/void *ent)
{
struct subordinate_range *rangeent = ent;
@@ -69,7 +76,8 @@ static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
* in @line, or NULL on failure. Note that the returned value should not
* be freed by the caller.
*/
-static void *subordinate_parse (const char *line)
+static void *
+subordinate_parse(const char *line)
{
static struct subordinate_range range;
static char rangebuf[1024];
@@ -90,19 +98,8 @@ static void *subordinate_parse (const char *line)
* field. The fields are converted into NUL terminated strings.
*/
- for (cp = rangebuf, i = 0; (i < SUBID_NFIELDS) && (NULL != cp); i++) {
- fields[i] = cp;
- while (('\0' != *cp) && (':' != *cp)) {
- cp++;
- }
-
- if ('\0' != *cp) {
- *cp = '\0';
- cp++;
- } else {
- cp = NULL;
- }
- }
+ for (cp = rangebuf, i = 0; (i < SUBID_NFIELDS) && (NULL != cp); i++)
+ fields[i] = strsep(&cp, ":");
/*
* There must be exactly SUBID_NFIELDS colon separated fields or
@@ -111,9 +108,9 @@ static void *subordinate_parse (const char *line)
if (i != SUBID_NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0')
return NULL;
range.owner = fields[0];
- if (getulong (fields[1], &range.start) == 0)
+ if (str2ul(&range.start, fields[1]) == -1)
return NULL;
- if (getulong (fields[2], &range.count) == 0)
+ if (str2ul(&range.count, fields[2]) == -1)
return NULL;
return &range;
@@ -208,7 +205,7 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
/*
* We only do special handling for these two files
*/
- if ((0 != strcmp(db->filename, "/etc/subuid")) && (0 != strcmp(db->filename, "/etc/subgid")))
+ if ((0 != strcmp(db->filename, SUBUID_FILE)) && (0 != strcmp(db->filename, SUBGID_FILE)))
return NULL;
/*
@@ -218,9 +215,9 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
* (It may be specified as literal UID or as another username which
* has the same UID as the username we are looking for.)
*/
- struct passwd *pwd;
+ char owner_uid_string[33];
uid_t owner_uid;
- char owner_uid_string[33] = "";
+ struct passwd *pwd;
/* Get UID of the username we are looking for */
@@ -230,7 +227,8 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
return NULL;
}
owner_uid = pwd->pw_uid;
- sprintf(owner_uid_string, "%lu", (unsigned long int)owner_uid);
+ if (SNPRINTF(owner_uid_string, "%lu", (unsigned long) owner_uid) == -1)
+ return NULL;
commonio_rewind(db);
while ((range = commonio_next(db)) != NULL) {
@@ -313,19 +311,16 @@ static bool have_range(struct commonio_db *db,
static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n)
{
- if (!*ranges) {
- *ranges = malloc(sizeof(struct subid_range));
- if (!*ranges)
- return false;
- } else {
- struct subid_range *alloced;
- alloced = realloc(*ranges, (n + 1) * (sizeof(struct subid_range)));
- if (!alloced)
- return false;
- *ranges = alloced;
- }
- (*ranges)[n].start = new->start;
- (*ranges)[n].count = new->count;
+ struct subid_range *sr;
+
+ sr = REALLOC(*ranges, n + 1, struct subid_range);
+ if (!sr)
+ return false;
+
+ sr[n].start = new->start;
+ sr[n].count = new->count;
+ *ranges = sr;
+
return true;
}
@@ -353,15 +348,19 @@ void free_subordinate_ranges(struct subordinate_range **ranges, int count)
*/
static int subordinate_range_cmp (const void *p1, const void *p2)
{
- struct subordinate_range *range1, *range2;
+ const struct commonio_entry *const *ce1;
+ const struct commonio_entry *const *ce2;
+ const struct subordinate_range *range1, *range2;
- if ((*(struct commonio_entry **) p1)->eptr == NULL)
+ ce1 = p1;
+ range1 = (*ce1)->eptr;
+ if (range1 == NULL)
return 1;
- if ((*(struct commonio_entry **) p2)->eptr == NULL)
- return -1;
- range1 = ((struct subordinate_range *) (*(struct commonio_entry **) p1)->eptr);
- range2 = ((struct subordinate_range *) (*(struct commonio_entry **) p2)->eptr);
+ ce2 = p2;
+ range2 = (*ce2)->eptr;
+ if (range2 == NULL)
+ return -1;
if (range1->start < range2->start)
return -1;
@@ -556,7 +555,7 @@ static int remove_range (struct commonio_db *db,
}
static struct commonio_db subordinate_uid_db = {
- "/etc/subuid", /* filename */
+ SUBUID_FILE, /* filename */
&subordinate_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
@@ -620,17 +619,28 @@ bool have_sub_uids(const char *owner, uid_t start, unsigned long count)
return have_range (&subordinate_uid_db, owner, start, count);
}
+/*
+ * sub_uid_add: add a subuid range, perhaps through nss.
+ *
+ * Return 1 if the range is already present or on success. On error
+ * return 0 and set errno appropriately.
+ */
int sub_uid_add (const char *owner, uid_t start, unsigned long count)
{
- if (get_subid_nss_handle())
- return -EOPNOTSUPP;
+ if (get_subid_nss_handle()) {
+ errno = EOPNOTSUPP;
+ return 0;
+ }
return add_range (&subordinate_uid_db, owner, start, count);
}
+/* Return 1 on success. on failure, return 0 and set errno appropriately */
int sub_uid_remove (const char *owner, uid_t start, unsigned long count)
{
- if (get_subid_nss_handle())
- return -EOPNOTSUPP;
+ if (get_subid_nss_handle()) {
+ errno = EOPNOTSUPP;
+ return 0;
+ }
return remove_range (&subordinate_uid_db, owner, start, count);
}
@@ -652,7 +662,7 @@ uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count)
}
static struct commonio_db subordinate_gid_db = {
- "/etc/subgid", /* filename */
+ SUBGID_FILE, /* filename */
&subordinate_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
@@ -716,17 +726,28 @@ bool local_sub_gid_assigned(const char *owner)
return range_exists (&subordinate_gid_db, owner);
}
+/*
+ * sub_gid_add: add a subgid range, perhaps through nss.
+ *
+ * Return 1 if the range is already present or on success. On error
+ * return 0 and set errno appropriately.
+ */
int sub_gid_add (const char *owner, gid_t start, unsigned long count)
{
- if (get_subid_nss_handle())
- return -EOPNOTSUPP;
+ if (get_subid_nss_handle()) {
+ errno = EOPNOTSUPP;
+ return 0;
+ }
return add_range (&subordinate_gid_db, owner, start, count);
}
+/* Return 1 on success. on failure, return 0 and set errno appropriately */
int sub_gid_remove (const char *owner, gid_t start, unsigned long count)
{
- if (get_subid_nss_handle())
- return -EOPNOTSUPP;
+ if (get_subid_nss_handle()) {
+ errno = EOPNOTSUPP;
+ return 0;
+ }
return remove_range (&subordinate_gid_db, owner, start, count);
}
@@ -910,7 +931,7 @@ static int append_uids(uid_t **uids, const char *owner, int n)
return n;
}
- ret = realloc(*uids, (n + 1) * sizeof(uid_t));
+ ret = REALLOC(*uids, n + 1, uid_t);
if (!ret) {
free(*uids);
return -1;
@@ -985,7 +1006,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b
switch (id_type) {
case ID_TYPE_UID:
if (!sub_uid_lock()) {
- printf("Failed loging subuids (errno %d)\n", errno);
+ printf("Failed locking subuids (errno %d)\n", errno);
return false;
}
if (!sub_uid_open(O_CREAT | O_RDWR)) {
@@ -997,7 +1018,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b
break;
case ID_TYPE_GID:
if (!sub_gid_lock()) {
- printf("Failed loging subgids (errno %d)\n", errno);
+ printf("Failed locking subgids (errno %d)\n", errno);
return false;
}
if (!sub_gid_open(O_CREAT | O_RDWR)) {
@@ -1057,7 +1078,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
switch (id_type) {
case ID_TYPE_UID:
if (!sub_uid_lock()) {
- printf("Failed loging subuids (errno %d)\n", errno);
+ printf("Failed locking subuids (errno %d)\n", errno);
return false;
}
if (!sub_uid_open(O_CREAT | O_RDWR)) {
@@ -1069,7 +1090,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
break;
case ID_TYPE_GID:
if (!sub_gid_lock()) {
- printf("Failed loging subgids (errno %d)\n", errno);
+ printf("Failed locking subgids (errno %d)\n", errno);
return false;
}
if (!sub_gid_open(O_CREAT | O_RDWR)) {
@@ -1097,6 +1118,6 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
}
#else /* !ENABLE_SUBIDS */
-extern int errno; /* warning: ANSI C forbids an empty source file */
+extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */