X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=cmds.c;h=08095378529aee15ad159caa62543cd32b854119;hb=4f879ea628d8c88d2b47b36e6be2c2de6e3c9de0;hp=422f52fc35119c5ead0b0becb22cac53f4cbe086;hpb=dbb6799580c29ff7a1cc193f6d8ca3711579a81f;p=betaftpd diff --git a/cmds.c b/cmds.c index 422f52f..0809537 100644 --- a/cmds.c +++ b/cmds.c @@ -2,7 +2,7 @@ Copyright (C) 1999-2000 Steinar H. Gunderson This program is is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License, version 2 if the + it under the terms of the GNU General Public License, version 2 of the License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, @@ -21,14 +21,14 @@ #include #endif -#if HAVE_SYS_TYPES_H -#include -#endif - #if HAVE_STROPTS_H #include #endif +#if HAVE_SYS_TYPES_H +#include +#endif + #if HAVE_SYS_CONF_H #include #endif @@ -77,10 +77,6 @@ #include #endif -#if HAVE_PWD_H -#include -#endif - #if HAVE_GRP_H #include #endif @@ -89,10 +85,6 @@ #include #endif -#if HAVE_SYS_SOCKET_H -#include -#endif - #if HAVE_SYS_STAT_H #include #endif @@ -109,10 +101,6 @@ #include #endif -#if HAVE_NETINET_IN_H -#include -#endif - #if HAVE_SHADOW_H #include #endif @@ -141,6 +129,10 @@ #include #include +#if WANT_DCACHE +#include +#endif + #define lstat stat extern struct conn *first_conn; @@ -317,6 +309,7 @@ int cmd_pass(struct conn * const c) c->auth = 0; } else { c->uid = p->pw_uid; + c->gid = p->pw_gid; strncpy(c->curr_dir, p->pw_dir, 254); c->curr_dir[254] = 0; } @@ -336,7 +329,7 @@ int cmd_pass(struct conn * const c) ) { c->auth = 0; } else { - c->auth = 3; + c->auth = 4; } } #endif /* !WANT_NONROOT */ @@ -352,6 +345,7 @@ int cmd_pass(struct conn * const c) chdir(c->curr_dir); dump_file(c, 230, "welcome.msg"); #endif + /* Have a different message for anonymous users? */ numeric(c, 230, "User logged in."); } return 1; @@ -418,9 +412,11 @@ int cmd_port(struct conn * const c) #if !WANT_NONROOT /* need root privilegies for a short while */ seteuid(getuid()); + setegid(getgid()); #endif bind(sock, (struct sockaddr *)&sin, sizeof(sin)); #if !WANT_NONROOT + setegid(c->gid); seteuid(c->uid); #endif @@ -913,7 +909,7 @@ char conn_state[5][27] = { "Waiting for e-mail address", "Waiting for password", "Logged in", - "Waiting for password", /* actually non-existant user */ + "Logged in", /* non-anonymous */ }; char ftran_state[6][42] = { @@ -1183,30 +1179,17 @@ void do_listing(struct conn * const c, struct list_options * const lo) #if WANT_DCACHE { - struct dcache *d = NULL, *next = first_dcache->next_dcache; - struct stat buf; + struct dcache *d = find_dcache(cwd, ptr, lo); + if (d != NULL) { + d->use_count++; + f->dir_cache = d; + f->file_data = d->dir_data; + f->size = d->dir_size; + f->dir_listing = 1; + f->pos = 0; - if (stat(cwd, &buf) > -1) { - /* run through the linked list */ - while (next != NULL) { - d = next; - next = d->next_dcache; - - if (buf.st_mtime <= d->generated && - strcmp(d->dir_name, cwd) == 0 && - strcmp(d->pattern, ptr) == 0 && - memcmp(&(d->lo), lo, - sizeof(struct list_options)) == 0) { - d->use_count++; - f->dir_cache = d; - f->file_data = d->dir_data; - f->size = d->dir_size; - f->dir_listing = 1; - f->pos = 0; - prepare_for_transfer(f); - return; - } - } + prepare_for_transfer(f); + return; } } #endif @@ -1226,23 +1209,7 @@ void do_listing(struct conn * const c, struct list_options * const lo) #endif #if WANT_DCACHE - /* populate the directory listing cache */ - { - struct stat buf; - struct dcache *d = alloc_new_dcache(); - if (d != NULL && stat(cwd, &buf) > -1) { - d->use_count++; - f->dir_cache = d; - d->dir_data = f->file_data; - d->dir_size = f->size; - d->generated = buf.st_mtime; - - strcpy(d->dir_name, cwd); - strncpy(d->pattern, ptr, 255); - d->pattern[255] = 0; - d->lo = *lo; - } - } + populate_dcache(f, cwd, ptr, lo); #endif #if HAVE_MMAP @@ -1294,6 +1261,8 @@ int get_num_files(struct conn * const c, const char * const pathname, } } + globfree(&pglob); + return num_files; } @@ -1590,7 +1559,7 @@ int cmd_rein(struct conn * const c) * down without clearing any sockets etc. In other words: * Don't use it on a production site. */ -void cmd_exit(struct conn * const c) +int cmd_exit(struct conn * const c) { while (first_conn->next_conn) destroy_conn(first_conn->next_conn); @@ -1640,9 +1609,11 @@ void parse_command(struct conn *c) #if !WANT_NONROOT if (h->do_setuid) { + setegid(c->gid); seteuid(c->uid); } else { - seteuid(0); + seteuid(getuid()); + setegid(getgid()); } #endif @@ -1660,7 +1631,10 @@ void parse_command(struct conn *c) if (h->callback(c)) { c->recv_buf[cmlen] = schar; #if !WANT_NONROOT - if (h->do_setuid) seteuid(getuid()); + if (h->do_setuid) { + seteuid(getuid()); + setegid(getgid()); + } #endif remove_bytes(c, cmlen); } @@ -1871,7 +1845,7 @@ int prepare_for_listing(struct conn * const c, char ** const ptr, case 'F': lo->classify = 1; break; - case ' ': + case '\0': fptr = optr + 1; *(optr--) = 0; break; @@ -1882,7 +1856,7 @@ int prepare_for_listing(struct conn * const c, char ** const ptr, } else { fptr = c->recv_buf; } - + /* then we chdir to the dir in fptr (if any) */ tmp = fptr ? strrchr(fptr, '/') : NULL; if (tmp != NULL) { @@ -1895,7 +1869,16 @@ int prepare_for_listing(struct conn * const c, char ** const ptr, } /* if no argument, choose all files */ - if (fptr == NULL || fptr[0] == 0) fptr = "*"; + if (fptr == NULL || fptr[0] == 0) { + fptr = "*"; + } else { + /* we need to check if the last part is a directory (no -d switch) */ + struct stat buf; + if (stat(fptr, &buf) == 0 && S_ISDIR(buf.st_mode)) { + TRAP_ERROR(chdir(fptr) == -1, 550, return -1); + fptr = "*"; + } + } *ptr = fptr; #if WANT_NONROOT