ubase

suckless linux base utils
git clone git://git.2f30.org/ubase.git
Log | Files | Refs | README | LICENSE

commit 77a2f9f92c41ca78da37b4bf576ca5612883b16d
parent 1abf7518ada8a2b977cac0b97bd47da2aeb2f2d2
Author: sin <sin@2f30.org>
Date:   Mon Jun  9 10:51:02 +0100

Add initial pw_check()

Diffstat:
passwd.h | 3++-
util/passwd.c | 137++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
2 files changed, 92 insertions(+), 48 deletions(-)
diff --git a/passwd.h b/passwd.h @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ /* passwd.c */ -int pw_scan(char *, struct passwd *); +int pw_check(struct passwd *, const char *); int pw_copy(int, int, const struct passwd *); +int pw_scan(char *, struct passwd *); diff --git a/util/passwd.c b/util/passwd.c @@ -1,12 +1,102 @@ /* See LICENSE file for copyright and license details. */ +#include <errno.h> #include <pwd.h> +#include <shadow.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include "../passwd.h" #include "../text.h" #include "../util.h" int +pw_check(struct passwd *pw, const char *pass) +{ + char *cryptpass, *p; + struct spwd *spw; + + p = pw->pw_passwd; + switch (pw->pw_passwd[0]) { + case '!': + case '*': + eprintf("denied\n"); + } + + if (pw->pw_passwd[0] == '\0') + return 1; + + if (pw->pw_passwd[0] == 'x' && pw->pw_passwd[1] == '\0') { + errno = 0; + spw = getspnam(pw->pw_name); + if (errno) + eprintf("getspnam: %:", pw->pw_name); + else if (!spw) + eprintf("who are you?\n"); + switch (spw->sp_pwdp[0]) { + case '!': + case '*': + eprintf("denied\n"); + } + p = spw->sp_pwdp; + } + + cryptpass = crypt(pass, p); + if (!cryptpass) + eprintf("crypt:"); + if (strcmp(cryptpass, p) != 0) + return 0; + return 1; +} + +int +pw_copy(int ffd, int tfd, const struct passwd *newpw) +{ + struct passwd pw; + char *buf = NULL, *p; + size_t size = 0; + FILE *from, *to; + + from = fdopen(ffd, "r"); + if (!from) { + weprintf("fdopen:"); + return -1; + } + to = fdopen(tfd, "w"); + if (!to) { + weprintf("fdopen:"); + return -1; + } + while (agetline(&buf, &size, from) != -1) { + p = strdup(buf); + if (!p) { + weprintf("strdup:"); + return -1; + } + if (newpw) { + if (pw_scan(p, &pw) < 0) + return -1; + if (strcmp(pw.pw_name, newpw->pw_name) == 0) { + fprintf(to, "%s:%s:%u:%u:%s:%s:%s\n", + newpw->pw_name, + newpw->pw_passwd, + newpw->pw_uid, + newpw->pw_gid, + newpw->pw_gecos, + newpw->pw_dir, + newpw->pw_shell); + continue; + } + } + fprintf(to, "%s", buf); + free(p); + } + fflush(to); + free(buf); + return 0; +} + +int pw_scan(char *bp, struct passwd *pw) { char *p; @@ -65,50 +155,3 @@ corrupt: weprintf("corrupted passwd entry\n"); return -1; } - -int -pw_copy(int ffd, int tfd, const struct passwd *newpw) -{ - struct passwd pw; - char *buf = NULL, *p; - size_t size = 0; - FILE *from, *to; - - from = fdopen(ffd, "r"); - if (!from) { - weprintf("fdopen:"); - return -1; - } - to = fdopen(tfd, "w"); - if (!to) { - weprintf("fdopen:"); - return -1; - } - while (agetline(&buf, &size, from) != -1) { - p = strdup(buf); - if (!p) { - weprintf("strdup:"); - return -1; - } - if (newpw) { - if (pw_scan(p, &pw) < 0) - return -1; - if (strcmp(pw.pw_name, newpw->pw_name) == 0) { - fprintf(to, "%s:%s:%u:%u:%s:%s:%s\n", - newpw->pw_name, - newpw->pw_passwd, - newpw->pw_uid, - newpw->pw_gid, - newpw->pw_gecos, - newpw->pw_dir, - newpw->pw_shell); - continue; - } - } - fprintf(to, "%s", buf); - free(p); - } - fflush(to); - free(buf); - return 0; -}