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 *) &current, 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(&current, 0, sizeof(current));
197            fwrite( (void *) &current, sizeof(current), 1, bftpdutmp);
198        }
199        index++;
200     }
201 }
202 
203 
204