Line data Source code
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 3 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, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "lib/afs/afs_settoken.h"
22 :
23 : #ifdef WITH_FAKE_KASERVER
24 :
25 : #define NO_ASN1_TYPEDEFS 1
26 :
27 : #include "system/filesys.h"
28 :
29 : #include <afs/param.h>
30 : #include <afs/stds.h>
31 : #include <afs/afs_args.h>
32 : #include <afs/auth.h>
33 : #include <afs/venus.h>
34 : #include <asm/unistd.h>
35 : #include <openssl/des.h>
36 : #include <sys/syscall.h>
37 :
38 : int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow)
39 : {
40 : /*
41 : return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
42 : */
43 : int errcode;
44 : int proc_afs_file;
45 : struct afsprocdata afs_syscall_data;
46 : afs_syscall_data.syscall = subcall;
47 : afs_syscall_data.param1 = (long)path;
48 : afs_syscall_data.param2 = cmd;
49 : afs_syscall_data.param3 = (long)cmarg;
50 : afs_syscall_data.param4 = follow;
51 : proc_afs_file = open(PROC_SYSCALL_FNAME, O_RDWR);
52 : if (proc_afs_file < 0)
53 : proc_afs_file = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
54 : if (proc_afs_file < 0)
55 : return -1;
56 : errcode = ioctl(proc_afs_file, VIOC_SYSCALL, &afs_syscall_data);
57 : close(proc_afs_file);
58 : return errcode;
59 : }
60 :
61 : struct ClearToken {
62 : uint32 AuthHandle;
63 : char HandShakeKey[8];
64 : uint32 ViceId;
65 : uint32 BeginTimestamp;
66 : uint32 EndTimestamp;
67 : };
68 :
69 : static bool afs_decode_token(const char *string, char **cell,
70 : DATA_BLOB *ticket, struct ClearToken *ct)
71 : {
72 : DATA_BLOB blob;
73 : struct ClearToken result_ct;
74 : char *saveptr;
75 :
76 : char *s = SMB_STRDUP(string);
77 :
78 : char *t;
79 :
80 : if ((t = strtok_r(s, "\n", &saveptr)) == NULL) {
81 : DEBUG(10, ("strtok_r failed\n"));
82 : return false;
83 : }
84 :
85 : *cell = SMB_STRDUP(t);
86 :
87 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
88 : DEBUG(10, ("strtok_r failed\n"));
89 : return false;
90 : }
91 :
92 : if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
93 : DEBUG(10, ("sscanf AuthHandle failed\n"));
94 : return false;
95 : }
96 :
97 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
98 : DEBUG(10, ("strtok_r failed\n"));
99 : return false;
100 : }
101 :
102 : blob = base64_decode_data_blob(t);
103 :
104 : if ( (blob.data == NULL) ||
105 : (blob.length != sizeof(result_ct.HandShakeKey) )) {
106 : DEBUG(10, ("invalid key: %x/%lu\n", (uint8_t)*blob.data,
107 : (unsigned long) blob.length));
108 : return false;
109 : }
110 :
111 : memcpy(result_ct.HandShakeKey, blob.data, blob.length);
112 :
113 : data_blob_free(&blob);
114 :
115 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
116 : DEBUG(10, ("strtok_r failed\n"));
117 : return false;
118 : }
119 :
120 : if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
121 : DEBUG(10, ("sscanf ViceId failed\n"));
122 : return false;
123 : }
124 :
125 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
126 : DEBUG(10, ("strtok_r failed\n"));
127 : return false;
128 : }
129 :
130 : if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
131 : DEBUG(10, ("sscanf BeginTimestamp failed\n"));
132 : return false;
133 : }
134 :
135 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
136 : DEBUG(10, ("strtok_r failed\n"));
137 : return false;
138 : }
139 :
140 : if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
141 : DEBUG(10, ("sscanf EndTimestamp failed\n"));
142 : return false;
143 : }
144 :
145 : if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
146 : DEBUG(10, ("strtok_r failed\n"));
147 : return false;
148 : }
149 :
150 : blob = base64_decode_data_blob(t);
151 :
152 : if (blob.data == NULL) {
153 : DEBUG(10, ("Could not get ticket\n"));
154 : return false;
155 : }
156 :
157 : *ticket = blob;
158 : *ct = result_ct;
159 :
160 : return true;
161 : }
162 :
163 : /*
164 : Put an AFS token into the Kernel so that it can authenticate against
165 : the AFS server. This assumes correct local uid settings.
166 :
167 : This is currently highly Linux and OpenAFS-specific. The correct API
168 : call for this would be ktc_SetToken. But to do that we would have to
169 : import a REALLY big bunch of libraries which I would currently like
170 : to avoid.
171 : */
172 :
173 : static bool afs_settoken(const char *cell,
174 : const struct ClearToken *ctok,
175 : DATA_BLOB ticket)
176 : {
177 : int ret;
178 : struct {
179 : char *in, *out;
180 : uint16 in_size, out_size;
181 : } iob;
182 :
183 : char buf[1024];
184 : char *p = buf;
185 : int tmp;
186 :
187 : memcpy(p, &ticket.length, sizeof(uint32));
188 : p += sizeof(uint32);
189 : memcpy(p, ticket.data, ticket.length);
190 : p += ticket.length;
191 :
192 : tmp = sizeof(struct ClearToken);
193 : memcpy(p, &tmp, sizeof(uint32));
194 : p += sizeof(uint32);
195 : memcpy(p, ctok, tmp);
196 : p += tmp;
197 :
198 : tmp = 0;
199 :
200 : memcpy(p, &tmp, sizeof(uint32));
201 : p += sizeof(uint32);
202 :
203 : tmp = strlen(cell);
204 : if (tmp >= MAXKTCREALMLEN) {
205 : DEBUG(1, ("Realm too long\n"));
206 : return false;
207 : }
208 :
209 : strncpy(p, cell, tmp);
210 : p += tmp;
211 : *p = 0;
212 : p +=1;
213 :
214 : iob.in = buf;
215 : iob.in_size = PTR_DIFF(p,buf);
216 : iob.out = buf;
217 : iob.out_size = sizeof(buf);
218 :
219 : #if 0
220 : file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
221 : #endif
222 :
223 : ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
224 :
225 : DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
226 : return (ret == 0);
227 : }
228 :
229 : bool afs_settoken_str(const char *token_string)
230 : {
231 : DATA_BLOB ticket;
232 : struct ClearToken ct;
233 : bool result;
234 : char *cell;
235 :
236 : if (!afs_decode_token(token_string, &cell, &ticket, &ct))
237 : return false;
238 :
239 : if (geteuid() != 0) {
240 : ct.ViceId = geteuid();
241 : }
242 :
243 : result = afs_settoken(cell, &ct, ticket);
244 :
245 : SAFE_FREE(cell);
246 : data_blob_free(&ticket);
247 :
248 : return result;
249 : }
250 :
251 : #else
252 :
253 0 : int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow)
254 : {
255 0 : errno = ENOSYS;
256 0 : return -1;
257 : }
258 :
259 0 : bool afs_settoken_str(const char *token_string)
260 : {
261 0 : return false;
262 : }
263 :
264 : #endif
|