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