9e39ce6cf68aa91a6ff191a3580f2a9db8424b03
[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,
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 =
147         (struct tokenInfo *)malloc((sizeof(struct tokenInfo) * count));
148     if (!tokenInfoP) {
149         perror("unlog_ForgetCertainTokens -- osi_Alloc failed");
150         exit(1);
151     }
152
153     for (code = index = index2 = 0; (!code) && (index < count); index++) {
154         code =
155             ktc_ListTokens(index2, &index2, &(tokenInfoP + index)->service);
156
157         if (!code) {
158             code =
159                 ktc_GetToken(&(tokenInfoP + index)->service,
160                              &(tokenInfoP + index)->token,
161                              sizeof(struct ktc_token),
162                              &(tokenInfoP + index)->client);
163
164             if (!code)
165                 (tokenInfoP + index)->deleted =
166                     unlog_CheckUnlogList(list, listSize,
167                                          &(tokenInfoP + index)->client);
168         }
169     }
170
171     unlog_VerifyUnlog(list, listSize, tokenInfoP, count);
172     code = ktc_ForgetAllTokens();
173
174     if (code) {
175         printf("unlog: could not discard tickets, code %d\n", code);
176         exit(1);
177     }
178
179     for (code = index = 0; index < count; index++) {
180         if (!((tokenInfoP + index)->deleted)) {
181             code =
182                 ktc_SetToken(&(tokenInfoP + index)->service,
183                              &(tokenInfoP + index)->token,
184                              &(tokenInfoP + index)->client, 0);
185             if (code) {
186                 fprintf(stderr, "Couldn't re-register token, code = %d\n",
187                         code);
188             }
189         }
190     }
191     return 0;
192 }
193
194 /*
195  * 0 if not in list, 1 if in list
196  */
197 int
198 unlog_CheckUnlogList(char **list, int count, struct ktc_principal *principal)
199 {
200     do {
201         if (strcmp(*list, principal->cell) == 0)
202             return 1;
203         list++;
204         --count;
205     } while (count);
206
207     return 0;
208 }
209
210 /*
211  * Caveat: this routine does NOT free up the memory passed (and replaced).
212  *         because it assumes it isn't a problem.
213  */
214
215 int
216 unlog_NormalizeCellNames(char **list, int size)
217 {
218     char *newCellName;
219     unsigned index;
220     struct afsconf_dir *conf;
221     int code;
222     struct afsconf_cell cellinfo;
223
224     if (!(conf = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
225         fprintf(stderr, "Cannot get cell configuration info!\n");
226         exit(1);
227     }
228
229     for (index = 0; index < size; index++, list++) {
230         newCellName = malloc(MAXKTCREALMLEN);
231         if (!newCellName) {
232             perror("unlog_NormalizeCellNames --- malloc failed");
233             exit(1);
234         }
235
236         lcstring(newCellName, *list, MAXKTCREALMLEN);
237         code = afsconf_GetCellInfo(conf, newCellName, 0, &cellinfo);
238         if (code) {
239             if (code == AFSCONF_NOTFOUND) {
240                 fprintf(stderr, "Unrecognized cell name %s\n", newCellName);
241             } else {
242                 fprintf(stderr,
243                         "unlog_NormalizeCellNames - afsconf_GetCellInfo");
244                 fprintf(stderr, " failed, code = %d\n", code);
245             }
246             exit(1);
247         }
248
249
250         strcpy(newCellName, cellinfo.name);
251
252         *list = newCellName;
253     }
254     afsconf_Close(conf);
255     return 0;
256 }
257
258 /*
259  * check given list to assure tokens were held for specified cells
260  * prints warning messages for those cells without such entries.
261  */
262 int
263 unlog_VerifyUnlog(char **cellList, int cellListSize, struct tokenInfo *tokenList, int tokenListSize)
264 {
265     int index;
266
267     for (index = 0; index < cellListSize; index++) {
268         int index2;
269         int found;
270
271         for (found = index2 = 0; !found && index2 < tokenListSize; index2++)
272             found =
273                 strcmp(cellList[index],
274                        (tokenList + index2)->client.cell) == 0;
275
276         if (!found)
277             fprintf(stderr, "unlog: Warning - no tokens held for cell %s\n",
278                     cellList[index]);
279     }
280     return 0;
281 }