Began setting up a second server socket that will be used exclusively for admin utilities
[citadel.git] / citadel / utils / chkpw.c
1 /* 
2  *
3  *
4  * Copyright (c) 1987-2009 by the citadel.org team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <errno.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <signal.h>
27 #include <pwd.h>
28 #include <ctype.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <limits.h>
35 #include <dirent.h>
36
37
38 #include "citadel.h"
39 #include "sysdep.h"
40 #include "citadel_dirs.h"
41 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
42 int chkpwd_write_pipe[2];
43 int chkpwd_read_pipe[2];
44
45 /*
46  * Validate a password on the host unix system by talking to the chkpwd daemon
47  */
48 static int validpw(uid_t uid, const char *pass)
49 {
50         char buf[256];
51         int rv;
52
53         rv = write(chkpwd_write_pipe[1], &uid, sizeof(uid_t));
54         if (rv == -1) {
55                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
56                 return 0;
57         }
58
59         rv = write(chkpwd_write_pipe[1], pass, 256);
60         if (rv == -1) {
61                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
62                 return 0;
63         }
64         rv = read(chkpwd_read_pipe[0], buf, 4);
65         if (rv == -1) {
66                 printf( "Communicatino with chkpwd broken: %s\n", strerror(errno));
67                 return 0;
68         }
69         if (!strncmp(buf, "PASS", 4)) {
70                 printf("pass\n");
71                 return(1);
72         }
73
74         printf("fail\n");
75         return 0;
76 }
77
78 /* 
79  * Start up the chkpwd daemon so validpw() has something to talk to
80  */
81 void start_chkpwd_daemon(void) {
82         pid_t chkpwd_pid;
83         struct stat filestats;
84         int i;
85
86         printf("Starting chkpwd daemon for host authentication mode\n");
87
88         if ((stat(file_chkpwd, &filestats)==-1) ||
89             (filestats.st_size==0)){
90                 printf("didn't find chkpwd daemon in %s: %s\n", file_chkpwd, strerror(errno));
91                 abort();
92         }
93         if (pipe(chkpwd_write_pipe) != 0) {
94                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
95                 abort();
96         }
97         if (pipe(chkpwd_read_pipe) != 0) {
98                 printf("Unable to create pipe for chkpwd daemon: %s\n", strerror(errno));
99                 abort();
100         }
101
102         chkpwd_pid = fork();
103         if (chkpwd_pid < 0) {
104                 printf("Unable to fork chkpwd daemon: %s\n", strerror(errno));
105                 abort();
106         }
107         if (chkpwd_pid == 0) {
108                 dup2(chkpwd_write_pipe[0], 0);
109                 dup2(chkpwd_read_pipe[1], 1);
110                 for (i=2; i<256; ++i) close(i);
111                 execl(file_chkpwd, file_chkpwd, NULL);
112                 printf("Unable to exec chkpwd daemon: %s\n", strerror(errno));
113                 abort();
114                 exit(errno);
115         }
116 }
117
118
119
120 int main(int argc, char **argv) {
121         char buf[256];
122         struct passwd *p;
123         int uid;
124         char ctdldir[PATH_MAX]=CTDLDIR;
125         char *ptr = NULL;
126         
127         calc_dirs_n_files(0,0,"", ctdldir, 0);
128         
129         printf("\n\n ** host auth mode test utility **\n\n");
130         start_chkpwd_daemon();
131
132         if (getuid() != 0){
133                 printf("\n\nERROR: you need to be root to run this!\n\n");
134                 return(1);
135         }
136         while(1) {
137                 printf("\n\nUsername: ");
138                 ptr = fgets(buf, sizeof buf, stdin);
139                 buf[strlen(buf)-1] = 0;
140                 p = getpwnam(buf);
141                 if (p == NULL) {
142                         printf("Not found\n");
143                 }
144                 else {
145                         uid = p->pw_uid;
146                         printf("     uid: %d\n", uid);
147                         printf("Password: ");
148                         ptr = fgets(buf, sizeof buf, stdin);
149                         buf[strlen(buf)-1] = 0;
150                         validpw(uid, buf);
151                 }
152         }
153
154         return(0);
155 }