source: branches/samba-3.2.x/source/lib/afs_settoken.c

Last change on this file was 133, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0pre3

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