1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
/*
* tf_shm.c
*
* Copyright 1988 by the Massachusetts Institute of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* Shared memory segment functions for session keys. Derived from code
* contributed by Dan Kolkowitz (kolk@jessica.stanford.edu).
*/
#include "mit-copyright.h"
#include <stdio.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 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 */
}
#if !defined(_AIX)
(void) shmctl(shmid, SHM_LOCK, 0); /* attempt to lock-in-core */
#endif
/* 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 */
}
|