Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / log / unlog.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 /*
11 unlog -- Tell the Andrew Cache Manager to either clean up your connection completely
12 or eliminate the caller's PAG.
13 February 1986
14
15 Usage:
16 unlog [cell ...]
17
18 where:
19 cell is the name the pertinent cell.
20
21 If no cell is provided, unlog destroys all tokens.
22
23 If a cell, for which a token is not held, is provided it is ignored.
24 */
25
26 #define VIRTUE 1
27 #define VICE 1
28
29 #include <afsconfig.h>
30 #include <afs/param.h>
31
32 #include <roken.h>
33 #include <afs/opr.h>
34
35 #include <afs/vice.h>
36
37 #include <afs/auth.h>
38 #include <afs/cellconfig.h>
39 #include <afs/afsutil.h>
40 #include <afs/cmd.h>
41
42 #undef VIRTUE
43 #undef VICE
44
45
46 struct tokenInfo {
47 struct ktc_token token;
48 struct ktc_principal service;
49 struct ktc_principal client;
50 int deleted;
51 };
52
53 static int unlog_ForgetCertainTokens(char **, int);
54 static int unlog_NormalizeCellNames(char **, int);
55 static int unlog_CheckUnlogList(char **, int, struct ktc_principal *);
56 static int unlog_VerifyUnlog(char **, int, struct tokenInfo *, int);
57
58 static int
59 CommandProc(struct cmd_syndesc *as, void *arock)
60 {
61 #define MAXCELLS 20 /* XXX */
62 struct cmd_item *itp;
63 afs_int32 code, i = 0;
64 char *cells[20];
65
66 if (as->parms[0].items) { /* A cell is provided */
67 for (itp = as->parms[0].items; itp; itp = itp->next) {
68 if (i >= MAXCELLS) {
69 printf
70 ("The maximum number of cells (%d) is exceeded; the rest are ignored\n",
71 MAXCELLS);
72 break;
73 }
74 cells[i++] = itp->data;
75 }
76 code = unlog_ForgetCertainTokens(cells, i);
77 } else
78 code = ktc_ForgetAllTokens();
79 if (code) {
80 printf("unlog: could not discard tickets, code %d\n", code);
81 exit(1);
82 }
83 return 0;
84 }
85
86
87 #include "AFS_component_version_number.c"
88
89 int
90 main(int argc, char *argv[])
91 { /*Main routine */
92 struct cmd_syndesc *ts;
93 afs_int32 code;
94
95 #ifdef AFS_AIX32_ENV
96 /*
97 * The following signal action for AIX is necessary so that in case of a
98 * crash (i.e. core is generated) we can include the user's data section
99 * in the core dump. Unfortunately, by default, only a partial core is
100 * generated which, in many cases, isn't too useful.
101 */
102 struct sigaction nsa;
103
104 sigemptyset(&nsa.sa_mask);
105 nsa.sa_handler = SIG_DFL;
106 nsa.sa_flags = SA_FULLDUMP;
107 sigaction(SIGSEGV, &nsa, NULL);
108 #endif
109
110 ts = cmd_CreateSyntax(NULL, CommandProc, NULL, 0,
111 "Release Kerberos authentication");
112 cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL, "cell name");
113
114 code = cmd_Dispatch(argc, argv);
115 exit(code != 0);
116 } /*Main routine */
117
118
119 /*
120 * Problem: only the KTC gives you the ability to selectively destroy
121 * a specified token.
122 *
123 * Solution: Build a list of tokens, delete the bad ones (the ones to
124 * remove from the permissions list,) destroy all tokens, and
125 * then re-register the good ones. Ugly, but it works.
126 */
127
128 static int
129 unlog_ForgetCertainTokens(char **list, int listSize)
130 {
131 int index, index2;
132 int count;
133 afs_int32 code;
134 struct ktc_principal serviceName;
135 struct tokenInfo *tokenInfoP;
136
137 /* normalize all the names in the list */
138 unlog_NormalizeCellNames(list, listSize);
139
140 /* figure out how many tokens exist */
141 count = 0;
142 do {
143 code = ktc_ListTokens(count, &count, &serviceName);
144 } while (!code);
145
146 tokenInfoP = malloc((sizeof(struct tokenInfo) * count));
147 if (!tokenInfoP) {
148 perror("unlog_ForgetCertainTokens -- osi_Alloc failed");
149 exit(1);
150 }
151
152 for (code = index = index2 = 0; (!code) && (index < count); index++) {
153 code =
154 ktc_ListTokens(index2, &index2, &(tokenInfoP + index)->service);
155
156 if (!code) {
157 code =
158 ktc_GetToken(&(tokenInfoP + index)->service,
159 &(tokenInfoP + index)->token,
160 sizeof(struct ktc_token),
161 &(tokenInfoP + index)->client);
162
163 if (!code)
164 (tokenInfoP + index)->deleted =
165 unlog_CheckUnlogList(list, listSize,
166 &(tokenInfoP + index)->client);
167 }
168 }
169
170 unlog_VerifyUnlog(list, listSize, tokenInfoP, count);
171 code = ktc_ForgetAllTokens();
172
173 if (code) {
174 printf("unlog: could not discard tickets, code %d\n", code);
175 exit(1);
176 }
177
178 for (code = index = 0; index < count; index++) {
179 if (!((tokenInfoP + index)->deleted)) {
180 code =
181 ktc_SetToken(&(tokenInfoP + index)->service,
182 &(tokenInfoP + index)->token,
183 &(tokenInfoP + index)->client, 0);
184 if (code) {
185 fprintf(stderr, "Couldn't re-register token, code = %d\n",
186 code);
187 }
188 }
189 }
190 return 0;
191 }
192
193 /*
194 * 0 if not in list, 1 if in list
195 */
196 int
197 unlog_CheckUnlogList(char **list, int count, struct ktc_principal *principal)
198 {
199 do {
200 if (strcmp(*list, principal->cell) == 0)
201 return 1;
202 list++;
203 --count;
204 } while (count);
205
206 return 0;
207 }
208
209 /*
210 * Caveat: this routine does NOT free up the memory passed (and replaced).
211 * because it assumes it isn't a problem.
212 */
213
214 int
215 unlog_NormalizeCellNames(char **list, int size)
216 {
217 char *newCellName;
218 unsigned index;
219 struct afsconf_dir *conf;
220 int code;
221 struct afsconf_cell cellinfo;
222
223 if (!(conf = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
224 fprintf(stderr, "Cannot get cell configuration info!\n");
225 exit(1);
226 }
227
228 for (index = 0; index < size; index++, list++) {
229 newCellName = malloc(MAXKTCREALMLEN);
230 if (!newCellName) {
231 perror("unlog_NormalizeCellNames --- malloc failed");
232 exit(1);
233 }
234
235 lcstring(newCellName, *list, MAXKTCREALMLEN);
236 code = afsconf_GetCellInfo(conf, newCellName, 0, &cellinfo);
237 if (code) {
238 if (code == AFSCONF_NOTFOUND) {
239 fprintf(stderr, "Unrecognized cell name %s\n", newCellName);
240 } else {
241 fprintf(stderr,
242 "unlog_NormalizeCellNames - afsconf_GetCellInfo");
243 fprintf(stderr, " failed, code = %d\n", code);
244 }
245 exit(1);
246 }
247
248
249 strcpy(newCellName, cellinfo.name);
250
251 *list = newCellName;
252 }
253 afsconf_Close(conf);
254 return 0;
255 }
256
257 /*
258 * check given list to assure tokens were held for specified cells
259 * prints warning messages for those cells without such entries.
260 */
261 int
262 unlog_VerifyUnlog(char **cellList, int cellListSize, struct tokenInfo *tokenList, int tokenListSize)
263 {
264 int index;
265
266 for (index = 0; index < cellListSize; index++) {
267 int index2;
268 int found;
269
270 for (found = index2 = 0; !found && index2 < tokenListSize; index2++)
271 found =
272 strcmp(cellList[index],
273 (tokenList + index2)->client.cell) == 0;
274
275 if (!found)
276 fprintf(stderr, "unlog: Warning - no tokens held for cell %s\n",
277 cellList[index]);
278 }
279 return 0;
280 }