diff options
author | Christian Ambach <ambi@samba.org> | 2014-04-14 22:35:21 +0200 |
---|---|---|
committer | Christian Ambach <ambi@samba.org> | 2014-06-04 20:09:38 +0200 |
commit | 558850c495880a916fbc4285993e3adda590453f (patch) | |
tree | 79c04f9beafb82606ccad092a9500db10b7e746c /lib/afs | |
parent | 89961ca2972b087ae4a974ce223b75263ec1ee1f (diff) | |
download | samba-558850c495880a916fbc4285993e3adda590453f.tar.gz |
s3:lib/afs move afs_settoken.c to common lib dir
Signed-off-by: Christian Ambach <ambi@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'lib/afs')
-rw-r--r-- | lib/afs/afs_funcs.c | 1 | ||||
-rw-r--r-- | lib/afs/afs_settoken.c | 264 | ||||
-rw-r--r-- | lib/afs/afs_settoken.h | 21 | ||||
-rw-r--r-- | lib/afs/wscript_build | 4 |
4 files changed, 290 insertions, 0 deletions
diff --git a/lib/afs/afs_funcs.c b/lib/afs/afs_funcs.c index 316bb1b5ec1..8a3c90a47e5 100644 --- a/lib/afs/afs_funcs.c +++ b/lib/afs/afs_funcs.c @@ -28,6 +28,7 @@ #include "passdb.h" #include "auth.h" #include "../librpc/gen_ndr/ndr_netlogon.h" +#include "lib/afs/afs_settoken.h" #include <afs/param.h> #include <afs/stds.h> diff --git a/lib/afs/afs_settoken.c b/lib/afs/afs_settoken.c new file mode 100644 index 00000000000..d0ffa49567f --- /dev/null +++ b/lib/afs/afs_settoken.c @@ -0,0 +1,264 @@ +/* + * Unix SMB/CIFS implementation. + * Generate AFS tickets + * Copyright (C) Volker Lendecke 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" +#include "lib/afs/afs_settoken.h" + +#ifdef WITH_FAKE_KASERVER + +#define NO_ASN1_TYPEDEFS 1 + +#include "system/filesys.h" + +#include <afs/param.h> +#include <afs/stds.h> +#include <afs/afs_args.h> +#include <afs/auth.h> +#include <afs/venus.h> +#include <asm/unistd.h> +#include <openssl/des.h> +#include <sys/syscall.h> + +int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow) +{ +/* + return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow)); +*/ + int errcode; + int proc_afs_file; + struct afsprocdata afs_syscall_data; + afs_syscall_data.syscall = subcall; + afs_syscall_data.param1 = (long)path; + afs_syscall_data.param2 = cmd; + afs_syscall_data.param3 = (long)cmarg; + afs_syscall_data.param4 = follow; + proc_afs_file = open(PROC_SYSCALL_FNAME, O_RDWR); + if (proc_afs_file < 0) + proc_afs_file = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR); + if (proc_afs_file < 0) + return -1; + errcode = ioctl(proc_afs_file, VIOC_SYSCALL, &afs_syscall_data); + close(proc_afs_file); + return errcode; +} + +struct ClearToken { + uint32 AuthHandle; + char HandShakeKey[8]; + uint32 ViceId; + uint32 BeginTimestamp; + uint32 EndTimestamp; +}; + +static bool afs_decode_token(const char *string, char **cell, + DATA_BLOB *ticket, struct ClearToken *ct) +{ + DATA_BLOB blob; + struct ClearToken result_ct; + char *saveptr; + + char *s = SMB_STRDUP(string); + + char *t; + + if ((t = strtok_r(s, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + *cell = SMB_STRDUP(t); + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) { + DEBUG(10, ("sscanf AuthHandle failed\n")); + return false; + } + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + blob = base64_decode_data_blob(t); + + if ( (blob.data == NULL) || + (blob.length != sizeof(result_ct.HandShakeKey) )) { + DEBUG(10, ("invalid key: %x/%lu\n", (uint8_t)*blob.data, + (unsigned long) blob.length)); + return false; + } + + memcpy(result_ct.HandShakeKey, blob.data, blob.length); + + data_blob_free(&blob); + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + if (sscanf(t, "%u", &result_ct.ViceId) != 1) { + DEBUG(10, ("sscanf ViceId failed\n")); + return false; + } + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) { + DEBUG(10, ("sscanf BeginTimestamp failed\n")); + return false; + } + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) { + DEBUG(10, ("sscanf EndTimestamp failed\n")); + return false; + } + + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); + return false; + } + + blob = base64_decode_data_blob(t); + + if (blob.data == NULL) { + DEBUG(10, ("Could not get ticket\n")); + return false; + } + + *ticket = blob; + *ct = result_ct; + + return true; +} + +/* + Put an AFS token into the Kernel so that it can authenticate against + the AFS server. This assumes correct local uid settings. + + This is currently highly Linux and OpenAFS-specific. The correct API + call for this would be ktc_SetToken. But to do that we would have to + import a REALLY big bunch of libraries which I would currently like + to avoid. +*/ + +static bool afs_settoken(const char *cell, + const struct ClearToken *ctok, + DATA_BLOB ticket) +{ + int ret; + struct { + char *in, *out; + uint16 in_size, out_size; + } iob; + + char buf[1024]; + char *p = buf; + int tmp; + + memcpy(p, &ticket.length, sizeof(uint32)); + p += sizeof(uint32); + memcpy(p, ticket.data, ticket.length); + p += ticket.length; + + tmp = sizeof(struct ClearToken); + memcpy(p, &tmp, sizeof(uint32)); + p += sizeof(uint32); + memcpy(p, ctok, tmp); + p += tmp; + + tmp = 0; + + memcpy(p, &tmp, sizeof(uint32)); + p += sizeof(uint32); + + tmp = strlen(cell); + if (tmp >= MAXKTCREALMLEN) { + DEBUG(1, ("Realm too long\n")); + return false; + } + + strncpy(p, cell, tmp); + p += tmp; + *p = 0; + p +=1; + + iob.in = buf; + iob.in_size = PTR_DIFF(p,buf); + iob.out = buf; + iob.out_size = sizeof(buf); + +#if 0 + file_save("/tmp/ioctlbuf", iob.in, iob.in_size); +#endif + + ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0); + + DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret)); + return (ret == 0); +} + +bool afs_settoken_str(const char *token_string) +{ + DATA_BLOB ticket; + struct ClearToken ct; + bool result; + char *cell; + + if (!afs_decode_token(token_string, &cell, &ticket, &ct)) + return false; + + if (geteuid() != 0) { + ct.ViceId = geteuid(); + } + + result = afs_settoken(cell, &ct, ticket); + + SAFE_FREE(cell); + data_blob_free(&ticket); + + return result; +} + +#else + +int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow) +{ + errno = ENOSYS; + return -1; +} + +bool afs_settoken_str(const char *token_string) +{ + return false; +} + +#endif diff --git a/lib/afs/afs_settoken.h b/lib/afs/afs_settoken.h new file mode 100644 index 00000000000..d6cc4621a76 --- /dev/null +++ b/lib/afs/afs_settoken.h @@ -0,0 +1,21 @@ +/* + * Unix SMB/CIFS implementation. + * Generate AFS tickets + * Copyright (C) Volker Lendecke 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +int afs_syscall(int subcall, const char *path, int cmd, char *cmarg, int follow); +bool afs_settoken_str(const char *token_string); diff --git a/lib/afs/wscript_build b/lib/afs/wscript_build index 45d8be5795f..7337491fe7c 100644 --- a/lib/afs/wscript_build +++ b/lib/afs/wscript_build @@ -4,3 +4,7 @@ bld.SAMBA3_SUBSYSTEM('LIBAFS', source='afs_funcs.c', deps='samba-util LIBAFS_SETTOKEN') +bld.SAMBA3_SUBSYSTEM('LIBAFS_SETTOKEN', + source='afs_settoken.c', + deps='samba-util') + |