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