mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r10234: Add new auth module "auth_script" to allow valid users to
be provisioned on demand - calls script with domain, username, challenge and LM and NT responses - passing the info through a pipe. Jeremy.
This commit is contained in:
parent
2490118796
commit
67be4ee41c
@ -368,6 +368,7 @@ AUTH_RHOSTS_OBJ = auth/auth_rhosts.o
|
||||
AUTH_SERVER_OBJ = auth/auth_server.o
|
||||
AUTH_UNIX_OBJ = auth/auth_unix.o
|
||||
AUTH_WINBIND_OBJ = auth/auth_winbind.o
|
||||
AUTH_SCRIPT_OBJ = auth/auth_script.o
|
||||
|
||||
AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \
|
||||
auth/auth_ntlmssp.o \
|
||||
@ -1165,6 +1166,10 @@ bin/domain.@SHLIBEXT@: $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_DOMAIN_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/script.@SHLIBEXT@: $(AUTH_SCRIPT_OBJ:.o=.@PICSUFFIX@)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SCRIPT_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/smbserver.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SERVER_OBJ:.o=.@PICSUFFIX@) @SONAMEFLAG@`basename $@`
|
||||
|
155
source/auth/auth_script.c
Normal file
155
source/auth/auth_script.c
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Call out to a shell script for an authentication check.
|
||||
|
||||
Copyright (C) Jeremy Allison 2005.
|
||||
|
||||
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"
|
||||
|
||||
#undef malloc
|
||||
|
||||
#undef DBGC_CLASS
|
||||
#define DBGC_CLASS DBGC_AUTH
|
||||
|
||||
/* Create a string containing the supplied :
|
||||
* domain\n
|
||||
* user\n
|
||||
* ascii hex challenge\n
|
||||
* ascii hex LM response\n
|
||||
* ascii hex NT response\n\0
|
||||
* and execute a shell script to check this.
|
||||
* Allows external programs to create users on demand.
|
||||
* Script returns zero on success, non-zero on fail.
|
||||
*/
|
||||
|
||||
static NTSTATUS script_check_user_credentials(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)
|
||||
{
|
||||
const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL);
|
||||
char *secret_str;
|
||||
size_t secret_str_len;
|
||||
char hex_str[49];
|
||||
int ret, i;
|
||||
|
||||
if (!script) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!user_info) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!auth_context) {
|
||||
DEBUG(3,("script_check_user_credentials: no auth_info !\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
secret_str_len = strlen(user_info->domain.str) + 1 +
|
||||
strlen(user_info->smb_name.str) + 1 +
|
||||
16 + 1 + /* 8 bytes of challenge going to 16 */
|
||||
48 + 1 + /* 24 bytes of challenge going to 48 */
|
||||
48 + 1;
|
||||
|
||||
secret_str = malloc(secret_str_len);
|
||||
if (!secret_str) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
safe_strcpy( secret_str, user_info->domain.str, secret_str_len - 1);
|
||||
safe_strcat( secret_str, "\n", secret_str_len - 1);
|
||||
safe_strcat( secret_str, user_info->smb_name.str, secret_str_len - 1);
|
||||
safe_strcat( secret_str, "\n", secret_str_len - 1);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
slprintf(&hex_str[i*2], 3, "%02X", auth_context->challenge.data[i]);
|
||||
}
|
||||
safe_strcat( secret_str, hex_str, secret_str_len - 1);
|
||||
safe_strcat( secret_str, "\n", secret_str_len - 1);
|
||||
|
||||
if (user_info->lm_resp.data) {
|
||||
for (i = 0; i < 24; i++) {
|
||||
slprintf(&hex_str[i*2], 3, "%02X", user_info->lm_resp.data[i]);
|
||||
}
|
||||
safe_strcat( secret_str, hex_str, secret_str_len - 1);
|
||||
}
|
||||
safe_strcat( secret_str, "\n", secret_str_len - 1);
|
||||
|
||||
if (user_info->nt_resp.data) {
|
||||
for (i = 0; i < 24; i++) {
|
||||
slprintf(&hex_str[i*2], 3, "%02X", user_info->nt_resp.data[i]);
|
||||
}
|
||||
safe_strcat( secret_str, hex_str, secret_str_len - 1);
|
||||
}
|
||||
safe_strcat( secret_str, "\n", secret_str_len - 1);
|
||||
|
||||
DEBUG(10,("script_check_user_credentials: running %s with parameters:\n%s\n",
|
||||
script, secret_str ));
|
||||
|
||||
ret = smbrunsecret( script, secret_str);
|
||||
|
||||
SAFE_FREE(secret_str);
|
||||
|
||||
if (ret) {
|
||||
DEBUG(1,("script_check_user_credentials: failed to authenticate %s\\%s\n",
|
||||
user_info->domain.str, user_info->smb_name.str ));
|
||||
/* auth failed. */
|
||||
return NT_STATUS_NO_SUCH_USER;
|
||||
}
|
||||
|
||||
/* Cause the auth system to keep going.... */
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* module initialisation */
|
||||
static NTSTATUS auth_init_script(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 = "script";
|
||||
(*auth_method)->auth = script_check_user_credentials;
|
||||
|
||||
if (param && *param) {
|
||||
/* we load the 'fallback' module - if script isn't here, call this
|
||||
module */
|
||||
if (!load_auth_module(auth_context, param, (auth_methods **)&(*auth_method)->private_data)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Define this to build static. */
|
||||
NTSTATUS auth_script_init(void)
|
||||
{
|
||||
return smb_register_auth(AUTH_INTERFACE_VERSION, "script", auth_init_script);
|
||||
}
|
||||
#else
|
||||
/* Define this to build shared. */
|
||||
NTSTATUS init_module(void)
|
||||
{
|
||||
return smb_register_auth(AUTH_INTERFACE_VERSION, "script", auth_init_script);
|
||||
}
|
||||
#endif
|
@ -460,7 +460,7 @@ dnl These have to be built static:
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin printerdb_file"
|
||||
|
||||
dnl These are preferably build shared, and static if dlopen() is not available
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437"
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437 auth_script"
|
||||
|
||||
if test "x$developer" = xyes; then
|
||||
default_static_modules="$default_static_modules rpc_echo"
|
||||
@ -4973,6 +4973,7 @@ SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH)
|
||||
SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH)
|
||||
SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH)
|
||||
SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH)
|
||||
SMB_MODULE(auth_script, \$(AUTH_SCRIPT_OBJ), "bin/script.$SHLIBEXT", AUTH)
|
||||
SMB_SUBSYSTEM(AUTH,auth/auth.o)
|
||||
|
||||
SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), "bin/recycle.$SHLIBEXT", VFS)
|
||||
|
@ -55,7 +55,7 @@ run a command being careful about uid/gid handling and putting the output in
|
||||
outfd (or discard it if outfd is NULL).
|
||||
****************************************************************************/
|
||||
|
||||
int smbrun(char *cmd, int *outfd)
|
||||
int smbrun(const char *cmd, int *outfd)
|
||||
{
|
||||
pid_t pid;
|
||||
uid_t uid = current_user.uid;
|
||||
@ -186,7 +186,7 @@ outfd (or discard it if outfd is NULL).
|
||||
sends the provided secret to the child stdin.
|
||||
****************************************************************************/
|
||||
|
||||
int smbrunsecret(char *cmd, char *secret)
|
||||
int smbrunsecret(const char *cmd, const char *secret)
|
||||
{
|
||||
pid_t pid;
|
||||
uid_t uid = current_user.uid;
|
||||
|
Loading…
Reference in New Issue
Block a user