]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - login-utils/lslogins.c
Make the ways of using output stream consistent in usage()
[thirdparty/util-linux.git] / login-utils / lslogins.c
index 3646883e0ef6807ed4153e21116ee83e878b5fce..217f3f3aedc9c6dc8e4df95a9c0548a0aa94f08c 100644 (file)
@@ -64,7 +64,7 @@
  * column description
  */
 struct lslogins_coldesc {
-       const char *name;
+       const char * const name;
        const char *help;
        const char *pretty_name;
 
@@ -478,7 +478,7 @@ static struct utmpx *get_last_btmp(struct lslogins_control *ctl, const char *use
 
 static int parse_utmpx(const char *path, size_t *nrecords, struct utmpx **records)
 {
-       size_t i, imax = 0;
+       size_t i, imax = 1;
        struct utmpx *ary = NULL;
        struct stat st;
 
@@ -490,9 +490,9 @@ static int parse_utmpx(const char *path, size_t *nrecords, struct utmpx **record
 
        /* optimize allocation according to file size, the realloc() below is
         * just fallback only */
-       if (stat(path, &st) == 0 && (size_t) st.st_size > sizeof(struct utmpx)) {
+       if (stat(path, &st) == 0 && (size_t) st.st_size >= sizeof(struct utmpx)) {
                imax = st.st_size / sizeof(struct utmpx);
-               ary = xmalloc(imax * sizeof(struct utmpx));
+               ary = xreallocarray(NULL, imax, sizeof(struct utmpx));
        }
 
        for (i = 0; ; i++) {
@@ -505,7 +505,7 @@ static int parse_utmpx(const char *path, size_t *nrecords, struct utmpx **record
                        break;
                }
                if (i == imax)
-                       ary = xrealloc(ary, (imax *= 2) * sizeof(struct utmpx));
+                       ary = xreallocarray(ary, imax *= 2, sizeof(struct utmpx));
                ary[i] = *u;
        }
 
@@ -604,7 +604,7 @@ static int get_nprocs(const uid_t uid)
 }
 #endif
 
-static const char *get_pwd_method(const char *str, const char **next, unsigned int *sz)
+static const char *get_pwd_method(const char *str, const char **next)
 {
        const char *p = str;
        const char *res = NULL;
@@ -612,32 +612,50 @@ static const char *get_pwd_method(const char *str, const char **next, unsigned i
        if (!p || *p++ != '$')
                return NULL;
 
-       if (sz)
-               *sz = 0;
-
        switch (*p) {
        case '1':
                res = "MD5";
-               if (sz)
-                       *sz = 22;
                break;
        case '2':
-               p++;
-               if (*p == 'a' || *p == 'y')
+               switch(*(p+1)) {
+               case 'a':
+               case 'y':
+                       p++;
                        res = "Blowfish";
+                       break;
+               case 'b':
+                       p++;
+                       res = "bcrypt";
+                       break;
+               }
+               break;
+       case '3':
+               res = "NT";
                break;
        case '5':
                res = "SHA-256";
-               if (sz)
-                       *sz = 43;
                break;
        case '6':
                res = "SHA-512";
-               if (sz)
-                       *sz = 86;
+               break;
+       case '7':
+               res = "scrypt";
+               break;
+       case 'y':
+               res = "yescrypt";
+               break;
+       case 'g':
+               if (*(p + 1) == 'y') {
+                       p++;
+                       res = "gost-yescrypt";
+               }
+               break;
+       case '_':
+               res = "bsdicrypt";
                break;
        default:
-               return NULL;
+               res = "unknown";
+               break;
        }
        p++;
 
@@ -648,7 +666,10 @@ static const char *get_pwd_method(const char *str, const char **next, unsigned i
        return res;
 }
 
-#define is_valid_pwd_char(x)   (isalnum((unsigned char) (x)) || (x) ==  '.' || (x) == '/')
+#define is_invalid_pwd_char(x) (isspace((unsigned char) (x)) || \
+                                (x) == ':' || (x) == ';' || (x) == '*' || \
+                                (x) == '!' || (x) == '\\')
+#define is_valid_pwd_char(x)   (isascii((unsigned char) (x)) && !is_invalid_pwd_char(x))
 
 /*
  * This function do not accept empty passwords or locked accouns.
@@ -656,17 +677,16 @@ static const char *get_pwd_method(const char *str, const char **next, unsigned i
 static int valid_pwd(const char *str)
 {
        const char *p = str;
-       unsigned int sz = 0, n;
 
        if (!str || !*str)
                return 0;
 
        /* $id$ */
-       if (get_pwd_method(str, &p, &sz) == NULL)
+       if (get_pwd_method(str, &p) == NULL)
                return 0;
+
        if (!p || !*p)
                return 0;
-
        /* salt$ */
        for (; *p; p++) {
                if (*p == '$') {
@@ -676,17 +696,15 @@ static int valid_pwd(const char *str)
                if (!is_valid_pwd_char(*p))
                        return 0;
        }
+
        if (!*p)
                return 0;
-
        /* encrypted */
-       for (n = 0; *p; p++, n++) {
-               if (!is_valid_pwd_char(*p))
+       for (; *p; p++) {
+               if (!is_valid_pwd_char(*p)) {
                        return 0;
+               }
        }
-
-       if (sz && n != sz)
-               return 0;
        return 1;
 }
 
@@ -869,7 +887,7 @@ static struct lslogins_user *get_user_info(struct lslogins_control *ctl, const c
 
                                while (p && (*p == '!' || *p == '*'))
                                        p++;
-                               user->pwd_method = get_pwd_method(p, NULL, NULL);
+                               user->pwd_method = get_pwd_method(p, NULL);
                        } else
                                user->pwd_method = NULL;
                        break;
@@ -975,7 +993,7 @@ static int get_ulist(struct lslogins_control *ctl, char *logins, char *groups)
                        (*ar)[i++] = xstrdup(u);
 
                        if (i == *arsiz)
-                               *ar = xrealloc(*ar, sizeof(char *) * (*arsiz += 32));
+                               *ar = xreallocarray(*ar, *arsiz += 32, sizeof(char *));
                }
                ctl->ulist_on = 1;
        }
@@ -1000,7 +1018,7 @@ static int get_ulist(struct lslogins_control *ctl, char *logins, char *groups)
                                (*ar)[i++] = xstrdup(u);
 
                                if (i == *arsiz)
-                                       *ar = xrealloc(*ar, sizeof(char *) * (*arsiz += 32));
+                                       *ar = xreallocarray(*ar, *arsiz += 32, sizeof(char *));
                        }
                }
                ctl->ulist_on = 1;
@@ -1013,6 +1031,9 @@ static void free_ctl(struct lslogins_control *ctl)
 {
        size_t n = 0;
 
+       if (!ctl)
+               return;
+
        free(ctl->wtmp);
        free(ctl->btmp);
 
@@ -1449,13 +1470,13 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_("     --btmp-file <path>   set an alternate path for btmp\n"), out);
        fputs(_("     --lastlog <path>     set an alternate path for lastlog\n"), out);
        fputs(USAGE_SEPARATOR, out);
-       printf(USAGE_HELP_OPTIONS(26));
+       fprintf(out, USAGE_HELP_OPTIONS(26));
 
        fputs(USAGE_COLUMNS, out);
        for (i = 0; i < ARRAY_SIZE(coldescs); i++)
                fprintf(out, " %14s  %s\n", coldescs[i].name, _(coldescs[i].help));
 
-       printf(USAGE_MAN_TAIL("lslogins(1)"));
+       fprintf(out, USAGE_MAN_TAIL("lslogins(1)"));
 
        exit(EXIT_SUCCESS);
 }