1 #include <stdio.h>
2 #include <string.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <time.h>
8
9 #include "main.h"
10 #include "bftpdutmp.h"
11 #include "mypaths.h"
12 #include "logging.h"
13 #include "options.h"
14
15 FILE *bftpdutmp = NULL;
16 long bftpdutmp_offset = 0xFFFFFFFF;
17
bftpdutmp_create_dir(char * path_to_file)18 void bftpdutmp_create_dir(char *path_to_file)
19 {
20 char *dir_name, *index;
21
22 if (! path_to_file) return;
23
24 dir_name = strdup(path_to_file);
25 if (! dir_name)
26 return;
27
28 index = strrchr(dir_name, '/');
29 if (index)
30 {
31 index[0] = '\0'; /* wipe out everything after folder name */
32 mkdir(dir_name, 0755);
33 }
34 free(dir_name);
35 }
36
37
38
bftpdutmp_init()39 void bftpdutmp_init()
40 {
41 char *filename = strdup(config_getoption("PATH_BFTPDUTMP"));
42
43 if (! filename)
44 return;
45
46 if ((!strcasecmp(filename, "none")) || (!filename[0]))
47 {
48 free(filename);
49 return;
50 }
51
52 /* try to create the directory, if it does not exist yet */
53 bftpdutmp_create_dir(filename);
54
55 /* we have to create the file if it doesn't exist */
56 bftpdutmp = fopen(filename, "a");
57 if (bftpdutmp)
58 fclose(bftpdutmp);
59 /* Then we can open it for reading and writing */
60 if (!(bftpdutmp = fopen(filename, "r+"))) {
61 bftpd_log("Could not open log file %s.\n", filename);
62 control_printf(SL_FAILURE, "421-Could not open file %s\r\n"
63 "421 Server disabled for security reasons.", filename);
64 exit(1);
65 }
66 rewind(bftpdutmp);
67 // clean up memory
68 free(filename);
69 }
70
bftpdutmp_end()71 void bftpdutmp_end()
72 {
73 if (bftpdutmp) {
74 if (bftpdutmp_offset != -1)
75 bftpdutmp_log(0);
76 fclose(bftpdutmp);
77 bftpdutmp = NULL;
78 }
79 }
80
bftpdutmp_log(char type)81 void bftpdutmp_log(char type)
82 {
83 struct bftpdutmp ut, tmp;
84 long i;
85 int max_length;
86
87 if (!bftpdutmp)
88 return;
89 memset((void *) &ut, 0, sizeof(ut));
90 ut.bu_pid = getpid();
91 if (type) {
92 ut.bu_type = 1;
93 strncpy(ut.bu_name, user, sizeof(ut.bu_name));
94 max_length = sizeof(ut.bu_host);
95 strncpy(ut.bu_host, remotehostname, max_length);
96 ut.bu_host[max_length - 1] = '\0'; /* avoid non-null terminated string */
97 /* Determine offset of first user marked dead */
98 rewind(bftpdutmp);
99 i = 0;
100 while (fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp)) {
101 if (!tmp.bu_type)
102 break;
103 i++;
104 }
105 bftpdutmp_offset = i * sizeof(tmp);
106 }
107
108 else
109 ut.bu_type = 0;
110
111 time(&(ut.bu_time));
112 fseek(bftpdutmp, bftpdutmp_offset, SEEK_SET);
113 fwrite((void *) &ut, sizeof(ut), 1, bftpdutmp);
114 fflush(bftpdutmp);
115 }
116
bftpdutmp_pidexists(pid_t pid)117 char bftpdutmp_pidexists(pid_t pid)
118 {
119 struct bftpdutmp tmp;
120 if (!bftpdutmp)
121 return 0;
122 rewind(bftpdutmp);
123 while (fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp)) {
124 if ((tmp.bu_pid == pid) && (tmp.bu_type))
125 return 1;
126 }
127 return 0;
128 }
129
bftpdutmp_usercount(char * username)130 int bftpdutmp_usercount(char *username)
131 {
132 struct bftpdutmp tmp;
133 int count = 0;
134 if (!bftpdutmp)
135 return 0;
136 rewind(bftpdutmp);
137 while ( fread((void *) &tmp, sizeof(tmp), 1, bftpdutmp) ) {
138 /*
139 Took this out. It seems to just be taking up log space. -- Jesse
140 bftpd_log("bu_name=%s; username=%s, bu_type=%i\n", tmp.bu_name, username, tmp.bu_type);
141 */
142 if (tmp.bu_type && ( !strcmp(tmp.bu_name, username) || !strcmp(username, "*")))
143 count++;
144 }
145
146 if (count < 0)
147 count = 1;
148 return count;
149 }
150
bftpdutmp_dup_ip_count(char * ip_address)151 int bftpdutmp_dup_ip_count(char *ip_address)
152 {
153 struct bftpdutmp tmp;
154 int count = 0;
155
156 if (! bftpdutmp)
157 return 0;
158
159 rewind(bftpdutmp);
160 while ( fread( (void *) &tmp, sizeof(tmp), 1, bftpdutmp) )
161 {
162 if (tmp.bu_type && (! strcmp(tmp.bu_host, ip_address) ) )
163 count++;
164 }
165
166 return count;
167 }
168
169
170
171 /*
172 This function removes a log entry of
173 a dead client. This is called
174 when the bftpd parent catches a
175 signal indicating the child/client died.
176 This makes it look like the child
177 logged out properly.
178 -- Jesse
179 */
bftpdutmp_remove_pid(int pid)180 void bftpdutmp_remove_pid(int pid)
181 {
182 struct bftpdutmp current;
183 int index = 0;
184
185 if (! bftpdutmp)
186 return;
187
188 rewind(bftpdutmp);
189 /* search for a matching pid */
190 while ( fread( (void *) ¤t, sizeof(current), 1, bftpdutmp) )
191 {
192 /* over-write the pid */
193 if ( current.bu_pid == pid )
194 {
195 fseek(bftpdutmp, index * sizeof(current), SEEK_SET);
196 memset(¤t, 0, sizeof(current));
197 fwrite( (void *) ¤t, sizeof(current), 1, bftpdutmp);
198 }
199 index++;
200 }
201 }
202
203
204