s3:lib/afs fix the build with --with-fake-kaserver
[Samba.git] / source3 / lib / afs_settoken.c
blob149fc66b0e449f36a8858050823343b7e1988743
1 /*
2 * Unix SMB/CIFS implementation.
3 * Generate AFS tickets
4 * Copyright (C) Volker Lendecke 2004
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.
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.
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/>.
20 #include "includes.h"
22 #ifdef WITH_FAKE_KASERVER
24 #define NO_ASN1_TYPEDEFS 1
26 #include "system/filesys.h"
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>
37 int afs_syscall( int subcall,
38 char * path,
39 int cmd,
40 char * cmarg,
41 int follow)
44 return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
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;
63 struct ClearToken {
64 uint32 AuthHandle;
65 char HandShakeKey[8];
66 uint32 ViceId;
67 uint32 BeginTimestamp;
68 uint32 EndTimestamp;
71 static bool afs_decode_token(const char *string, char **cell,
72 DATA_BLOB *ticket, struct ClearToken *ct)
74 DATA_BLOB blob;
75 struct ClearToken result_ct;
76 char *saveptr;
78 char *s = SMB_STRDUP(string);
80 char *t;
82 if ((t = strtok_r(s, "\n", &saveptr)) == NULL) {
83 DEBUG(10, ("strtok_r failed\n"));
84 return False;
87 *cell = SMB_STRDUP(t);
89 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
90 DEBUG(10, ("strtok_r failed\n"));
91 return False;
94 if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
95 DEBUG(10, ("sscanf AuthHandle failed\n"));
96 return False;
99 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
100 DEBUG(10, ("strtok_r failed\n"));
101 return False;
104 blob = base64_decode_data_blob(t);
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;
113 memcpy(result_ct.HandShakeKey, blob.data, blob.length);
115 data_blob_free(&blob);
117 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
118 DEBUG(10, ("strtok_r failed\n"));
119 return False;
122 if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
123 DEBUG(10, ("sscanf ViceId failed\n"));
124 return False;
127 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
128 DEBUG(10, ("strtok_r failed\n"));
129 return False;
132 if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
133 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
134 return False;
137 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
138 DEBUG(10, ("strtok_r failed\n"));
139 return False;
142 if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
143 DEBUG(10, ("sscanf EndTimestamp failed\n"));
144 return False;
147 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
148 DEBUG(10, ("strtok_r failed\n"));
149 return False;
152 blob = base64_decode_data_blob(t);
154 if (blob.data == NULL) {
155 DEBUG(10, ("Could not get ticket\n"));
156 return False;
159 *ticket = blob;
160 *ct = result_ct;
162 return True;
166 Put an AFS token into the Kernel so that it can authenticate against
167 the AFS server. This assumes correct local uid settings.
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.
175 static bool afs_settoken(const char *cell,
176 const struct ClearToken *ctok,
177 DATA_BLOB ticket)
179 int ret;
180 struct {
181 char *in, *out;
182 uint16 in_size, out_size;
183 } iob;
185 char buf[1024];
186 char *p = buf;
187 int tmp;
189 memcpy(p, &ticket.length, sizeof(uint32));
190 p += sizeof(uint32);
191 memcpy(p, ticket.data, ticket.length);
192 p += ticket.length;
194 tmp = sizeof(struct ClearToken);
195 memcpy(p, &tmp, sizeof(uint32));
196 p += sizeof(uint32);
197 memcpy(p, ctok, tmp);
198 p += tmp;
200 tmp = 0;
202 memcpy(p, &tmp, sizeof(uint32));
203 p += sizeof(uint32);
205 tmp = strlen(cell);
206 if (tmp >= MAXKTCREALMLEN) {
207 DEBUG(1, ("Realm too long\n"));
208 return False;
211 strncpy(p, cell, tmp);
212 p += tmp;
213 *p = 0;
214 p +=1;
216 iob.in = buf;
217 iob.in_size = PTR_DIFF(p,buf);
218 iob.out = buf;
219 iob.out_size = sizeof(buf);
221 #if 0
222 file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
223 #endif
225 ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
227 DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
228 return (ret == 0);
231 bool afs_settoken_str(const char *token_string)
233 DATA_BLOB ticket;
234 struct ClearToken ct;
235 bool result;
236 char *cell;
238 if (!afs_decode_token(token_string, &cell, &ticket, &ct))
239 return False;
241 if (geteuid() != sec_initial_uid())
242 ct.ViceId = getuid();
244 result = afs_settoken(cell, &ct, ticket);
246 SAFE_FREE(cell);
247 data_blob_free(&ticket);
249 return result;
252 #else
254 bool afs_settoken_str(const char *token_string)
256 return False;
259 #endif