|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T u
Length: 6573 (0x19ad)
Types: TextFile
Names: »user.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦2fafebccf⟧ »EurOpenD3/mail/smail3.1.19.tar.Z«
└─⟦bcd2bc73f⟧
└─⟦this⟧ »src/directors/user.c«
/* @(#)user.c 3.15 4/4/88 11:55:46 */
/*
* Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
*
* See the file COPYING, distributed with smail, for restriction
* and warranty information.
*
* namei master id: @(#)user.c 3.15 4/4/88 11:55:46
*/
/*
* user.c:
* direct mail to a transport which will deliver to local user
* mailboxes. Match only local addresses which are login names
* on the local host.
*
* Specifications for the user directing driver:
*
* private attribute data:
* transport (name): the name of the transport to use in delivering
* mail to local users.
*/
#include <stdio.h>
#include <pwd.h>
#include "defs.h"
#include "../smail.h"
#include "../smailconf.h"
#include "../parse.h"
#include "../addr.h"
#include "../log.h"
#include "../direct.h"
#include "../transport.h"
#include "../exitcodes.h"
#include "../dys.h"
#include "user.h"
#ifndef DEPEND
# include "../extern.h"
# include "../debug.h"
# include "../error.h"
#endif
\f
/*
* dtd_user - direct to local user mailboxes
*/
/*ARGSUSED*/
struct addr *
dtd_user(dp, in, out, new, defer, fail)
struct director *dp; /* director entry */
struct addr *in; /* input local-form addrs */
struct addr **out; /* output resolved addrs */
struct addr **new; /* output new addrs to resolve */
struct addr **defer; /* addrs to defer to a later time */
struct addr **fail; /* unresolvable addrs */
{
register struct addr *cur; /* temp for processing input */
struct addr *pass = NULL; /* addrs to pass to next director */
struct addr *next; /* next value for cur */
struct user_private *priv = (struct user_private *)dp->private;
DEBUG(DBG_DRIVER_HI, "dtd_user called\n");
for (cur = in; cur; cur = next) {
next = cur->succ;
if (priv->prefix) {
struct addr *new;
int len = strlen(priv->prefix);
/*
* if we are testing against a prefix, strip the prefix and
* lookup the name in the passwd file. If found, return a
* new fully resolved addr.
*/
if (strncmpic(priv->prefix, cur->remainder, len) != 0) {
cur->succ = pass;
pass = cur;
continue; /* did not start with prefix */
}
new = alloc_addr();
new->remainder = COPY_STRING(cur->remainder + len);
director_user_info(new);
if (new->flags&ADDR_NOTUSER) {
/* we did not match a user on the local host */
xfree(new->remainder);
xfree((char *)new);
cur->succ = pass;
pass = cur;
continue;
}
new->in_addr = COPY_STRING(new->remainder);
new->director = dp;
new->parent = cur;
cur = new;
} else {
/* fill in any user information */
director_user_info(cur);
/* don't match it if it is not a local user */
if (cur->flags&ADDR_NOTUSER) {
cur->succ = pass;
pass = cur;
continue;
}
}
DEBUG2(DBG_DRIVER_LO, "director %s matched user %s\n",
dp->name, cur->remainder);
cur->director = dp; /* matched address */
/* attach the transport */
cur->transport = find_transport(priv->transport);
if (cur->transport == NULL) {
/*
* ERR_122 - user transport not specified
*
* DESCRIPTION
* No transport attribute was specified for a user
* director. The attribute is required.
*
* ACTIONS
* Defer the message with a configuration error.
*
* RESOLUTION
* The director file should be edited to specify the
* correct transport for local delivery.
*/
cur->error = note_error(ERR_CONFERR|ERR_122,
xprintf("director %s: transport not defined",
dp->name));
cur->succ = *defer;
*defer = cur;
continue;
}
cur->next_addr = COPY_STRING(cur->remainder);
cur->succ = *out;
*out = cur;
}
return pass; /* return addrs for next director */
}
/*
* dtv_user - verify a user on the local host
*/
/*ARGSUSED*/
void
dtv_user(dp, in, retry, okay, defer, fail)
struct director *dp; /* director entry */
struct addr *in; /* input local-form addrs */
struct addr **retry; /* output list of unmatched addrs */
struct addr **okay; /* output list of verified addrs */
struct addr **defer; /* temporariliy unverifiable addrs */
struct addr **fail; /* unverified addrs */
{
register struct addr *cur; /* temp for processing input */
struct addr *next; /* next value for cur */
struct user_private *priv = (struct user_private *)dp->private;
DEBUG(DBG_DRIVER_HI, "dtv_user called\n");
/* loop over all of the input addrs */
for (cur = in; cur; cur = next) {
next = cur->succ;
if (priv->prefix) {
int len = strlen(priv->prefix);
/*
* if we are testing against a prefix, strip the prefix and
* see if the remaining string matches a local user
*/
if (strncmpic(priv->prefix, cur->remainder, len) == 0 &&
getpwbyname(cur->remainder + len))
{
/* matched */
cur->succ = *okay;
*okay = cur;
continue;
}
} else {
/* fill in any user information */
director_user_info(cur);
/* match only if this is a user */
if (cur->flags&ADDR_ISUSER) {
cur->succ = *okay;
*okay = cur;
continue;
}
}
/* didn't match */
cur->succ = *retry;
*retry = cur;
}
}
/*
* dtb_user - read the configuration file attributes
*/
char *
dtb_user(dp, attrs)
struct director *dp; /* director entry being defined */
struct attribute *attrs; /* list of per-driver attributes */
{
char *error;
static struct attr_table user_attributes[] = {
{ "transport", t_string, NULL, NULL, OFFSET(user_private, transport) },
{ "prefix", t_string, NULL, NULL, OFFSET(user_private, prefix) },
};
static struct attr_table *end_user_attributes = ENDTABLE(user_attributes);
static struct user_private user_template = {
"local",
NULL,
};
struct user_private *priv; /* new user_private structure */
/* copy the template private data */
priv = (struct user_private *)xmalloc(sizeof(*priv));
(void) memcpy((char *)priv, (char *)&user_template, sizeof(*priv));
dp->private = (char *)priv;
/* fill in the attributes of the private data */
error = fill_attributes((char *)priv,
attrs,
&dp->flags,
user_attributes,
end_user_attributes);
if (error) {
return error;
} else {
if (priv->transport == NULL) {
return "transport attribute required";
}
if (find_transport(priv->transport) == NULL) {
return xprintf("unknown transport: %s", priv->transport);
}
return NULL;
}
}