219 lines
5.6 KiB
C
219 lines
5.6 KiB
C
/*********************************************************************\
|
|
* Copyright (c) 2003 by Radim Kolar (hsn@cybermail.net) *
|
|
* *
|
|
* You may copy or modify this file in any manner you wish, provided *
|
|
* that this notice is always included, and that you hold the author *
|
|
* harmless for any loss or damage resulting from the installation or *
|
|
* use of this software. *
|
|
\*********************************************************************/
|
|
|
|
#include "tweak.h"
|
|
#include <stdio.h>
|
|
#include "server_def.h"
|
|
#include "s_extern.h"
|
|
#include "my-string.h"
|
|
|
|
/* loads a password from file in current directory */
|
|
static char *load_password (const char * file)
|
|
{
|
|
/* load password */
|
|
FILE *f;
|
|
char fsp_passwd[80];
|
|
|
|
f=fopen(file,"r");
|
|
if(f) {
|
|
if(fscanf(f, "%79s", fsp_passwd) != 1) {
|
|
if(dbug) printf("load_pass: no password found in file\n");
|
|
fclose(f);
|
|
return NULL;
|
|
}
|
|
} else
|
|
return NULL;
|
|
fclose(f);
|
|
return strdup(fsp_passwd);
|
|
}
|
|
|
|
/* save a password to file in current directory */
|
|
static void save_password (const char *file,const char *password)
|
|
{
|
|
/* load password */
|
|
FILE *f;
|
|
|
|
f=fopen(file,"w");
|
|
if(f) {
|
|
fprintf(f,"%s\n",password);
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
/* save access rights to filesystem */
|
|
void save_access_rights (DIRINFO *di)
|
|
{
|
|
/* step 1 - unlink everything */
|
|
unlink(FSP_NOGET);
|
|
unlink(FSP_DEL);
|
|
unlink(FSP_ADD);
|
|
unlink(FSP_MKDIR);
|
|
unlink(FSP_RENAME);
|
|
unlink(FSP_NOLIST);
|
|
unlink(FSP_PASSWORD);
|
|
unlink(FSP_OWNER);
|
|
unlink(FSP_OWNERPASSWORD);
|
|
unlink(FSP_DIRLISTING);
|
|
|
|
if(!use_access_files) return;
|
|
|
|
/* step2 save flagfiles */
|
|
if(! (di->protection & DIR_GET) ) touch(FSP_NOGET);
|
|
if(di->protection & DIR_DEL) touch(FSP_DEL);
|
|
if(di->protection & DIR_ADD) touch(FSP_ADD);
|
|
if(di->protection & DIR_MKDIR) touch(FSP_MKDIR);
|
|
if(di->protection & DIR_RENAME) touch(FSP_RENAME);
|
|
if(!di->protection& DIR_LIST) touch(FSP_NOLIST);
|
|
|
|
/* step3 pazzwordz */
|
|
if(di->public_password) save_password(FSP_PASSWORD,di->public_password);
|
|
if(di->owner_password) save_password(FSP_OWNERPASSWORD,di->owner_password);
|
|
|
|
/* save Owner ACL */
|
|
if(di->owner)
|
|
{
|
|
FILE *f;
|
|
f=fopen(FSP_OWNER,"w");
|
|
if(f)
|
|
{
|
|
dump_iptab(di->owner,f);
|
|
fclose(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* called with current directory == tested directory */
|
|
/* load access rights for validated directory */
|
|
void load_access_rights (DIRINFO *di)
|
|
{
|
|
struct stat sf;
|
|
FILE *f;
|
|
char owner_line[256];
|
|
|
|
di->owner=NULL;
|
|
di->owner_password=NULL;
|
|
di->public_password=NULL;
|
|
di->protection=DIR_LIST|DIR_GET;
|
|
di->readme=NULL;
|
|
|
|
/* load directory readme file */
|
|
if(!FSP_STAT(readme_file,&sf))
|
|
{
|
|
f=fopen(readme_file,"r");
|
|
if(f)
|
|
{
|
|
unsigned int s;
|
|
/* max readme file size is
|
|
* packetsize - pro_bytes (now 1) - 1 (for /0)
|
|
*/
|
|
s=min(packetsize-PRO_BYTES-1,sf.st_size);
|
|
di->readme=calloc(1,s+1); /* allocate also space for ending /0 */
|
|
if(di->readme)
|
|
{
|
|
fread(di->readme,s,1,f);
|
|
di->protection|=DIR_README;
|
|
}
|
|
fclose(f);
|
|
}
|
|
}
|
|
|
|
if(!use_access_files) return;
|
|
|
|
/* LOAD ACCESS RIGHTS FROM FILES IN CURRENT DIRECTORY */
|
|
if(fexist(FSP_NOGET)) di->protection^=DIR_GET;
|
|
if(fexist(FSP_DEL)) di->protection|=DIR_DEL;
|
|
if(fexist(FSP_ADD)) di->protection|=DIR_ADD;
|
|
if(fexist(FSP_MKDIR)) di->protection|=DIR_MKDIR;
|
|
if(fexist(FSP_RENAME)) di->protection|=DIR_RENAME;
|
|
if(fexist(FSP_NOLIST)) di->protection^=DIR_LIST;
|
|
if(!FSP_STAT(FSP_PASSWORD,&sf))
|
|
if(sf.st_size>0)
|
|
di->public_password=load_password(FSP_PASSWORD);
|
|
|
|
/* load owner info */
|
|
f=fopen(FSP_OWNER,"r");
|
|
if(!f)
|
|
return;
|
|
|
|
while(fscanf(f, "%255[^\n\r]", owner_line) == 1)
|
|
{
|
|
add_ipline(owner_line,&di->owner);
|
|
}
|
|
fclose(f);
|
|
/* .. and password */
|
|
if(!FSP_STAT(FSP_OWNERPASSWORD,&sf))
|
|
{
|
|
if(sf.st_size>0)
|
|
di->owner_password=load_password(FSP_OWNERPASSWORD);
|
|
}
|
|
}
|
|
|
|
/* does caller has enough security rights? */
|
|
/* if rights has DIR_PRIV set than caller is restristed and need also
|
|
* at least 'N' record to get it, if he has DIR_README, we will send him
|
|
* a datagram with error reply */
|
|
|
|
const char * require_access_rights (const DIRINFO *di,unsigned char rights,unsigned long ip_addr, const char * passwd)
|
|
{
|
|
const char *acc=NULL;
|
|
|
|
/* check if we has record in an owner tabl. */
|
|
if(di->owner)
|
|
{
|
|
/* check ip access */
|
|
acc=check_ip_table(ip_addr,di->owner);
|
|
}
|
|
|
|
if(acc!=NULL)
|
|
{
|
|
if(acc[0]=='I' || acc[0]=='D')
|
|
/* bazmeg IP! */
|
|
return acc;
|
|
if(acc[0]=='O') /* possible owner */
|
|
{
|
|
if(di->owner_password==NULL)
|
|
{
|
|
if(permit_passwordless_owners)
|
|
return acc; /* passwordless owner */
|
|
} else
|
|
{
|
|
/* do we have a password? */
|
|
if(passwd)
|
|
{
|
|
/* compare passwords */
|
|
if(!strcmp(passwd,di->owner_password))
|
|
return acc; /* owner with good password */
|
|
} else
|
|
if(rights & DIR_OWNER)
|
|
return "DPassword required for owner";
|
|
}
|
|
}
|
|
}
|
|
|
|
if(rights & DIR_OWNER)
|
|
return "DNot an owner";
|
|
/* is password needed for public access? */
|
|
if(di->public_password)
|
|
{
|
|
if(passwd==NULL)
|
|
return "DYou need a password";
|
|
else
|
|
if(strcmp(di->public_password,passwd))
|
|
return "DInvalid password";
|
|
}
|
|
|
|
/* now check public access rights */
|
|
if( (rights & di->protection) ||
|
|
(rights==0)
|
|
)
|
|
return "NWelcome on board captain!";
|
|
else
|
|
return "DPermission denied";
|
|
}
|