source: vendor/3.6.24/source3/lib/afs_settoken.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

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