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