*
* On success, return 0
* If the ID is in use, return EEXIST
+ * If the ID might clash with -1, return EINVAL
* If the ID is outside the range, return ERANGE
* In other cases, return errno from getgrgid()
*/
return ERANGE;
}
+ /* Check for compatibility with 16b and 32b gid_t error codes */
+ if (gid == UINT16_MAX || gid == UINT32_MAX) {
+ return EINVAL;
+ }
+
/*
* Check whether we already detected this GID
* using the gr_next() loop
* gr_locate_gid() found the GID in an as-yet uncommitted
* entry. We'll proceed below and auto-set a GID.
*/
- } else if (result == EEXIST || result == ERANGE) {
+ } else if (result == EEXIST || result == ERANGE || result == EINVAL) {
/*
* Continue on below. At this time, we won't
- * treat these two cases differently.
+ * treat these three cases differently.
*/
} else {
/*
*gid = id;
free (used_gids);
return 0;
- } else if (result == EEXIST) {
- /* This GID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*gid = id;
free (used_gids);
return 0;
- } else if (result == EEXIST) {
- /* This GID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*gid = id;
free (used_gids);
return 0;
- } else if (result == EEXIST) {
- /* This GID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*gid = id;
free (used_gids);
return 0;
- } else if (result == EEXIST) {
- /* This GID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*
* On success, return 0
* If the ID is in use, return EEXIST
+ * If the ID might clash with -1, return EINVAL
* If the ID is outside the range, return ERANGE
* In other cases, return errno from getpwuid()
*/
return ERANGE;
}
+ /* Check for compatibility with 16b and 32b uid_t error codes */
+ if (uid == UINT16_MAX || uid == UINT32_MAX) {
+ return EINVAL;
+ }
+
/*
* Check whether we already detected this UID
* using the pw_next() loop
* pw_locate_uid() found the UID in an as-yet uncommitted
* entry. We'll proceed below and auto-set an UID.
*/
- } else if (result == EEXIST || result == ERANGE) {
+ } else if (result == EEXIST || result == ERANGE || result == EINVAL) {
/*
* Continue on below. At this time, we won't
- * treat these two cases differently.
+ * treat these three cases differently.
*/
} else {
/*
*uid = id;
free (used_uids);
return 0;
- } else if (result == EEXIST) {
- /* This UID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*uid = id;
free (used_uids);
return 0;
- } else if (result == EEXIST) {
- /* This UID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*uid = id;
free (used_uids);
return 0;
- } else if (result == EEXIST) {
- /* This UID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.
*uid = id;
free (used_uids);
return 0;
- } else if (result == EEXIST) {
- /* This UID is in use, we'll continue to the next */
+ } else if (result == EEXIST || result == EINVAL) {
+ /*
+ * This GID is in use or unusable, we'll
+ * continue to the next.
+ */
} else {
/*
* An unexpected error occurred.