log: Tidy header includes
[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
34 #include <afs/vice.h>
35
36 #include <afs/auth.h>
37 #include <afs/cellconfig.h>
38 #include <afs/afsutil.h>
39 #include <afs/cmd.h>
40
41 #undef VIRTUE
42 #undef VICE
43
44
45 struct tokenInfo {
46     struct ktc_token token;
47     struct ktc_principal service;
48     struct ktc_principal client;
49     int deleted;
50 };
51
52 static int unlog_ForgetCertainTokens(char **, int);
53 static int unlog_NormalizeCellNames(char **, int);
54 static int unlog_CheckUnlogList(char **, int, struct ktc_principal *);
55 static int unlog_VerifyUnlog(char **, int, struct tokenInfo *, int);
56
57 static int
58 CommandProc(struct cmd_syndesc *as, void *arock)
59 {
60 #define MAXCELLS 20             /* XXX */
61     struct cmd_item *itp;
62     afs_int32 code, i = 0;
63     char *cells[20];
64
65     if (as->parms[0].items) {   /* A cell is provided */
66         for (itp = as->parms[0].items; itp; itp = itp->next) {
67             if (i > MAXCELLS) {
68                 printf
69                     ("The maximum number of cells (%d) is exceeded; the rest are ignored\n",
70                      MAXCELLS);
71                 break;
72             }
73             cells[i++] = itp->data;
74         }
75         code = unlog_ForgetCertainTokens(cells, i);
76     } else
77         code = ktc_ForgetAllTokens();
78     if (code) {
79         printf("unlog: could not discard tickets, code %d\n", code);
80         exit(1);
81     }
82     return 0;
83 }
84
85
86 #include "AFS_component_version_number.c"
87
88 int
89 main(int argc, char *argv[])
90 {                               /*Main routine */
91     struct cmd_syndesc *ts;
92     afs_int32 code;
93
94 #ifdef  AFS_AIX32_ENV
95     /*
96      * The following signal action for AIX is necessary so that in case of a
97      * crash (i.e. core is generated) we can include the user's data section
98      * in the core dump. Unfortunately, by default, only a partial core is
99      * generated which, in many cases, isn't too useful.
100      */
101     struct sigaction nsa;
102
103     sigemptyset(&nsa.sa_mask);
104     nsa.sa_handler = SIG_DFL;
105     nsa.sa_flags = SA_FULLDUMP;
106     sigaction(SIGSEGV, &nsa, NULL);
107 #endif
108
109     ts = cmd_CreateSyntax(NULL, CommandProc, NULL,
110                           "Release Kerberos authentication");
111     cmd_AddParm(ts, "-cell", CMD_LIST, CMD_OPTIONAL, "cell name");
112
113     code = cmd_Dispatch(argc, argv);
114     exit(code != 0);
115 }                               /*Main routine */
116
117
118 /*
119  * Problem: only the KTC gives you the ability to selectively destroy
120  *          a specified token.
121  *
122  * Solution: Build a list of tokens, delete the bad ones (the ones to
123  *           remove from the permissions list,) destroy all tokens, and
124  *           then re-register the good ones.  Ugly, but it works.
125  */
126
127 static int
128 unlog_ForgetCertainTokens(char **list, int listSize)
129 {
130     int index, index2;
131     int count;
132     afs_int32 code;
133     struct ktc_principal serviceName;
134     struct tokenInfo *tokenInfoP;
135
136     /* normalize all the names in the list */
137     unlog_NormalizeCellNames(list, listSize);
138
139     /* figure out how many tokens exist */
140     count = 0;
141     do {
142         code = ktc_ListTokens(count, &count, &serviceName);
143     } while (!code);
144
145     tokenInfoP =
146         (struct tokenInfo *)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 }