ff856cddc6bd86d655d7b63930d2145752488f66
[citadel.git] / citadel / chkpw.c
1 /* 
2  *
3  */
4
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <fcntl.h>
10 #include <signal.h>
11 #include <pwd.h>
12 #include <ctype.h>
13 #include <sys/types.h>
14 #include <sys/wait.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <limits.h>
19 #include <dirent.h>
20
21
22 #include "citadel.h"
23 #include "sysdep.h"
24 #include "citadel_dirs.h"
25 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
26 int chkpwd_write_pipe[2];
27 int chkpwd_read_pipe[2];
28
29 /*
30  * Validate a password on the host unix system by talking to the chkpwd daemon
31  */
32 static int validpw(uid_t uid, const char *pass)
33 {
34         char buf[256];
35
36         write(chkpwd_write_pipe[1], &uid, sizeof(uid_t));
37         write(chkpwd_write_pipe[1], pass, 256);
38         read(chkpwd_read_pipe[0], buf, 4);
39
40         if (!strncmp(buf, "PASS", 4)) {
41                 printf("pass\n");
42                 return(1);
43         }
44
45         printf("fail\n");
46         return 0;
47 }
48
49 /* 
50  * Start up the chkpwd daemon so validpw() has something to talk to
51  */
52 void start_chkpwd_daemon(void) {
53         pid_t chkpwd_pid;
54         struct stat filestats;
55         int i;
56
57         printf("Starting chkpwd daemon for host authentication mode\n");
58
59         if ((stat(file_chkpwd, &filestats)==-1) ||
60             (filestats.st_size==0)){
61                 printf("didn't find chkpwd daemon in %s: %s\n", file_chkpwd, strerror(errno));
62                 abort();
63         }
64         if (pipe(chkpwd_write_pipe) != 0) {
65                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
66                 abort();
67         }
68         if (pipe(chkpwd_read_pipe) != 0) {
69                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
70                 abort();
71         }
72
73         chkpwd_pid = fork();
74         if (chkpwd_pid < 0) {
75                 printf("Unable to fork chkpwd daemon: %s\n", strerror(errno));
76                 abort();
77         }
78         if (chkpwd_pid == 0) {
79                 dup2(chkpwd_write_pipe[0], 0);
80                 dup2(chkpwd_read_pipe[1], 1);
81                 for (i=2; i<256; ++i) close(i);
82                 execl(file_chkpwd, file_chkpwd, NULL);
83                 printf("Unable to exec chkpwd daemon: %s\n", strerror(errno));
84                 abort();
85                 exit(errno);
86         }
87 }
88
89
90
91 int main(int argc, char **argv) {
92         char buf[256];
93         struct passwd *p;
94         int uid;
95         char ctdldir[PATH_MAX]=CTDLDIR;
96         
97         calc_dirs_n_files(0,0,"", ctdldir, 0);
98         
99         printf("\n\n ** host auth mode test utility **\n\n");
100         start_chkpwd_daemon();
101
102         if (getuid() != 0){
103                 printf("\n\nERROR: you need to be root to run this!\n\n");
104                 return(1);
105         }
106         while(1) {
107                 printf("\n\nUsername: ");
108                 fgets(buf, sizeof buf, stdin);
109                 buf[strlen(buf)-1] = 0;
110                 p = getpwnam(buf);
111                 if (p == NULL) {
112                         printf("Not found\n");
113                 }
114                 else {
115                         uid = p->pw_uid;
116                         printf("     uid: %d\n", uid);
117                         printf("Password: ");
118                         fgets(buf, sizeof buf, stdin);
119                         buf[strlen(buf)-1] = 0;
120                         validpw(uid, buf);
121                 }
122         }
123
124         return(0);
125 }