ctdb-daemon: Do not allow database detach if AllowClientDBAttach=1
[Samba.git] / source3 / lib / afs_settoken.c
blob7aff55fd762278bf74a82f4ecf6dda5fabfe66d2
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, const char *path, int cmd, char *cmarg, int follow)
40 return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
42 int errcode;
43 int proc_afs_file;
44 struct afsprocdata afs_syscall_data;
45 afs_syscall_data.syscall = subcall;
46 afs_syscall_data.param1 = (long)path;
47 afs_syscall_data.param2 = cmd;
48 afs_syscall_data.param3 = (long)cmarg;
49 afs_syscall_data.param4 = follow;
50 proc_afs_file = open(PROC_SYSCALL_FNAME, O_RDWR);
51 if (proc_afs_file < 0)
52 proc_afs_file = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
53 if (proc_afs_file < 0)
54 return -1;
55 errcode = ioctl(proc_afs_file, VIOC_SYSCALL, &afs_syscall_data);
56 close(proc_afs_file);
57 return errcode;
60 struct ClearToken {
61 uint32 AuthHandle;
62 char HandShakeKey[8];
63 uint32 ViceId;
64 uint32 BeginTimestamp;
65 uint32 EndTimestamp;
68 static bool afs_decode_token(const char *string, char **cell,
69 DATA_BLOB *ticket, struct ClearToken *ct)
71 DATA_BLOB blob;
72 struct ClearToken result_ct;
73 char *saveptr;
75 char *s = SMB_STRDUP(string);
77 char *t;
79 if ((t = strtok_r(s, "\n", &saveptr)) == NULL) {
80 DEBUG(10, ("strtok_r failed\n"));
81 return false;
84 *cell = SMB_STRDUP(t);
86 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
87 DEBUG(10, ("strtok_r failed\n"));
88 return false;
91 if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
92 DEBUG(10, ("sscanf AuthHandle failed\n"));
93 return false;
96 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
97 DEBUG(10, ("strtok_r failed\n"));
98 return false;
101 blob = base64_decode_data_blob(t);
103 if ( (blob.data == NULL) ||
104 (blob.length != sizeof(result_ct.HandShakeKey) )) {
105 DEBUG(10, ("invalid key: %x/%lu\n", (uint8_t)*blob.data,
106 (unsigned long) blob.length));
107 return false;
110 memcpy(result_ct.HandShakeKey, blob.data, blob.length);
112 data_blob_free(&blob);
114 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
115 DEBUG(10, ("strtok_r failed\n"));
116 return false;
119 if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
120 DEBUG(10, ("sscanf ViceId failed\n"));
121 return false;
124 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
125 DEBUG(10, ("strtok_r failed\n"));
126 return false;
129 if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
130 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
131 return false;
134 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
135 DEBUG(10, ("strtok_r failed\n"));
136 return false;
139 if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
140 DEBUG(10, ("sscanf EndTimestamp failed\n"));
141 return false;
144 if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
145 DEBUG(10, ("strtok_r failed\n"));
146 return false;
149 blob = base64_decode_data_blob(t);
151 if (blob.data == NULL) {
152 DEBUG(10, ("Could not get ticket\n"));
153 return false;
156 *ticket = blob;
157 *ct = result_ct;
159 return true;
163 Put an AFS token into the Kernel so that it can authenticate against
164 the AFS server. This assumes correct local uid settings.
166 This is currently highly Linux and OpenAFS-specific. The correct API
167 call for this would be ktc_SetToken. But to do that we would have to
168 import a REALLY big bunch of libraries which I would currently like
169 to avoid.
172 static bool afs_settoken(const char *cell,
173 const struct ClearToken *ctok,
174 DATA_BLOB ticket)
176 int ret;
177 struct {
178 char *in, *out;
179 uint16 in_size, out_size;
180 } iob;
182 char buf[1024];
183 char *p = buf;
184 int tmp;
186 memcpy(p, &ticket.length, sizeof(uint32));
187 p += sizeof(uint32);
188 memcpy(p, ticket.data, ticket.length);
189 p += ticket.length;
191 tmp = sizeof(struct ClearToken);
192 memcpy(p, &tmp, sizeof(uint32));
193 p += sizeof(uint32);
194 memcpy(p, ctok, tmp);
195 p += tmp;
197 tmp = 0;
199 memcpy(p, &tmp, sizeof(uint32));
200 p += sizeof(uint32);
202 tmp = strlen(cell);
203 if (tmp >= MAXKTCREALMLEN) {
204 DEBUG(1, ("Realm too long\n"));
205 return false;
208 strncpy(p, cell, tmp);
209 p += tmp;
210 *p = 0;
211 p +=1;
213 iob.in = buf;
214 iob.in_size = PTR_DIFF(p,buf);
215 iob.out = buf;
216 iob.out_size = sizeof(buf);
218 #if 0
219 file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
220 #endif
222 ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
224 DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
225 return (ret == 0);
228 bool afs_settoken_str(const char *token_string)
230 DATA_BLOB ticket;
231 struct ClearToken ct;
232 bool result;
233 char *cell;
235 if (!afs_decode_token(token_string, &cell, &ticket, &ct))
236 return false;
238 if (geteuid() != sec_initial_uid())
239 ct.ViceId = getuid();
241 result = afs_settoken(cell, &ct, ticket);
243 SAFE_FREE(cell);
244 data_blob_free(&ticket);
246 return result;
249 #else
251 int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow)
253 errno = ENOSYS;
254 return -1;
257 bool afs_settoken_str(const char *token_string)
259 return false;
262 #endif