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