Private AUthentication LAyer authentication support

Luke Howard lukeh at PADL.COM
Wed Dec 4 02:41:51 GMT 2002


The attached file contains an extension to the SAMBA authentication
subsystem to support PAULA pass-through authentication. PAULA is
defined in the ActiveX/DCOM specification, at the following URL:

	http://www.opengroup.org/onlinepubs/009899899

It should be refactored as a dynamically loadable plugin -- I am
told that this is trivial to do.

Note, though, that the present implementation does not encrypt
sensitive parameters with a shared secret, as required by the
specification. In our implementation, we needed a simple way of
allowing SAMBA to authenticate NTLM clients against our own DCE
RPC-based domain controller (on the same host), and wished to
avoid the configuration overhead of a shared secret. We only
accept PAULA requests that come from a trusted client on the
local machine.

-- Luke
-------------- next part --------------
/* 
   Unix SMB/CIFS implementation.

   PAULA authentication implementation

   Copyright (C) Luke Howard 2002
   
   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"

#include <paula.h>

#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH

/*
 * PAULA, or the Private AUthentication LAyer, is an interface for 
 * doing NTLM authentication on machines that don't have a fully-
 * fleged LSA (eg. Unix systems).
 *
 * The interface is defined by Microsoft and Compaq in the DCOM
 * specification available at:
 *   http://www.opengroup.org/onlinepubs/009899899/CHP01CHP.HTM#chap01.sect1.5
 */

static NTSTATUS check_paula_security(const struct auth_context *auth_context,
				       void *my_private_data, 
				       TALLOC_CTX *mem_ctx,
				       const auth_usersupplied_info *user_info, 
				       auth_serversupplied_info **server_info)
{
	char Domain[64];
	char Workstation[64];
	char UserName[64];
	char Challenge[8];
	char CaseInsensitiveChallengeResponse[24];
	char CaseSensitiveChallengeResponse[24];
	char UserSessionKey[16];
	char LanManSessionKey[8];
	unsigned32 Cookie;
	NTSTATUS status;
	unsigned32 protocolStatus, protocolSubStatus;

	if (user_info == NULL) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	if (auth_context == NULL) {
		DEBUG(3, ("check_paula_security: no authentication context provided for user %s\n", user_info->internal_username.str));
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (user_info->domain.len >= sizeof(Domain)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(Domain, user_info->domain.str, user_info->domain.len + 1);

	if (user_info->wksta_name.len >= sizeof(Workstation)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(Workstation, user_info->wksta_name.str, user_info->wksta_name.len + 1);

	if (user_info->smb_name.len >= sizeof(UserName)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(UserName, user_info->smb_name.str, user_info->smb_name.len + 1);

	if (auth_context->challenge.length > sizeof(Challenge)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(Challenge, auth_context->challenge.data, auth_context->challenge.length);

	if (user_info->lm_resp.length > sizeof(CaseInsensitiveChallengeResponse)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(CaseInsensitiveChallengeResponse, user_info->lm_resp.data, user_info->lm_resp.length);

	if (user_info->nt_resp.length > sizeof(CaseSensitiveChallengeResponse)) {
		return NT_STATUS_BUFFER_TOO_SMALL;
	}
	memcpy(CaseSensitiveChallengeResponse, user_info->nt_resp.data, user_info->nt_resp.length);

	PaulaLMLogonRequest(Cookie,
		Domain,
		Workstation,
		UserName,
		Challenge,
		CaseInsensitiveChallengeResponse,
		CaseSensitiveChallengeResponse,
		&Cookie,
		&protocolStatus,
		&protocolSubStatus,
		(unsigned32 *)&status,
		UserSessionKey,
		LanManSessionKey);
	if (protocolStatus != 0) {
		DEBUG(1, ("check_paula_security: PaulaLMLogonRequest RPC failed (%08x %08x)\n", protocolStatus, protocolSubStatus));
		return NT_STATUS_UNSUCCESSFUL;
	}

	DEBUG(1, ("check_paula_security: PaulaLMLogonRequest returned %08x\n", status));

	if (NT_STATUS_IS_OK(status)) {
		struct passwd *pwd;

		pwd = Get_Pwnam(UserName);
		if (pwd == NULL) {
			DEBUG(1, ("check_paula_security: could not find local account for %s\n", UserName));
			status = NT_STATUS_NO_SUCH_USER;
		} else {
			make_server_info_pw(server_info, pwd);
		}
	}

	return status;
}

/* module initialisation */
NTSTATUS auth_init_paula(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 
{
	if (!make_auth_methods(auth_context, auth_method)) {
		return NT_STATUS_NO_MEMORY;
	}

	(*auth_method)->name = "paula";
	(*auth_method)->auth = check_paula_security;
	return NT_STATUS_OK;
}
-------------- next part --------------
--
Luke Howard | PADL Software Pty Ltd | www.padl.com


More information about the samba-technical mailing list