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