pymessaging: Pass around the server_id struct to python callbacks rather than the...
[Samba/gebeck_regimport.git] / source3 / lib / afs_settoken.c
blob77d9ace3d3bf91a6ed59f739d1932c33cddba683
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 const 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 int proc_afs_file;
48 struct afsprocdata afs_syscall_data;
49 afs_syscall_data.syscall = subcall;
50 afs_syscall_data.param1 = (long)path;
51 afs_syscall_data.param2 = cmd;
52 afs_syscall_data.param3 = (long)cmarg;
53 afs_syscall_data.param4 = follow;
54 proc_afs_file = open(PROC_SYSCALL_FNAME, O_RDWR);
55 if (proc_afs_file < 0)
56 proc_afs_file = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
57 if (proc_afs_file < 0)
58 return -1;
59 errcode = ioctl(proc_afs_file, VIOC_SYSCALL, &afs_syscall_data);
60 close(proc_afs_file);
61 return errcode;
64 struct ClearToken {
65 uint32 AuthHandle;
66 char HandShakeKey[8];
67 uint32 ViceId;
68 uint32 BeginTimestamp;
69 uint32 EndTimestamp;
72 static bool afs_decode_token(const char *string, char **cell,
73 DATA_BLOB *ticket, struct ClearToken *ct)
75 DATA_BLOB blob;
76 struct ClearToken result_ct;
77 char *saveptr;
79 char *s = SMB_STRDUP(string);
81 char *t;
83 if ((t = strtok_r(s, "\n", &saveptr)) == NULL) {
84 DEBUG(10, ("strtok_r failed\n"));
85 return false;
88 *cell = SMB_STRDUP(t);
90 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
91 DEBUG(10, ("strtok_r failed\n"));
92 return false;
95 if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
96 DEBUG(10, ("sscanf AuthHandle failed\n"));
97 return false;
100 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
101 DEBUG(10, ("strtok_r failed\n"));
102 return false;
105 blob = base64_decode_data_blob(t);
107 if ( (blob.data == NULL) ||
108 (blob.length != sizeof(result_ct.HandShakeKey) )) {
109 DEBUG(10, ("invalid key: %x/%lu\n", (uint8_t)*blob.data,
110 (unsigned long) blob.length));
111 return false;
114 memcpy(result_ct.HandShakeKey, blob.data, blob.length);
116 data_blob_free(&blob);
118 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
119 DEBUG(10, ("strtok_r failed\n"));
120 return false;
123 if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
124 DEBUG(10, ("sscanf ViceId failed\n"));
125 return false;
128 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
129 DEBUG(10, ("strtok_r failed\n"));
130 return false;
133 if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
134 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
135 return false;
138 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
139 DEBUG(10, ("strtok_r failed\n"));
140 return false;
143 if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
144 DEBUG(10, ("sscanf EndTimestamp failed\n"));
145 return false;
148 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
149 DEBUG(10, ("strtok_r failed\n"));
150 return false;
153 blob = base64_decode_data_blob(t);
155 if (blob.data == NULL) {
156 DEBUG(10, ("Could not get ticket\n"));
157 return false;
160 *ticket = blob;
161 *ct = result_ct;
163 return true;
167 Put an AFS token into the Kernel so that it can authenticate against
168 the AFS server. This assumes correct local uid settings.
170 This is currently highly Linux and OpenAFS-specific. The correct API
171 call for this would be ktc_SetToken. But to do that we would have to
172 import a REALLY big bunch of libraries which I would currently like
173 to avoid.
176 static bool afs_settoken(const char *cell,
177 const struct ClearToken *ctok,
178 DATA_BLOB ticket)
180 int ret;
181 struct {
182 char *in, *out;
183 uint16 in_size, out_size;
184 } iob;
186 char buf[1024];
187 char *p = buf;
188 int tmp;
190 memcpy(p, &ticket.length, sizeof(uint32));
191 p += sizeof(uint32);
192 memcpy(p, ticket.data, ticket.length);
193 p += ticket.length;
195 tmp = sizeof(struct ClearToken);
196 memcpy(p, &tmp, sizeof(uint32));
197 p += sizeof(uint32);
198 memcpy(p, ctok, tmp);
199 p += tmp;
201 tmp = 0;
203 memcpy(p, &tmp, sizeof(uint32));
204 p += sizeof(uint32);
206 tmp = strlen(cell);
207 if (tmp >= MAXKTCREALMLEN) {
208 DEBUG(1, ("Realm too long\n"));
209 return false;
212 strncpy(p, cell, tmp);
213 p += tmp;
214 *p = 0;
215 p +=1;
217 iob.in = buf;
218 iob.in_size = PTR_DIFF(p,buf);
219 iob.out = buf;
220 iob.out_size = sizeof(buf);
222 #if 0
223 file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
224 #endif
226 ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
228 DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
229 return (ret == 0);
232 bool afs_settoken_str(const char *token_string)
234 DATA_BLOB ticket;
235 struct ClearToken ct;
236 bool result;
237 char *cell;
239 if (!afs_decode_token(token_string, &cell, &ticket, &ct))
240 return false;
242 if (geteuid() != sec_initial_uid())
243 ct.ViceId = getuid();
245 result = afs_settoken(cell, &ct, ticket);
247 SAFE_FREE(cell);
248 data_blob_free(&ticket);
250 return result;
253 #else
255 bool afs_settoken_str(const char *token_string)
257 return false;
260 #endif