r2023: If there's garbage in the pidfile, we should not panic but assume that no one
[tprouty/samba.git] / source / lib / afs_settoken.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Generate AFS tickets
4  *  Copyright (C) Volker Lendecke 2004
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *  
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *  
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "includes.h"
22
23 #ifdef WITH_FAKE_KASERVER
24
25 #include <afs/stds.h>
26 #include <afs/afs.h>
27 #include <afs/auth.h>
28 #include <afs/venus.h>
29 #include <asm/unistd.h>
30 #include <openssl/des.h>
31 #include <sys/syscall.h>
32
33 int afs_syscall( int subcall,
34           char * path,
35           int cmd,
36           char * cmarg,
37           int follow)
38 {
39         return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
40 }
41
42 struct ClearToken {
43         uint32 AuthHandle;
44         char HandShakeKey[8];
45         uint32 ViceId;
46         uint32 BeginTimestamp;
47         uint32 EndTimestamp;
48 };
49
50 static BOOL afs_decode_token(const char *string, char **cell,
51                              DATA_BLOB *ticket, struct ClearToken *ct)
52 {
53         DATA_BLOB blob;
54         struct ClearToken result_ct;
55
56         char *s = strdup(string);
57
58         char *t;
59
60         if ((t = strtok(s, "\n")) == NULL) {
61                 DEBUG(10, ("strtok failed\n"));
62                 return False;
63         }
64
65         *cell = strdup(t);
66
67         if ((t = strtok(NULL, "\n")) == NULL) {
68                 DEBUG(10, ("strtok failed\n"));
69                 return False;
70         }
71
72         if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
73                 DEBUG(10, ("sscanf AuthHandle failed\n"));
74                 return False;
75         }
76                 
77         if ((t = strtok(NULL, "\n")) == NULL) {
78                 DEBUG(10, ("strtok failed\n"));
79                 return False;
80         }
81
82         blob = base64_decode_data_blob(t);
83
84         if ( (blob.data == NULL) ||
85              (blob.length != sizeof(result_ct.HandShakeKey) )) {
86                 DEBUG(10, ("invalid key: %x/%d\n", (uint32)blob.data,
87                            blob.length));
88                 return False;
89         }
90
91         memcpy(result_ct.HandShakeKey, blob.data, blob.length);
92
93         data_blob_free(&blob);
94
95         if ((t = strtok(NULL, "\n")) == NULL) {
96                 DEBUG(10, ("strtok failed\n"));
97                 return False;
98         }
99
100         if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
101                 DEBUG(10, ("sscanf ViceId failed\n"));
102                 return False;
103         }
104                 
105         if ((t = strtok(NULL, "\n")) == NULL) {
106                 DEBUG(10, ("strtok failed\n"));
107                 return False;
108         }
109
110         if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
111                 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
112                 return False;
113         }
114                 
115         if ((t = strtok(NULL, "\n")) == NULL) {
116                 DEBUG(10, ("strtok failed\n"));
117                 return False;
118         }
119
120         if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
121                 DEBUG(10, ("sscanf EndTimestamp failed\n"));
122                 return False;
123         }
124                 
125         if ((t = strtok(NULL, "\n")) == NULL) {
126                 DEBUG(10, ("strtok failed\n"));
127                 return False;
128         }
129
130         blob = base64_decode_data_blob(t);
131
132         if (blob.data == NULL) {
133                 DEBUG(10, ("Could not get ticket\n"));
134                 return False;
135         }
136
137         *ticket = blob;
138         *ct = result_ct;
139
140         return True;
141 }
142
143 /*
144   Put an AFS token into the Kernel so that it can authenticate against
145   the AFS server. This assumes correct local uid settings.
146
147   This is currently highly Linux and OpenAFS-specific. The correct API
148   call for this would be ktc_SetToken. But to do that we would have to
149   import a REALLY big bunch of libraries which I would currently like
150   to avoid. 
151 */
152
153 static BOOL afs_settoken(const char *cell,
154                          const struct ClearToken *ctok,
155                          DATA_BLOB ticket)
156 {
157         int ret;
158         struct {
159                 char *in, *out;
160                 uint16 in_size, out_size;
161         } iob;
162
163         char buf[1024];
164         char *p = buf;
165         int tmp;
166
167         memcpy(p, &ticket.length, sizeof(uint32));
168         p += sizeof(uint32);
169         memcpy(p, ticket.data, ticket.length);
170         p += ticket.length;
171
172         tmp = sizeof(struct ClearToken);
173         memcpy(p, &tmp, sizeof(uint32));
174         p += sizeof(uint32);
175         memcpy(p, ctok, tmp);
176         p += tmp;
177
178         tmp = 0;
179
180         memcpy(p, &tmp, sizeof(uint32));
181         p += sizeof(uint32);
182
183         tmp = strlen(cell);
184         if (tmp >= MAXKTCREALMLEN) {
185                 DEBUG(1, ("Realm too long\n"));
186                 return False;
187         }
188
189         strncpy(p, cell, tmp);
190         p += tmp;
191         *p = 0;
192         p +=1;
193
194         iob.in = buf;
195         iob.in_size = PTR_DIFF(p,buf);
196         iob.out = buf;
197         iob.out_size = sizeof(buf);
198
199 #if 0
200         file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
201 #endif
202
203         ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
204
205         DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
206         return (ret == 0);
207 }
208
209 BOOL afs_settoken_str(const char *token_string)
210 {
211         DATA_BLOB ticket;
212         struct ClearToken ct;
213         BOOL result;
214         char *cell;
215
216         if (!afs_decode_token(token_string, &cell, &ticket, &ct))
217                 return False;
218
219         if (geteuid() != 0)
220                 ct.ViceId = getuid();
221
222         result = afs_settoken(cell, &ct, ticket);
223
224         SAFE_FREE(cell);
225         data_blob_free(&ticket);
226
227         return result;
228 }
229
230 #else
231
232 BOOL afs_settoken_str(const char *token_string)
233 {
234         return False;
235 }
236
237 #endif