source: TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_cd.c @ 987

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/trunk/src/bbftp-server-3.2.0/bbftpd/bbftpd_cd.c@987
Revision 987, 5.4 KB checked in by spascoe, 13 years ago (diff)

Closer inspection of the bbftp code reveals I'll need to refactor the
authz interface slightly. bbftpd_private_authz has been renamed
bbftpd_private_authz_control with a slightly different prototype.
This function now doesn't authorise store/retrieve requests.

Line 
1/*
2 * bbftpd/bbftpd_cd.c
3 * Copyright (C) 1999, 2000, 2001, 2002 IN2P3, CNRS
4 * bbftp@in2p3.fr
5 * http://doc.in2p3.fr/bbftp
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 */ 
21
22/****************************************************************************
23
24 
25 RETURN:
26        0  Keep the connection open (does not mean that the directory has been
27           successfully created)
28        -1 Tell the calling program to close the connection
29 
30 bbftpd_cd.c    v 2.0.0 2001/02/12  - Creation of the routine.
31                v 2.0.1 2001/04/23  - Correct indentation
32                v 2.1.0 2001/06/01  - Change routine name
33                                     
34 *****************************************************************************/
35#include <bbftpd.h>
36
37#include <errno.h>
38#include <fcntl.h>
39#include <netinet/in.h>
40#include <stdio.h>
41#include <syslog.h>
42#include <sys/stat.h>
43#include <sys/types.h>
44#include <unistd.h>
45#include <utime.h>
46#if HAVE_STRING_H
47# include <string.h>
48#endif
49
50#include <common.h>
51#include <daemon.h>
52#include <daemon_proto.h>
53#include <structures.h>
54
55extern int transferoption ;
56extern int recvcontrolto ;
57int bbftpd_cd(int sock,int msglen) 
58{
59
60    char    *buffer ;
61    int        savederrno ;
62    char    *logmessage ;
63    struct  mess_dir *msg_dir ;
64    char    *dirname ;
65
66    if ( (buffer = (char *) malloc (msglen+1) ) == NULL ) {
67         syslog(BBFTPD_ERR,"Unable to malloc space for directory name (%d)",msglen) ;
68         reply(MSG_BAD,"Unable to malloc space for directory name") ;
69        return 0 ;
70    }
71    if ( (logmessage = (char *) malloc (msglen+1024) ) == NULL ) {
72         syslog(BBFTPD_ERR,"Unable to malloc space for logmessage ") ;
73         reply(MSG_BAD,"Unable to malloc space for logmessage") ;
74        FREE(buffer) ;
75        return 0 ;
76    }
77    /*
78    ** Read the characteristics of the directory
79    */
80    if ( readmessage(sock,buffer,msglen,recvcontrolto) < 0 ) {
81        /*
82        ** Error ...
83        */
84        syslog(BBFTPD_ERR,"Error reading directory name") ;
85        FREE(buffer) ;
86        FREE(logmessage) ;
87        return -1 ;
88    }
89    /*
90    ** buffer contains the directory to create
91    */
92    buffer[msglen] = '\0' ;
93    msg_dir = (struct mess_dir *) buffer ;
94     transferoption  = msg_dir->transferoption ;
95    dirname = msg_dir->dirname ;
96
97#ifdef NDG_AUTH
98    if (bbftpd_private_authz_control(MSG_CHDIR_V2, msg_dir->transferoption, msg_dir->dirname,
99                                     logmessage) != 0) {
100      syslog(BBFTPD_ERR, logmessage);
101      reply(MSG_BAD, logmessage);
102      FREE(logmessage);
103      FREE(buffer);
104      return 0;
105    }
106#endif // NDG_AUTH
107   
108    if ( (transferoption & TROPT_RFIO) == TROPT_RFIO ) {
109        syslog(BBFTPD_ERR,"Changing directory is not allowed under RFIO") ;
110        sprintf(logmessage,"Changing directory is not allowed under RFIO") ;
111        reply(MSG_BAD_NO_RETRY,logmessage) ;
112        FREE(logmessage) ;
113        FREE(buffer) ;
114        return 0 ;
115    }
116    syslog(BBFTPD_DEBUG,"Changing directory to %s",dirname) ;
117    /*
118    ** We change the directory
119    */
120    if ( chdir(dirname) < 0 ) {
121        /*
122        ** Depending on errno we are going to tell the client to
123        ** retry or not
124        */
125        savederrno = errno ;
126        sprintf(logmessage,"Error changing directory %s : %s ",dirname,strerror(errno)) ;
127        syslog(BBFTPD_ERR,"Error changing directory %s : %s",dirname,strerror(errno)) ;
128        /*
129        ** We tell the client not to retry in the following case (even in waiting
130        ** WAITRETRYTIME the problem will not be solved) :
131        **        EACCES        : Search permission denied
132        **        ELOOP        : To many symbolic links on path
133        **        ENAMETOOLONG: Path argument too long
134        **        ENOTDIR        : A component in path is not a directory
135        **        ENOENT      : A component of the path prefix does not exist or is a null pathname.
136        */
137        if ( savederrno == EACCES ||
138                savederrno == ELOOP ||
139                savederrno == ENAMETOOLONG ||
140                savederrno == ENOTDIR ||
141                savederrno == ENOENT ) {
142            reply(MSG_BAD_NO_RETRY,logmessage) ;
143            FREE(buffer) ;
144            FREE(logmessage) ;
145        } else {
146            reply(MSG_BAD,logmessage) ;
147            FREE(logmessage) ;
148            FREE(buffer) ;
149        }
150        return 0 ;
151    } else {
152        if ( getcwd(logmessage,msglen+1024)  == NULL ) {
153            /*
154            ** Unable to get current directory
155            */
156            sprintf(logmessage,"Unable to get current directory") ;
157            reply(MSG_BAD,logmessage) ;
158            FREE(logmessage) ;
159            FREE(buffer) ;
160            return 0 ;
161        } 
162    }
163    reply(MSG_OK,logmessage) ;
164    FREE(logmessage) ;
165    FREE(buffer) ;
166    return 0 ;
167}
Note: See TracBrowser for help on using the repository browser.