Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 05 Sep 1998 16:31:53 -0600
From:      Wes Peters <wes@softweyr.com>
To:        laurens van alphen <lva@dds.nl>
Cc:        freebsd-isp@FreeBSD.ORG, freebsd-security@FreeBSD.ORG
Subject:   Re: small LDA c program requested
Message-ID:  <35F1BBD9.7E2A42F@softweyr.com>
References:  <000501bdd817$1c440870$60e65982@uptight.student.utwente.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
laurens van alphen wrote:
> 
> hi all,
> 
> working with cucipop-1.31 and the new vpop features. there are numerous bugs
> in the implementation that i basically fixed.
> 
> my next move was a LDA that will deliver the way cucipop wants it:
> /var/mail/domain/user:
> 
> #!/bin/sh
> umask 077
> cat - >> /var/mail/${1}/${2}
> 
> this indeed works. all i need now i a port to c for speed and security.
> things that need to be added are:

OK, I've hacked up a quick little program to do this.  The error checking
is fairly good, but it could use some logging capabilities.  I've attached
a Berkeley-style copyright, so you're free to extend it if you wish. If
this is something that is of general interest to cucipop users, let me
know so I can send it to Mr. van den Berg, or at least to the FreeBSD
port maintainer.

> - regex $1 and $2 to match a-z and - and .

Got that -- I didn't use regex, it's too expensive in this simple case.
I assumed you meant A-Z a-z . - for domain and user names.  If not,
remove the uppercase characters from the string validChars in function
invalidName.

> - check $1 (directory) exists, if not bail

Got that, too.  I didn't check for writability, since that will happen
when we try to open() the file anyhow.

> - check symlinks in $1 and $2 probably?

I can add that, if you can tell me what you want.  What I have here will
work fine even if both the domain directory and the user file are
symlinks; it is symlink-unaware.

> suggestions welcome

No suggestions, just code.  ;^)

> -- the information contained in this communication is confidential and
> may be legally privileged. it is intended solely for the use of the
> individual or entity to whom it is addressed and others authorised to
> receive it. if you are not the intended recipient you are hereby notified
> that any disclosure, copying, distribution or taking any action in
> reliance of the contents of this information is strictly prohibited and
> may be unlawful. craxx is either liable for the proper and complete
> transmission of the information contained in this communication nor
> for any delay in its receipt.

This has got to be the most draconian .sig I've ever seen.  What, precisely,
do you expect to accomplish with this?  ;^)

Here's the program, for your compiling enjoyment:

/*================================================================
 *
 * LDA: a small Local Delivery Agent for email.
 *
 *----------------------------------------------------------------
 *
 * Copyright 1998 Softweyr LLC, South Jordan Utah USA.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 *----------------------------------------------------------------
 *
 * Author: Wes Peters, wes@softweyr.com
 * Date: 3 Sept 1998
 *
 *================================================================*/

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syslimits.h>

#include <fcntl.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>

char *programName;


void
abort(char *why, ...)
{
    va_list ap;

    fprintf(stderr, "%s: ", programName);

    va_start(ap, why);
    vfprintf(stderr, why, ap);
    va_end(ap);
    
    exit(-1);
}

int
invalidName(char *name)
{
    static char *validChars =
        "ABCDEFGHIJKLMNOPQRSTUVWXYSabcdefghijklmnopqrstuvwxyz-.";

    if (strlen(name) > NAME_MAX)
    {
        return 1;
    }

    return strcspn(name, validChars);
}


int
main(int argc, char *argv[])
{
    char *domain, *user;
    int fd, nbytes;
    struct stat S;
    char mailbox[PATH_MAX + 1];
    char buffer[BUFSIZ];

    programName = argv[0];
    domain = argv[1];
    user = argv[2];

    /*
     * Verify we have two arguments, and that they are valid domain/user
     * names.
     */
    if (argc != 3)
    {
        abort("wrong number of arguments.\nusage: %s domain-name user-name",
              programName);
    }

    if (invalidName(argv[1]))
    {
        abort("incorrect domain name \"%s\".\n", domain);
    }

    if (invalidName(user))
    {
        abort("incorrect user name \"%s\".\n", user);
    }

    /*
     * Make sure the domain directory exists and is writable.
     */
    snprintf(mailbox, PATH_MAX, "/var/mail/%s", domain);
    if (stat(mailbox, &S) == -1)
    {
        abort("Cannot stat domain directory \"%s\".\n", mailbox);
    }

    if (!S_ISDIR(S.st_mode))
    {
        abort("Domain directory \"%s\" is NOT a directory.\n", mailbox);
    }

    /*
     * Create the file and prepare to write.
     */
    snprintf(mailbox, PATH_MAX, "/var/mail/%s/%s", domain, user);
    if ((fd = open(mailbox, O_WRONLY | O_APPEND | O_CREAT, 0600)) < 0)
    {
        abort("Cannot open user mailbox \"%s\" for appending.\n", mailbox);
    }

    /*
     * OK, copy stdin until exhausted.
     */
    while ((nbytes = read(STDIN_FILENO, buffer, BUFSIZ)) > 0)
    {
        if (write(fd, buffer, nbytes) != nbytes)
        {
            abort("Error writing mailbox \"%s\".\n", mailbox);
        }
    }

    close(fd);
    return 0;
}

-- 
             Where am I, and what am I doing in this handbasket?

Wes Peters                                                      +1.801.915.2061
Softweyr LLC                                                   wes@softweyr.com

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35F1BBD9.7E2A42F>