[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Configuration files in /usr/etc



[Please don't CC me when replying to the list.  Thanks.]

I wrote:
>To give us something substantial to debate/argue over, I'll try writing
>a first draft of this function and some documentation for it this
>weekend.  I'll post it here for criticism, hopefully Monday.

Okay, here it is.

I'm not too sure about setID; I -think- the way it works is such that a
setID program will have its real id different from its effective id,
and that this will also be the case for any programs it invokes.  Is
that right?

Anyway, see what you think.  It's a bit rough and ready, and has had
virtually no testing, but it should be enough to spark off criticism.
If you can tell me what's wrong with it, I'll try to fix it!

--Charles Briscoe-Smith
White pages entry, with PGP key: <URL:http://alethea.ukc.ac.uk/wp?95cpb4>
PGP public keyprint: 74 68 AB 2E 1C 60 22 94  B8 21 2D 01 DE 66 13 E2



/* fopenconf -- Locate and open configuration file
   Copyright 1997 C. P. Briscoe-Smith

Redistribution and use in source code and/or executable forms, with
or without modification, are permitted provided that the following
condition is met:

Any redistribution must retain the above copyright notice, this
condition and the following disclaimer, either as part of the program
source code included in the redistribution or in human-readable
materials provided with the redistribution.

THIS SOFTWARE IS PROVIDED "AS IS".  Any express or implied warranties
concerning this software are disclaimed by the copyright holder to
the fullest extent permitted by applicable law.  In no event shall
the copyright-holder be liable for any damages of any kind, however
caused and on any theory of liability, arising in any way out of the
use of, or inability to use, this software.

----------------------------------------------------------------------

In other words, do not misrepresent my work as your own work, and do
not sue me if it causes problems.  Feel free to do anything else you
wish with it!
*/

#include <stdio.h>

FILE *fopenconf (const char *filename,
                 const char *opentype,
                 const char *overridepath);

/*
The `fopenconf' function opens an I/O stream to a configuration file
named FILENAME, and returns a pointer to the stream.  The configuration
file is searched for along the configuration path, as specified below.

The OPENTYPE argument is a string that controls how the file is opened
and specifies attributes of the resulting stream.  It is interpreted as
for `fopen'.

If the OVERRIDEPATH argument is NULL, fopenconf obtains the configuration
path internally, otherwise OVERRIDEPATH is used as the configuration path.

If obtaining the configuration path internally, fopenconf checks
whether the effective uid and gid are the same as the real uid and gid.
If there are any differences, a built-in configuration path is used,
otherwise the configuration path is obtained from the environment
variable "CONFIG_PATH".

The path is always searched to find the file; it is illegal for the
FILENAME argument to begin with a '/'.  It is explicitly allowed for a
'/' to be present in FILENAME other than at the beginning; this allows
configuration files to be hierachically organised below the configuration
directories.

The path search is carried out as follows.  Each colon-separated path
element is tried in turn.  A slash and the FILENAME are appended to the
path element and lstat(2) called on the result.  If this succeeds, the
resulting path is used.

If the search fails to produce an accessible file, or the open fails,
`fopenconf' returns a null pointer.
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

FILE *
fopenconf(const char *filename, const char *opentype, const char *overridepath)
{
	const char *path;
	const char *builtinpath="/etc:/usr/local/etc:/usr/etc";
	size_t trailerlen=strlen(filename)+2;

	if (overridepath)
		path=overridepath;
	else if (getuid()!=geteuid() || getgid()!=getegid())
		path=builtinpath;
	else
		path=getenv("CONFIG_PATH");

	if (path==0)
		path=builtinpath;

	while (path) {
		const char *elem=path;
		size_t len;
		char *fullname;
		struct stat statbuf;

		path=strchr(path, ':');
		if (path) {
			len=path-elem;
			path++;
		}
		else {
			len=strlen(elem);
		}

		if (len==0) {
			len=1;
			elem=".";
		}

		fullname=malloc(len+trailerlen);
		if (fullname==0)
			return 0;

		strncpy(fullname, elem, len);
		fullname[len]='/';
		strcpy(&fullname[len+1], filename);

		if (lstat(fullname, &statbuf)==0) {
			FILE *fp=fopen(fullname, opentype);

			free(fullname);
			return fp;
		}

		free(fullname);
	}

	return 0;
}

#ifdef TEST
void
testit(const char *name, const char *override)
{
	FILE *fp;
	struct stat statbuf;

	fp=fopenconf(name, "r", override);
	printf("Tried `%s'. %s.\n", name, fp ? "Okay" : "Bad");
	if (fp) {
		fstat(fileno(fp), &statbuf);
		printf("  %4d,%8d %04o l:%2d u:%8d g:%8d s:%8d\n",
		       statbuf.st_dev, statbuf.st_ino,
		       statbuf.st_mode, statbuf.st_nlink,
		       statbuf.st_uid, statbuf.st_gid,
		       statbuf.st_size);
	}
}

int
main(void)
{
	testit("termcap", NULL);
	testit("termcap", "");
	return 0;
}
#endif


--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-devel-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .


Reply to: