Commit | Line | Data |
---|---|---|
805e021f CE |
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 | } |