source: branches/samba-3.5.x/source3/lib/afs_settoken.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 5.5 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/param.h>
27#include <afs/stds.h>
28#include <afs/afs.h>
29#include <afs/auth.h>
30#include <afs/venus.h>
31#include <asm/unistd.h>
32#include <openssl/des.h>
33#include <sys/syscall.h>
34
35int afs_syscall( int subcall,
36 char * path,
37 int cmd,
38 char * cmarg,
39 int follow)
40{
41/*
42 return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
43*/
44 int errcode;
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 int 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
61struct ClearToken {
62 uint32 AuthHandle;
63 char HandShakeKey[8];
64 uint32 ViceId;
65 uint32 BeginTimestamp;
66 uint32 EndTimestamp;
67};
68
69static 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/%d\n", (uint32)blob.data,
107 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
173static 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
229bool 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 = getuid();
241
242 result = afs_settoken(cell, &ct, ticket);
243
244 SAFE_FREE(cell);
245 data_blob_free(&ticket);
246
247 return result;
248}
249
250#else
251
252bool afs_settoken_str(const char *token_string)
253{
254 return False;
255}
256
257#endif
Note: See TracBrowser for help on using the repository browser.