/*
* Remove temporary pseudo-files that have timed-out
* from the trusted directory
*/
void
cleantrusted(void)
{
Node *np, **l;
ulong t;
np = finddir(Trusted);
if (np == 0)
return;
t = time(0)-Timeout;
l = &np->children;
for (np = np->children; np; np = *l) {
if(np->d.type == Trustedtemp && t >= np->d.mtime) {
*l = np->sibs;
if(debugfd >= 0)
fprint(debugfd, "Deleting %s\n", np->d.name);
np->parent->count--;
free(np);
} else
l = &np->sibs;
}
}
/*
* match path components to prohibited domain & user specifications. patterns include:
* domain, domain! or domain!* - all users in domain
* *.domain, *.domain! or *.domain!* - all users in domain and its subdomains
* !user or *!user - user in all domains
* domain!user - user in domain
* *.domain!user - user in domain and its subdomains
*
* if "user" has a trailing '*', it matches all user names beginning with "user"
*
* there are special semantics for the "domain, domain! or domain!*" specifications:
* the first two forms match when the domain is anywhere in at list of source-routed
* domains while the latter matches only when the domain is the last hop. the same is
* true for the *.domain!* form of the pattern.
*/
static int
accountmatch(char *spec, char **doms, int ndoms, char *user)
{
char *cp, *userp;
int i, ret;
userp = 0;
ret = 0;
cp = strchr(spec, '!');
if(cp){
*cp++ = 0; /* restored below */
if(*cp)
if(strcmp(cp, "*")) /* "!*" is the same as no user field */
userp = cp; /* there is a user name */
}
if(userp == 0){ /* no user field - domain match only */
for(i = 0; i < ndoms && doms[i]; i++)
if(dommatch(doms[i], spec) == 0)
ret = 1;
} else {
/* check for "!user", "*!user" or "domain!user" */
if(usermatch(user, userp) == 0){
if(*spec == 0 || strcmp(spec, "*") == 0)
ret = 1;
else if(ndoms > 0 && dommatch(doms[ndoms-1], spec) == 0)
ret = 1;
}
}
if(cp)
cp[-1] = '!';
return ret;
}
/*
* match a user name. the only meta-char is '*' which matches all
* characters. we only allow it as "*", which matches anything or
* an * at the end of the name (e.g., "username*") which matches
* trailing characters.
*/
static int
usermatch(char *pathuser, char *specuser)
{
int n;
/*
* Custom allocators to avoid malloc overheads on small objects.
* We never free these. (See below.)
*/
typedef struct Stringtab Stringtab;
struct Stringtab {
Stringtab *link;
char *str;
};
static Stringtab*
taballoc(void)
{
static Stringtab *t;
static uint nt;
if(nt == 0){
t = malloc(64*sizeof(Stringtab));
if(t == 0)
fatal("out of memory");
nt = 64;
}
nt--;
return t++;
}
static char*
xstrdup(char *s)
{
char *r;
int len;
static char *t;
static int nt;
len = strlen(s)+1;
if(len >= 8192)
fatal("strdup big string");
if(nt < len){
t = malloc(8192);
if(t == 0)
fatal("out of memory");
nt = 8192;
}
r = t;
t += len;
nt -= len;
strcpy(r, s);
return r;
}
/*
* Return a uniquely allocated copy of a string.
* Don't free these -- they stay in the table for the
* next caller who wants that particular string.
* String comparison can be done with pointer comparison
* if you know both strings are atoms.
*/
static Stringtab *stab[1024];
static uint
hash(char *s)
{
uint h;
uchar *p;
h = 0;
for(p=(uchar*)s; *p; p++)
h = h*37 + *p;
return h;
}