Commit 68938182 authored by Volker Lendecke's avatar Volker Lendecke Committed by Gerald (Jerry) Carter
Browse files

r449: Two AFS-related things:

Split off the non-crypto related parts of lib/afs.c into
lib/afs_settoken.c. This makes wbinfo link without -lcrypto.

Commit vfs_afsacl.c, display & set AFS acls via the NT security editor.

Volker
(This used to be commit 43870a3fc1073cf7d60f1becae5c2ff98ab49439)
parent 5c2cd8aa
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -322,6 +322,7 @@ VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
VFS_CAP_OBJ = modules/vfs_cap.o
VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
VFS_AFSACL_OBJ = modules/vfs_afsacl.o

PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o

@@ -362,6 +363,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
	       lib/sysquotas_xfs.o lib/sysquotas_4A.o \
	       smbd/change_trust_pw.o smbd/fake_file.o \
	       smbd/quotas.o smbd/ntquotas.o lib/afs.o smbd/msdfs.o \
	       lib/afs_settoken.o \
	       $(MANGLE_OBJ) @VFS_STATIC@

SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
@@ -514,7 +516,8 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
	  $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
	  $(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
	  $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
	  $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o lib/afs.o
	  $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o \
	  lib/afs.o lib/afs_settoken.o

CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
	  $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
@@ -637,10 +640,11 @@ WINBINDD_OBJ = \
		$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
		$(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
		$(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
		$(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o lib/afs.o
		$(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o \
		lib/afs.o lib/afs_settoken.o

WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
		$(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) lib/afs.o
		$(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) lib/afs_settoken.o

WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@

@@ -1189,6 +1193,11 @@ bin/expand_msdfs.@SHLIBEXT@: $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@)
	@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_EXPAND_MSDFS_OBJ:.o=.@PICSUFFIX@) \
		@SONAMEFLAG@`basename $@`

bin/afsacl.@SHLIBEXT@: $(VFS_AFSACL_OBJ:.o=.po)
	@echo "Building plugin $@"
	@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_AFSACL_OBJ:.o=.po) \
		@SONAMEFLAG@`basename $@`

bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
	@echo Linking $@
	@$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
+23 −4
Original line number Diff line number Diff line
@@ -2377,14 +2377,32 @@ if test x"$samba_cv_WITH_AFS" != x"no" ||
    fi
fi

if test x"$samba_cv_WITH_FAKE_KASERVER" != x"no"; then
	AC_CHECK_LIB( crypto, DES_pcbc_encrypt, LIBS="$LIBS -lcrypto" )
fi

if test x"$samba_cv_WITH_FAKE_KASERVER" != x"no" && test x"$have_afs_headers" == x"yes"; then
    AC_DEFINE(WITH_FAKE_KASERVER,1,[Whether to include AFS fake-kaserver support])
fi

#################################################
# check whether to compile AFS/NT ACL mapping module
samba_cv_WITH_VFS_AFSACL=no
AC_MSG_CHECKING(whether to use AFS fake-kaserver)
AC_ARG_WITH(vfs-afsacl,
[  --with-vfs-afsacl       Include AFS to NT ACL mapping module (default=no) ],
[ case "$withval" in
  yes|auto)
    AC_MSG_RESULT($withval)
    samba_cv_WITH_VFS_AFSACL=yes
    ;;
  *)
    AC_MSG_RESULT(no)
    ;;
  esac ],
  AC_MSG_RESULT(no)
)

if test x"$samba_cv_WITH_VFS_AFSACL" == x"yes"; then
   default_shared_modules="$default_shared_modules vfs_afsacl"
fi
	
if test x"$samba_cv_WITH_AFS" != x"no" && test x"$have_afs_headers" = x"yes"; then
    AC_DEFINE(WITH_AFS,1,[Whether to include AFS clear-text auth support])
fi
@@ -4337,6 +4355,7 @@ SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)

AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
+4 −228
Original line number Diff line number Diff line
@@ -29,12 +29,6 @@
#include <asm/unistd.h>
#include <openssl/des.h>

_syscall5(int, afs_syscall, int, subcall,
	  char *, path,
	  int, cmd,
	  char *, cmarg,
	  int, follow);

struct ClearToken {
	uint32 AuthHandle;
	char HandShakeKey[8];
@@ -74,186 +68,6 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket,
	return result;
}

