Esempio n. 1
0
    int
f_retr( SNET *sn, int ac, char **av )
{

    ssize_t		readlen;
    struct stat		st;
    struct timeval	tv;
    char		buf[8192];
    char		path[ MAXPATHLEN ];
    char		*d_path, *d_tran;
    int			fd;

    switch ( keyword( ac, av )) {
    case K_COMMAND:
	if ( ac == 2 ) { 

	    if ( snprintf( path, MAXPATHLEN, "command/%s", command_file )
		    >= MAXPATHLEN ) {
		syslog( LOG_ERR, "f_retr: command/%s: path too long",
		    command_file );
		snet_writef( sn, "%d Path too long\r\n", 540 );
		return( 1 );
	    }
	} else {
	    if (( d_path = decode( av[ 2 ] )) == NULL ) {
		syslog( LOG_ERR, "f_retr: decode: buffer too small" );
		snet_writef( sn, "%d Line too long\r\n", 540 );
		return( 1 );
	    } 

	    /* Check for access */
	    if ( !list_check( access_list, d_path )) {
		syslog( LOG_WARNING | LOG_AUTH, "attempt to access: %s",
		    d_path );
		snet_writef( sn, "%d No access for %s\r\n", 540, d_path );
		return( 1 );
	    }

	    if ( snprintf( path, MAXPATHLEN, "command/%s", d_path )
		    >= MAXPATHLEN ) {
		syslog( LOG_ERR, "f_retr: command path too long" );
		snet_writef( sn, "%d Path too long\r\n", 540 );
		return( 1 );
	    }
	}
	break;

    case K_TRANSCRIPT:
	if (( d_tran = decode( av[ 2 ] )) == NULL ) {
	    syslog( LOG_ERR, "f_retr: decode: buffer too small" );
	    snet_writef( sn, "%d Line too long\r\n", 540 );
	    return( 1 );
	} 

	/* Check for access */
	if ( !list_check( access_list, d_tran )) {
	    syslog( LOG_WARNING | LOG_AUTH, "attempt to access: %s", d_tran );
	    snet_writef( sn, "%d No access for %s\r\n", 540, d_tran );
	    return( 1 );
	}

	if ( snprintf( path, MAXPATHLEN, "transcript/%s", d_tran )
		>= MAXPATHLEN ) {
	    syslog( LOG_ERR, "f_retr: transcript path too long" );
	    snet_writef( sn, "%d Path too long\r\n", 540 );
	    return( 1 );
	}
	break;

    case K_SPECIAL:
	if (( d_path = decode( av[ 2 ] )) == NULL ) {
	    syslog( LOG_ERR, "f_retr: decode: buffer too small" );
	    snet_writef( sn, "%d Line too long\r\n", 540 );
	    return( 1 );
	} 

	if ( snprintf( path, MAXPATHLEN, "%s/%s", special_dir, d_path )
		>= MAXPATHLEN ) {
	    syslog( LOG_ERR, "f_retr: special path too long" );
	    snet_writef( sn, "%d Path too long\r\n", 540 );
	    return( 1 );
	}

	break;

    case K_FILE:
	if (( d_path = decode( av[ 3 ] )) == NULL ) {
	    syslog( LOG_ERR, "f_retr: decode: buffer too small" );
	    snet_writef( sn, "%d Line too long\r\n", 540 );
	    return( 1 );
	} 
	if (( d_path = strdup( d_path )) == NULL ) {
	    syslog( LOG_ERR, "f_retr: strdup: %s: %m", d_path );
	    return( -1 );
	}
	if (( d_tran = decode( av[ 2 ] )) == NULL ) {
	    syslog( LOG_ERR, "f_retr: decode: buffer too small" );
	    snet_writef( sn, "%d Line too long\r\n", 540 );
	    return( 1 );
	} 

	/* Check for access */
	if ( !list_check( access_list, d_tran )) {
	    syslog( LOG_WARNING | LOG_AUTH, "attempt to access: %s", d_tran );
	    snet_writef( sn, "%d No access for %s:%s\r\n", 540, d_tran,
		d_path );
	    return( 1 );
	}

	if ( snprintf( path, MAXPATHLEN, "file/%s/%s", d_tran, d_path )
		>= MAXPATHLEN ) {
	    syslog( LOG_ERR, "f_retr: file path too long" );
	    snet_writef( sn, "%d Path too long\r\n", 540 );
	    return( 1 );
	}
	free( d_path );
	break;

    default:
	snet_writef( sn, "%d RETR Syntax error\r\n", 540 );
	return( 1 );
    }

    if (( fd = open( path, O_RDONLY, 0 )) < 0 ) {
    	syslog( LOG_ERR, "open: %s: %m", path );
	snet_writef( sn, "%d Unable to access %s.\r\n", 543, path );
	return( 1 );
    }
    
    /* dump file info */

    if ( fstat( fd, &st ) < 0 ) { 
	syslog( LOG_ERR, "f_retr: fstat: %m" );
	snet_writef( sn, "%d Access Error: %s\r\n", 543, path );
	if ( close( fd ) < 0 ) {
	    syslog( LOG_ERR, "close: %m" );
	    return( -1 );
	}
	return( 1 );
    }

    /*
     * Here's a problem.  Do we need to add long long support to
     * snet_writef?
     */
    snet_writef( sn, "240 Retrieving file\r\n%" PRIofft "d\r\n", st.st_size );

    /* dump file */

    while (( readlen = read( fd, buf, sizeof( buf ))) > 0 ) {
	tv.tv_sec = 60 ;
	tv.tv_usec = 0;
	if ( snet_write( sn, buf, readlen, &tv ) != readlen ) {
	    syslog( LOG_ERR, "snet_write: %m" );
	    return( -1 );
	}
    }

    if ( readlen < 0 ) {
	syslog( LOG_ERR, "read: %m" );
	return( -1 );
    }

    snet_writef( sn, ".\r\n" );

    if ( close( fd ) < 0 ) {
        syslog( LOG_ERR, "close: %m" );
	return( -1 );
    }

    syslog( LOG_DEBUG, "f_retr: 'file' %s retrieved", path );

    return( 0 );
}
Esempio n. 2
0
    static int
