freebsd-dev/eBones/krb/tf_shm.c
Geoff Rehmet 60643d379b Initial import of eBones.
(Including all changes for FreeBSD - importing the original eBones distribution
would be too complex at this stage, since I don't have access to Piero's 
CVS.)
(If you want to include eBones in your system, don't forget to include
MAKE_EBONES in /etc/make.conf.)
(This stuff is now also suppable from braae.ru.ac.za.)

Bones originally from MIT SIPB.
Original port to FreeBSD 1.x  by Piero Serini.
Moved to FreeBSD 2.0 by Doug Rabson and Geoff Rehmet.
Nice bug fixes from Doug Rabson.
1994-09-30 14:50:09 +00:00

175 lines
4.1 KiB
C

/*
* Copyright 1988 by the Massachusetts Institute of Technology.
* For copying and distribution information, please see the file
* <Copyright.MIT>.
*
* Shared memory segment functions for session keys. Derived from code
* contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
*
* from: tf_shm.c,v 4.2 89/10/25 23:26:46 qjb Exp $
* $Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $
*/
#ifndef lint
static char rcsid[] =
"$Id: tf_shm.c,v 1.2 1994/07/19 19:26:26 g89r4222 Exp $";
#endif lint
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <krb.h>
#include <des.h>
#include <sys/stat.h>
#include <fcntl.h>
#define MAX_BUFF sizeof(des_cblock)*1000 /* room for 1k keys */
extern int errno;
extern int krb_debug;
/*
* krb_create_shmtkt:
*
* create a shared memory segment for session keys, leaving its id
* in the specified filename.
*/
int
krb_shm_create(file_name)
char *file_name;
{
int retval;
int shmid;
struct shmid_ds shm_buf;
FILE *sfile;
uid_t me, metoo, getuid(), geteuid();
(void) krb_shm_dest(file_name); /* nuke it if it exists...
this cleans up to make sure we
don't slowly lose memory. */
shmid = shmget((long)IPC_PRIVATE,MAX_BUFF, IPC_CREAT);
if (shmid == -1) {
if (krb_debug)
perror("krb_shm_create shmget");
return(KFAILURE); /* XXX */
}
me = getuid();
metoo = geteuid();
/*
* now set up the buffer so that we can modify it
*/
shm_buf.shm_perm.uid = me;
shm_buf.shm_perm.gid = getgid();
shm_buf.shm_perm.mode = 0600;
if (shmctl(shmid,IPC_SET,&shm_buf) < 0) { /*can now map it */
if (krb_debug)
perror("krb_shm_create shmctl");
(void) shmctl(shmid, IPC_RMID, 0);
return(KFAILURE); /* XXX */
}
(void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
/* arrange so the file is owned by the ruid
(swap real & effective uid if necessary). */
if (me != metoo) {
if (setreuid(metoo, me) < 0) {
/* can't switch??? barf! */
if (krb_debug)
perror("krb_shm_create: setreuid");
(void) shmctl(shmid, IPC_RMID, 0);
return(KFAILURE);
} else
if (krb_debug)
printf("swapped UID's %d and %d\n",metoo,me);
}
if ((sfile = fopen(file_name,"w")) == 0) {
if (krb_debug)
perror("krb_shm_create file");
(void) shmctl(shmid, IPC_RMID, 0);
return(KFAILURE); /* XXX */
}
if (fchmod(fileno(sfile),0600) < 0) {
if (krb_debug)
perror("krb_shm_create fchmod");
(void) shmctl(shmid, IPC_RMID, 0);
return(KFAILURE); /* XXX */
}
if (me != metoo) {
if (setreuid(me, metoo) < 0) {
/* can't switch??? barf! */
if (krb_debug)
perror("krb_shm_create: setreuid2");
(void) shmctl(shmid, IPC_RMID, 0);
return(KFAILURE);
} else
if (krb_debug)
printf("swapped UID's %d and %d\n",me,metoo);
}
(void) fprintf(sfile,"%d",shmid);
(void) fflush(sfile);
(void) fclose(sfile);
return(KSUCCESS);
}
/*
* krb_is_diskless:
*
* check / to see if file .diskless exists. If so it is diskless.
* Do it this way now to avoid dependencies on a particular routine.
* Choose root file system since that will be private to the client.
*/
int krb_is_diskless()
{
struct stat buf;
if (stat("/.diskless",&buf) < 0)
return(0);
else return(1);
}
/*
* krb_shm_dest: destroy shared memory segment with session keys, and remove
* file pointing to it.
*/
int krb_shm_dest(file)
char *file;
{
int shmid;
FILE *sfile;
struct stat st_buf;
if (stat(file,&st_buf) == 0) {
/* successful stat */
if ((sfile = fopen(file,"r")) == 0) {
if (krb_debug)
perror("cannot open shared memory file");
return(KFAILURE); /* XXX */
}
if (fscanf(sfile,"%d",&shmid) == 1) {
if (shmctl(shmid,IPC_RMID,0) != 0) {
if (krb_debug)
perror("krb_shm_dest: cannot delete shm segment");
(void) fclose(sfile);
return(KFAILURE); /* XXX */
}
} else {
if (krb_debug)
fprintf(stderr, "bad format in shmid file\n");
(void) fclose(sfile);
return(KFAILURE); /* XXX */
}
(void) fclose(sfile);
(void) unlink(file);
return(KSUCCESS);
} else
return(RET_TKFIL); /* XXX */
}