commit 77a2f9f92c41ca78da37b4bf576ca5612883b16d
parent 1abf7518ada8a2b977cac0b97bd47da2aeb2f2d2
Author: sin <sin@2f30.org>
Date: Mon, 9 Jun 2014 10:51:02 +0100
Add initial pw_check()
Diffstat:
M | passwd.h | | | 3 | ++- |
M | 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;
-}