retr_ticket( SNET *sn, struct servicelist *sl, char *krbpath )
{
    struct stat		st;
    int			fd;
    ssize_t             readlen;
    char                buf[ 8192 ];
    struct timeval      tv;

    /* S: 240 Retrieving file
     * S: [size]
     * S: [data]
     * S: .
     */

    if (( sl->sl_flag & SL_TICKET ) == 0 ) {
	syslog( LOG_ERR, "%s not allowed to retrieve tkts",
		sl->sl_auth->al_hostname );
	snet_writef( sn, "%d RETR: %s not allowed to retrieve tkts.\r\n",
		441, sl->sl_auth->al_hostname );
	return( 1 );
    }

    if (( fd = open( krbpath, O_RDONLY, 0 )) < 0 ) {
        syslog( LOG_ERR, "open: %s: %m", krbpath );
        snet_writef( sn, "%d Unable to access %s.\r\n", 547, krbpath );
        return( 1 );
    }

    if ( fstat( fd, &st ) < 0 ) {
        syslog( LOG_ERR, "f_retr: fstat: %m" );
        snet_writef( sn, "%d Access Error: %s\r\n", 548, krbpath );
        if ( close( fd ) < 0 ) {
            syslog( LOG_ERR, "close: %m" );
            return( -1 );
        }
        return( 1 );
    }

    snet_writef( sn, "%d Retrieving file\r\n", 240 );
    snet_writef( sn, "%d\r\n", (int)st.st_size );

    while (( readlen = read( fd, buf, sizeof( buf ))) > 0 ) {
        tv = cosign_net_timeout;
        if ( snet_write( sn, buf, (int)readlen, &tv ) != readlen ) {
            syslog( LOG_ERR, "snet_write: %m" );
            return( -1 );
        }
    }

    if ( readlen < 0 ) {
        syslog( LOG_ERR, "read: %m" );
	close( fd );
        return( -1 );
    }

    if ( close( fd ) < 0 ) {
        syslog( LOG_ERR, "close: %m" );
        return( -1 );
    }

    snet_writef( sn, ".\r\n" );

    return( 0 );
}