1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28/*	  All Rights Reserved  	*/
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include "mail.h"
33/*
34	If mail file does not exist create it
35*/
36#ifdef OLD
37void createmf(uid, file)
38uid_t uid;
39char *file;
40{
41	int fd;
42
43	void (*istat)(), (*qstat)(), (*hstat)();
44
45	if (access(file, A_EXIST) == CERROR) {
46		istat = signal(SIGINT, SIG_IGN);
47		qstat = signal(SIGQUIT, SIG_IGN);
48		hstat = signal(SIGHUP, SIG_IGN);
49		umask(0);
50		if ((fd = creat(file, MFMODE)) == -1)
51			sav_errno = errno;
52		else
53			close(fd);
54		umask(7);
55		(void) signal(SIGINT, istat);
56		(void) signal(SIGQUIT, qstat);
57		(void) signal(SIGHUP, hstat);
58	}
59}
60#else
61
62#include <sys/stat.h>
63#include <fcntl.h>
64#include <stdio.h>
65
66int accessmf(path)
67char *path;
68{
69
70struct stat fsb,sb;
71int mbfd;
72tryagain:
73	if (lstat(path, &sb)) {
74		/* file/symlink does not exist, so create one */
75		mbfd = open(path,
76		    O_APPEND|O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
77		chmod(path, 0660);
78		/* if someone create a symlink/file just ahead */
79		/* of us, the create will failed with EEXIST   */
80		/* This is what we want, because we do not     */
81		/* want someone to re-direct our "create"      */
82	        /* request to a another location.              */
83		if (mbfd == -1) {
84			if (errno == EEXIST)
85				goto tryagain;
86		}
87
88	/* file/symlink  exist, make sure it is not linked */
89	} else if (sb.st_nlink != 1 || S_ISLNK(sb.st_mode)) {
90		fprintf(stderr,
91"%s: security violation, '%s' should not be linked to other file\n", program, path);
92		sav_errno = errno;
93		return -1;
94	} else {
95		/* if we get here, there is a pre-existing file, */
96		/* and it is not a symlink...			 */
97		/* open it, and make sure it is the same file    */
98		/* we lstat() before...                          */
99		/* this is to guard against someone deleting the */
100		/* old file and creat a new symlink in its place */
101		/* We are not createing a new file here, but we  */
102		/* do not want append to the worng file either   */
103		mbfd = open(path, O_APPEND|O_WRONLY, 0);
104		if (mbfd != -1 &&
105		    (fstat(mbfd, &fsb) || fsb.st_nlink != 1 ||
106		    S_ISLNK(fsb.st_mode) || sb.st_dev != fsb.st_dev ||
107		    sb.st_ino != fsb.st_ino)) {
108			/*  file changed after open */
109			fprintf(stderr, "%s: security violation, '%s' inode changed after open\n", program, path);
110			(void)close(mbfd);
111			return -1;
112		}
113	}
114
115	if (mbfd == -1) {
116		sav_errno = errno;
117		return -1;
118	}
119
120	return mbfd;
121}
122#endif
123