summaryrefslogtreecommitdiff
path: root/lib/afs
diff options
context:
space:
mode:
authorChristian Ambach <ambi@samba.org>2014-04-14 22:35:21 +0200
committerChristian Ambach <ambi@samba.org>2014-06-04 20:09:38 +0200
commit558850c495880a916fbc4285993e3adda590453f (patch)
tree79c04f9beafb82606ccad092a9500db10b7e746c /lib/afs
parent89961ca2972b087ae4a974ce223b75263ec1ee1f (diff)
downloadsamba-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.c1
-rw-r--r--lib/afs/afs_settoken.c264
-rw-r--r--lib/afs/afs_settoken.h21
-rw-r--r--lib/afs/wscript_build4
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')
+