142 lines
4.4 KiB
Diff
142 lines
4.4 KiB
Diff
* Case insensitive lookup patch for atftpd
|
|
*
|
|
* Copyright (c) 2006-2007 Gianluigi Tiesi <sherpya@netfarm.it>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this software; if not, write to the
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
diff -Nur atftp-0.7.dfsg.orig/tftpd.c atftp-0.7.dfsg/tftpd.c
|
|
--- atftp-0.7.dfsg.orig/tftpd.c 2007-12-09 06:06:20.000000000 +0100
|
|
+++ atftp-0.7.dfsg/tftpd.c 2007-12-09 06:08:51.229707272 +0100
|
|
@@ -667,6 +667,15 @@
|
|
switch (retval)
|
|
{
|
|
case GET_RRQ:
|
|
+ if (data->tftp_options[OPT_FILENAME].value[0] == '\\')
|
|
+ if (!tftpd_lookup_file(directory, data->tftp_options[OPT_FILENAME].value))
|
|
+ {
|
|
+ /* Short circuit */
|
|
+ tftp_send_error(data->sockfd, &data->client_info->client,
|
|
+ ENOTFOUND, data->data_buffer, data->data_buffer_size);
|
|
+ stats_err_locked();
|
|
+ break;
|
|
+ }
|
|
logger(LOG_NOTICE, "Serving %s to %s:%d",
|
|
data->tftp_options[OPT_FILENAME].value,
|
|
inet_ntoa(data->client_info->client.sin_addr),
|
|
diff -Nur atftp-0.7.dfsg.orig/tftpd.h atftp-0.7.dfsg/tftpd.h
|
|
--- atftp-0.7.dfsg.orig/tftpd.h 2004-02-27 03:05:26.000000000 +0100
|
|
+++ atftp-0.7.dfsg/tftpd.h 2007-12-09 06:06:35.319368784 +0100
|
|
@@ -77,6 +77,7 @@
|
|
/*
|
|
* Functions defined in tftpd_file.c
|
|
*/
|
|
+int tftpd_lookup_file(const char *directory, char *filename);
|
|
int tftpd_rules_check(char *filename);
|
|
int tftpd_receive_file(struct thread_data *data);
|
|
int tftpd_send_file(struct thread_data *data);
|
|
diff -Nur atftp-0.7.dfsg.orig/tftpd_file.c atftp-0.7.dfsg/tftpd_file.c
|
|
--- atftp-0.7.dfsg.orig/tftpd_file.c 2004-02-18 03:21:47.000000000 +0100
|
|
+++ atftp-0.7.dfsg/tftpd_file.c 2007-12-09 06:09:23.683773504 +0100
|
|
@@ -27,6 +27,7 @@
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
+#include <dirent.h>
|
|
#include <sys/stat.h>
|
|
#include "tftpd.h"
|
|
#include "tftp_io.h"
|
|
@@ -60,6 +61,81 @@
|
|
extern tftpd_pcre_self_t *pcre_top;
|
|
#endif
|
|
|
|
+/*
|
|
+ * Case insensitive file lookup, for windows clients
|
|
+ */
|
|
+
|
|
+int tftpd_lookup_entry(const char *comp, char *dest)
|
|
+{
|
|
+ DIR *dirp;
|
|
+ struct dirent *dptr;
|
|
+ dirp = opendir(dest);
|
|
+ if (!dirp) return 0;
|
|
+ while ((dptr = readdir(dirp)))
|
|
+ {
|
|
+ if (!strcasecmp(dptr->d_name, comp))
|
|
+ {
|
|
+ strcat(dest, "/");
|
|
+ strcat(dest, dptr->d_name);
|
|
+ closedir(dirp);
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ closedir(dirp);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int tftpd_lookup_file(const char *directory, char *filename)
|
|
+{
|
|
+ int found = 0;
|
|
+ int len = 0;
|
|
+ char dest[MAXLEN];
|
|
+ char comp[MAXLEN];
|
|
+ char *check = filename;
|
|
+ char *seek = NULL;
|
|
+
|
|
+ dest[0] = 0;
|
|
+ strcat(dest, directory);
|
|
+ len = strlen(dest);
|
|
+ if (dest[len-1] == '/')
|
|
+ dest[len-1] = 0;
|
|
+ check++;
|
|
+ while (*check)
|
|
+ {
|
|
+ seek = strchr(check, '\\');
|
|
+ if (!seek)
|
|
+ {
|
|
+ if ((*check) && (tftpd_lookup_entry(check, dest)))
|
|
+ found = 1;
|
|
+ break;
|
|
+ }
|
|
+ len = seek - check;
|
|
+ memcpy(comp, check, len);
|
|
+ comp[len]=0;
|
|
+ if (!tftpd_lookup_entry(comp, dest))
|
|
+ break;
|
|
+ check += len + 1;
|
|
+ }
|
|
+
|
|
+ if (found)
|
|
+ {
|
|
+ filename[0] = 0;
|
|
+ strcat(filename, dest + strlen(directory));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ seek = filename;
|
|
+ while (*seek)
|
|
+ {
|
|
+ if (*seek == '\\') *seek = '/';
|
|
+ seek++;
|
|
+ }
|
|
+ filename++;
|
|
+ }
|
|
+
|
|
+ logger(LOG_DEBUG, "Filecase lookup file: %s (found %s)", filename, (found ? "yes" : "no"));
|
|
+ return found;
|
|
+}
|
|
|
|
/*
|
|
* Rules for filenames. This is common to both tftpd_recieve_file
|