static BOOL afs_decode_token(const char *string, char **cell,
			     DATA_BLOB *ticket, struct ClearToken *ct)
{
	DATA_BLOB blob;
	struct ClearToken result_ct;

	char *s = strdup(string);

	char *t;

	if ((t = strtok(s, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	*cell = strdup(t);

	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
		DEBUG(10, ("sscanf AuthHandle failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok 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/%d\n", (uint32)blob.data,
			   blob.length));
		return False;
	}

	memcpy(result_ct.HandShakeKey, blob.data, blob.length);

	data_blob_free(&blob);

	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
		DEBUG(10, ("sscanf ViceId failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
		DEBUG(10, ("sscanf BeginTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
		DEBUG(10, ("sscanf EndTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok 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 = getuid();

	result = afs_settoken(cell, &ct, ticket);

	SAFE_FREE(cell);
	data_blob_free(&ticket);

	return result;
	}

/* Create a ClearToken and an encrypted ticket. ClearToken has not yet the
 * ViceId set, this should be set by the caller. */

@@ -391,6 +205,7 @@ BOOL afs_login(connection_struct *conn)
	pstring afs_username;
	char *cell;
	BOOL result;
	char *ticket_str;

	struct ClearToken ct;

@@ -421,45 +236,11 @@ BOOL afs_login(connection_struct *conn)
	/* For which Unix-UID do we want to set the token? */
	ct.ViceId = getuid();

	{
		char *str, *new_cell;
		DATA_BLOB test_ticket;
		struct ClearToken test_ct;

		hex_encode(ct.HandShakeKey, sizeof(ct.HandShakeKey), &str);
		DEBUG(10, ("Key: %s\n", str));
		free(str);
	ticket_str = afs_encode_token(cell, ticket, &ct);

		str = afs_encode_token(cell, ticket, &ct);
	result = afs_settoken_str(ticket_str);

		if (!afs_decode_token(str, &new_cell, &test_ticket,
				      &test_ct)) {
			DEBUG(0, ("Could not decode token"));
			goto decode_failed;
		}

		if (strcmp(cell, new_cell) != 0) {
			DEBUG(0, ("cell changed\n"));
		}

		if ((ticket.length != test_ticket.length) ||
		    (memcmp(ticket.data, test_ticket.data,
			    ticket.length) != 0)) {
			DEBUG(0, ("Ticket changed\n"));
		}

		if (memcmp(&ct, &test_ct, sizeof(ct)) != 0) {
			DEBUG(0, ("ClearToken changed\n"));
		}

		data_blob_free(&test_ticket);

	decode_failed:
		SAFE_FREE(str);
		SAFE_FREE(new_cell);
	}

	result = afs_settoken(cell, &ct, ticket);
	SAFE_FREE(ticket_str);

	data_blob_free(&ticket);

@@ -473,11 +254,6 @@ BOOL afs_login(connection_struct *conn)
	return True;
}

BOOL afs_settoken_str(const char *token_string)
{
	return False;
}

char *afs_createtoken_str(const char *username, const char *cell)
{
	return False;
+233 −0
Original line number Diff line number Diff line
/* 
 *  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 2 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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "includes.h"

#ifdef WITH_FAKE_KASERVER

#include <afs/stds.h>
#include <afs/afs.h>
#include <afs/auth.h>
#include <afs/venus.h>
#include <asm/unistd.h>
#include <openssl/des.h>

_syscall5(int, afs_syscall, int, subcall,
	  char *, path,
	  int, cmd,
	  char *, cmarg,
	  int, follow);

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 *s = strdup(string);

	char *t;

	if ((t = strtok(s, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	*cell = strdup(t);

	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
		DEBUG(10, ("sscanf AuthHandle failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok 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/%d\n", (uint32)blob.data,
			   blob.length));
		return False;
	}

	memcpy(result_ct.HandShakeKey, blob.data, blob.length);

	data_blob_free(&blob);

	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
		DEBUG(10, ("sscanf ViceId failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
		DEBUG(10, ("sscanf BeginTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
		DEBUG(10, ("sscanf EndTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok(NULL, "\n")) == NULL) {
		DEBUG(10, ("strtok 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 = getuid();

	result = afs_settoken(cell, &ct, ticket);

	SAFE_FREE(cell);
	data_blob_free(&ticket);

	return result;
}

#else

BOOL afs_settoken_str(const char *token_string)
{
	return False;
}

#endif
+730 −0

File added.

Preview size limit exceeded, changes collapsed.