2 * Unix SMB/CIFS implementation.
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/>.
21 #include "lib/afs/afs_settoken.h"
23 #ifdef WITH_FAKE_KASERVER
25 #define NO_ASN1_TYPEDEFS 1
27 #include "system/filesys.h"
29 #include <afs/param.h>
31 #include <afs/afs_args.h>
33 #include <afs/venus.h>
34 #include <asm/unistd.h>
35 #include <openssl/des.h>
36 #include <sys/syscall.h>
38 int afs_syscall(int subcall
, const char *path
, int cmd
, char *cmarg
, int follow
)
41 return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
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 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)
56 errcode
= ioctl(proc_afs_file
, VIOC_SYSCALL
, &afs_syscall_data
);
65 uint32 BeginTimestamp
;
69 static bool afs_decode_token(const char *string
, char **cell
,
70 DATA_BLOB
*ticket
, struct ClearToken
*ct
)
73 struct ClearToken result_ct
;
76 char *s
= SMB_STRDUP(string
);
80 if ((t
= strtok_r(s
, "\n", &saveptr
)) == NULL
) {
81 DEBUG(10, ("strtok_r failed\n"));
85 *cell
= SMB_STRDUP(t
);
87 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
88 DEBUG(10, ("strtok_r failed\n"));
92 if (sscanf(t
, "%u", &result_ct
.AuthHandle
) != 1) {
93 DEBUG(10, ("sscanf AuthHandle failed\n"));
97 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
98 DEBUG(10, ("strtok_r failed\n"));
102 blob
= base64_decode_data_blob(t
);
104 if ( (blob
.data
== NULL
) ||
105 (blob
.length
!= sizeof(result_ct
.HandShakeKey
) )) {
106 DEBUG(10, ("invalid key: %x/%lu\n", (uint8_t)*blob
.data
,
107 (unsigned long) blob
.length
));
111 memcpy(result_ct
.HandShakeKey
, blob
.data
, blob
.length
);
113 data_blob_free(&blob
);
115 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
116 DEBUG(10, ("strtok_r failed\n"));
120 if (sscanf(t
, "%u", &result_ct
.ViceId
) != 1) {
121 DEBUG(10, ("sscanf ViceId failed\n"));
125 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
126 DEBUG(10, ("strtok_r failed\n"));
130 if (sscanf(t
, "%u", &result_ct
.BeginTimestamp
) != 1) {
131 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
135 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
136 DEBUG(10, ("strtok_r failed\n"));
140 if (sscanf(t
, "%u", &result_ct
.EndTimestamp
) != 1) {
141 DEBUG(10, ("sscanf EndTimestamp failed\n"));
145 if ((t
= strtok_r(NULL
, "\n", &saveptr
)) == NULL
) {
146 DEBUG(10, ("strtok_r failed\n"));
150 blob
= base64_decode_data_blob(t
);
152 if (blob
.data
== NULL
) {
153 DEBUG(10, ("Could not get ticket\n"));
164 Put an AFS token into the Kernel so that it can authenticate against
165 the AFS server. This assumes correct local uid settings.
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
173 static bool afs_settoken(const char *cell
,
174 const struct ClearToken
*ctok
,
180 uint16 in_size
, out_size
;
187 memcpy(p
, &ticket
.length
, sizeof(uint32
));
189 memcpy(p
, ticket
.data
, ticket
.length
);
192 tmp
= sizeof(struct ClearToken
);
193 memcpy(p
, &tmp
, sizeof(uint32
));
195 memcpy(p
, ctok
, tmp
);
200 memcpy(p
, &tmp
, sizeof(uint32
));
204 if (tmp
>= MAXKTCREALMLEN
) {
205 DEBUG(1, ("Realm too long\n"));
209 strncpy(p
, cell
, tmp
);
215 iob
.in_size
= PTR_DIFF(p
,buf
);
217 iob
.out_size
= sizeof(buf
);
220 file_save("/tmp/ioctlbuf", iob
.in
, iob
.in_size
);
223 ret
= afs_syscall(AFSCALL_PIOCTL
, 0, VIOCSETTOK
, (char *)&iob
, 0);
225 DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret
));
229 bool afs_settoken_str(const char *token_string
)
232 struct ClearToken ct
;
236 if (!afs_decode_token(token_string
, &cell
, &ticket
, &ct
))
239 if (geteuid() != 0) {
240 ct
.ViceId
= geteuid();
243 result
= afs_settoken(cell
, &ct
, ticket
);
246 data_blob_free(&ticket
);
253 int afs_syscall(int subcall
, const char *path
, int cmd
, char *cmarg
, int follow
)
259 bool afs_settoken_str(const char *token_string
)