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