1 #include "config.h"
2 #include <stdio.h>
3 #ifdef HAVE_CRYPT_H
4 # include <crypt.h>
5 #endif
6 #include <string.h>
7 #include <errno.h>
8 #include <signal.h>
9 #include <unistd.h>
10 #ifdef HAVE_SYS_TIME_H
11 # include <sys/time.h>
12 #endif
13 #include <time.h>
14 #include <stdlib.h>
15 #include <limits.h>
16
17 #include "mystring.h"
18 #include "options.h"
19 #include "commands.h"
20 #include "logging.h"
21 #include "bftpdutmp.h"
22 #include "login.h"
23
24 FILE *mystatuslog;
25
loginfailed()26 void loginfailed()
27 {
28 control_printf(SL_FAILURE, "421 Login incorrect.");
29 bftpd_log("Administrative login FAILED\n");
30 exit(1);
31 }
32
command_adminlogin(char * params)33 void command_adminlogin(char *params)
34 {
35 char adminpass[31];
36 char rootpass[31];
37 char buffer[256];
38 char *realadminpass = config_getoption("ADMIN_PASS");
39 if (sscanf(params, "%30s %30s", adminpass, rootpass) < 2)
40 loginfailed();
41 if (!realadminpass[0])
42 loginfailed();
43 if (strcmp(crypt(adminpass, realadminpass), realadminpass))
44 loginfailed();
45 /* Admin password is right */
46 strcpy(user, "root");
47 init_userinfo();
48 if (checkpass(rootpass))
49 loginfailed();
50 /* Root password is right as well */
51 signal(SIGALRM, SIG_IGN);
52 control_printf(SL_SUCCESS, "230 Administrative login successful.");
53 bftpd_log("Administrative login SUCCESSFUL\n");
54 while (fgets(buffer, sizeof(buffer), stdin)) {
55 admin_parsecmd(buffer);
56 }
57 exit(0);
58 }
59
command_admingetconf(char * params)60 void command_admingetconf(char *params)
61 {
62 control_printf(SL_FAILURE, "500 Not implemented yet.");
63 }
64
command_adminlog(char * params)65 void command_adminlog(char *params)
66 {
67 fd_set rfds;
68 struct timeval tv;
69 char buffer[256];
70 control_printf(SL_SUCCESS, "200 Starting logfile transmission.");
71 mystatuslog = statuslogforreading;
72 fseek(mystatuslog, 0, SEEK_END);
73 while (mystatuslog) {
74 while (fgets(buffer, sizeof(buffer), mystatuslog))
75 /* Don't use control_printf here, as it would generate an infinite loop */
76 fprintf(stderr, "%s", buffer);
77 FD_ZERO(&rfds);
78 FD_SET(0, &rfds);
79 tv.tv_sec = 1;
80 tv.tv_usec = 0;
81 if (select(1, &rfds, NULL, NULL, &tv) > 0) {
82 if (!fgets(buffer, sizeof(buffer), stdin))
83 exit(0);
84 admin_parsecmd(buffer);
85 }
86 }
87 control_printf(SL_SUCCESS, "202 Logfile transmission stopped.");
88 }
89
command_adminstoplog(char * params)90 void command_adminstoplog(char *params)
91 {
92 mystatuslog = NULL;
93 control_printf(SL_SUCCESS, "201 Stopping logfile transmission.");
94 }
95
command_adminwho(char * params)96 void command_adminwho(char *params)
97 {
98 struct bftpdutmp tmp;
99 fprintf(stderr, "200-User listing follows.\n");
100 fprintf(stderr, "200-PID User Host Login time\n");
101 rewind(bftpdutmp);
102 while (fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp)) {
103 if (!tmp.bu_type)
104 continue;
105 fprintf(stderr, "200-%-10i%-15s%-20s%s", tmp.bu_pid, tmp.bu_name, tmp.bu_host,
106 ctime(&(tmp.bu_time)));
107 }
108 fprintf(stderr, "200 User listing finished.\n");
109 }
110
command_adminkick(char * strpid)111 void command_adminkick(char *strpid)
112 {
113 unsigned long int get_pid = strtoul(strpid, NULL, 10);
114 int pid;
115
116 if (get_pid <= INT_MAX)
117 pid = get_pid;
118 else
119 pid = 0;
120
121 if (!pid)
122 control_printf(SL_FAILURE, "500 Error: Given PID is not valid.");
123 else if (bftpdutmp_pidexists(pid)) {
124 if (kill(pid, SIGTERM))
125 control_printf(SL_FAILURE, "500 Error: %s.", strerror(errno));
126 else
127 control_printf(SL_FAILURE, "200 OK");
128 } else
129 control_printf(SL_FAILURE, "500 Error: The given PID does not belong to bftpd.");
130 }
131
command_adminquit(char * params)132 void command_adminquit(char *params)
133 {
134 control_printf(SL_SUCCESS, "221 See you later...");
135 exit(0);
136 }
137
138 const struct admin_command admin_commands[] = {
139 {"ADMIN_GETCONF", command_admingetconf},
140 {"ADMIN_LOG", command_adminlog},
141 {"ADMIN_STOPLOG", command_adminstoplog},
142 {"ADMIN_WHO", command_adminwho},
143 {"ADMIN_KICK", command_adminkick},
144 {"ADMIN_QUIT", command_adminquit},
145 {NULL, NULL}
146 };
147
admin_parsecmd(char * str)148 int admin_parsecmd(char *str)
149 {
150 int i;
151 char *p, *pp;
152 int string_length;
153 string_length = strlen(str) - 2;
154 if (string_length < 0) string_length = 0;
155 str[string_length] = '\0'; /* Remove \r\n */
156 p = pp = str; /* Remove garbage in the string */
157 while (*p)
158 if ((unsigned char) *p < 32)
159 p++;
160 else
161 *pp++ = *p++;
162 *pp++ = 0;
163 for (i = 0; admin_commands[i].name; i++) { /* Parse command */
164 if (!strncasecmp(str, admin_commands[i].name, strlen(admin_commands[i].name))) {
165 cutto(str, strlen(admin_commands[i].name));
166 p = str;
167 while ((*p) && ((*p == ' ') || (*p == '\t')))
168 p++;
169 memmove(str, p, strlen(str) - (p - str) + 1);
170 admin_commands[i].function(str);
171 return 0;
172 }
173 }
174 control_printf(SL_FAILURE, "500 Unknown command: \"%s\"", str);
175 return 1;
176 }
177