]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - libc/gen/pw_scan.c
It is believed the last subsystem that limited ID sizes to something
[pw-darwin.git] / libc / gen / pw_scan.c
index 9db291df868fbd0e128f59a2a356ab8bbdc2deb1..24e822597bfd782806b6910adbe3a0f77c1b6ed2 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * SUCH DAMAGE.
  */
 
-#ifndef lint
-#if 0
+#if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)pw_scan.c  8.3 (Berkeley) 4/2/94";
-#endif
-static const char rcsid[] =
-  "$FreeBSD$";
-#endif /* not lint */
+#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
 
 /*
  * This module is used to "verify" password entries by chpass(1) and
@@ -59,21 +53,27 @@ static const char rcsid[] =
 
 /*
  * Some software assumes that IDs are short.  We should emit warnings
- * for id's which can not be stored in a short, but we are more liberal
+ * for id's which cannot be stored in a short, but we are more liberal
  * by default, warning for IDs greater than USHRT_MAX.
  *
- * If pw_big_ids_warning is anything other than -1 on entry to pw_scan()
- * it will be set based on the existance of PW_SCAN_BIG_IDS in the
- * environment.
+ * If pw_big_ids_warning is -1 on entry to pw_scan(), it will be set based
+ * on the existence of PW_SCAN_BIG_IDS in the environment.
+ *
+ * It is believed all baseline system software that can not handle the
+ * normal ID sizes is now gone so pw_big_ids_warning is disabled for now.
+ * But the code has been left in place in case end-users want to re-enable
+ * it and/or for the next time the ID sizes get bigger but pieces of the
+ * system lag behind.
  */
-static int     pw_big_ids_warning = -1;
+static int     pw_big_ids_warning = 0;
 
 int
 __pw_scan(char *bp, struct passwd *pw, int flags)
 {
        uid_t id;
        int root;
-       char *p, *sh;
+       char *ep, *p, *sh;
+       unsigned long temp;
 
        if (pw_big_ids_warning == -1)
                pw_big_ids_warning = getenv("PW_SCAN_BIG_IDS") == NULL ? 1 : 0;
@@ -101,10 +101,17 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
                        return (0);
                }
        }
-       id = strtoul(p, (char **)NULL, 10);
-       if (errno == ERANGE) {
+       errno = 0;
+       temp = strtoul(p, &ep, 10);
+       if ((temp == ULONG_MAX && errno == ERANGE) || temp > UID_MAX) {
+               if (flags & _PWSCAN_WARN)
+                       warnx("%s > max uid value (%u)", p, UID_MAX);
+               return (0);
+       }
+       id = temp;
+       if (*ep != '\0') {
                if (flags & _PWSCAN_WARN)
-                       warnx("%s > max uid value (%lu)", p, ULONG_MAX);
+                       warnx("%s uid is incorrect", p);
                return (0);
        }
        if (root && id) {
@@ -122,10 +129,24 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
                goto fmt;
        if (p[0])
                pw->pw_fields |= _PWF_GID;
-       id = strtoul(p, (char **)NULL, 10);
-       if (errno == ERANGE) {
+       else {
+               if (pw->pw_name[0] != '+' && pw->pw_name[0] != '-') {
+                       if (flags & _PWSCAN_WARN)
+                               warnx("no gid for user %s", pw->pw_name);
+                       return (0);
+               }
+       }
+       errno = 0;
+       temp = strtoul(p, &ep, 10);
+       if ((temp == ULONG_MAX && errno == ERANGE) || temp > GID_MAX) {
                if (flags & _PWSCAN_WARN)
-                       warnx("%s > max gid value (%lu)", p, ULONG_MAX);
+                       warnx("%s > max gid value (%u)", p, GID_MAX);
+               return (0);
+       }
+       id = temp;
+       if (*ep != '\0') {
+               if (flags & _PWSCAN_WARN)
+                       warnx("%s gid is incorrect", p);
                return (0);
        }
        if (flags & _PWSCAN_WARN && pw_big_ids_warning && id > USHRT_MAX) {
@@ -166,7 +187,7 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
                goto fmt;
 
        p = pw->pw_shell;
-       if (root && *p)                                 /* empty == /bin/sh */
+       if (root && *p) {                               /* empty == /bin/sh */
                for (setusershell();;) {
                        if (!(sh = getusershell())) {
                                if (flags & _PWSCAN_WARN)
@@ -176,6 +197,8 @@ __pw_scan(char *bp, struct passwd *pw, int flags)
                        if (!strcmp(p, sh))
                                break;
                }
+               endusershell();
+       }
        if (p[0])
                pw->pw_fields |= _PWF_SHELL;