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