]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - libutil/login_cap.c
Revert "Set chpass to 755 too"
[pw-darwin.git] / libutil / login_cap.c
index 6d965e307c3457f06ddfae69801d5602fb1a572b..8befd7c87b1d7bfb8dc97dbf915a612a06d85236 100644 (file)
@@ -44,6 +44,10 @@ __FBSDID("$FreeBSD$");
 #include <syslog.h>
 #include <unistd.h>
 
+#include <os/availability.h>
+API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
+void * reallocarray(void * in_ptr, size_t nmemb, size_t size) __DARWIN_EXTSN(reallocarray) __result_use_check;
+
 /*
  * allocstr()
  * Manage a single static pointer for handling a local char* buffer,
@@ -61,6 +65,8 @@ static char * internal_string = NULL;
 static size_t internal_arraysz = 0;
 static const char ** internal_array = NULL;
 
+static char path_login_conf[] = _PATH_LOGIN_CONF;
+
 static char *
 allocstr(const char *str)
 {
@@ -84,7 +90,7 @@ allocarray(size_t sz)
 
     if (sz <= internal_arraysz)
        p = internal_array;
-    else if ((p = realloc(internal_array, sz * sizeof(char*))) != NULL) {
+    else if ((p = reallocarray(internal_array, sz, sizeof(char*))) != NULL) {
        internal_arraysz = sz;
        internal_array = p;
     }
@@ -169,13 +175,16 @@ login_close(login_cap_t * lc)
 
 
 /*
- * login_getclassbyname() get the login class by its name.
+ * login_getclassbyname()
+ * Get the login class by its name.
  * If the name given is NULL or empty, the default class
- * LOGIN_DEFCLASS (ie. "default") is fetched. If the
+ * LOGIN_DEFCLASS (i.e., "default") is fetched.
+ * If the name given is LOGIN_MECLASS and
  * 'pwd' argument is non-NULL and contains an non-NULL
  * dir entry, then the file _FILE_LOGIN_CONF is picked
  * up from that directory and used before the system
- * login database.
+ * login database. In that case the system login database
+ * is looked up using LOGIN_MECLASS, too, which is a bug.
  * Return a filled-out login_cap_t structure, including
  * class name, and the capability record buffer.
  */
@@ -212,12 +221,14 @@ login_getclassbyname(char const *name, const struct passwd *pwd)
 
        if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir,
                            _FILE_LOGIN_CONF) < MAXPATHLEN) {
-           login_dbarray[i] = userpath;
            if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1)
-               i++;            /* only use 'secure' data */
+               login_dbarray[i++] = userpath;
        }
-       if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1)
-           login_dbarray[i++] = _PATH_LOGIN_CONF;
+       /*
+        * XXX: Why to add the system database if the class is `me'?
+        */
+       if (_secure_path(path_login_conf, 0, 0) != -1)
+           login_dbarray[i++] = path_login_conf;
        login_dbarray[i] = NULL;
 
        memset(lc, 0, sizeof(login_cap_t));
@@ -232,7 +243,7 @@ login_getclassbyname(char const *name, const struct passwd *pwd)
                break;  /* Don't retry default on 'me' */
            if (i == 0)
                r = -1;
-           else if ((r = open(login_dbarray[0], O_RDONLY)) >= 0)
+           else if ((r = open(login_dbarray[0], O_RDONLY | O_CLOEXEC)) >= 0)
                close(r);
            /*
             * If there's at least one login class database,
@@ -300,12 +311,13 @@ login_getclass(const char *cls)
 
 
 /*
- * login_getclass()
+ * login_getpwclass()
  * Get the login class for a given password entry from
  * the system (only) login class database.
  * If the password entry's class field is not set, or
  * the class specified does not exist, then use the
- * default of LOGIN_DEFCLASS (ie. "default").
+ * default of LOGIN_DEFCLASS (i.e., "default") for an unprivileged
+ * user or that of LOGIN_DEFROOTCLASS (i.e., "root") for a super-user.
  * Return a filled-out login_cap_t structure, including
  * class name, and the capability record buffer.
  */
@@ -320,14 +332,18 @@ login_getpwclass(const struct passwd *pwd)
        if (cls == NULL || *cls == '\0')
            cls = (pwd->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
     }
+    /*
+     * XXX: pwd should be unused by login_getclassbyname() unless cls is `me',
+     *      so NULL can be passed instead of pwd for more safety.
+     */
     return login_getclassbyname(cls, pwd);
 }
 
 
 /*
  * login_getuserclass()
- * Get the login class for a given password entry, allowing user
- * overrides via ~/.login_conf.
+ * Get the `me' login class, allowing user overrides via ~/.login_conf.
+ * Note that user overrides are allowed only in the `me' class.
  */
 
 login_cap_t *
@@ -337,7 +353,6 @@ login_getuserclass(const struct passwd *pwd)
 }
 
 
-
 /*
  * login_getcapstr()
  * Given a login_cap entry, and a capability name, return the
@@ -731,7 +746,7 @@ login_getcapsize(login_cap_t *lc, const char *cap, rlim_t def, rlim_t error)
 
 /*
  * login_getcapbool()
- * From the login_cap_t <lc>, check for the existance of the capability
+ * From the login_cap_t <lc>, check for the existence of the capability
  * of <cap>.  Return <def> if <lc>->lc_cap is NULL, otherwise return
  * the whether or not <cap> exists there.
  */