fsp/server/acl.c
2004-11-15 17:17:57 +00:00

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";
}