1/* 2 Unix SMB/CIFS implementation. 3 4 Winbind client authentication mechanism designed to defer all 5 authentication to the winbind daemon. 6 7 Copyright (C) Tim Potter 2000 8 Copyright (C) Andrew Bartlett 2001 - 2002 9 Copyright (C) Dan Sledz 2009 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23*/ 24 25/* This auth module is very similar to auth_winbind with 3 distinct 26 * differences. 27 * 28 * 1) Does not fallback to another auth module if winbindd is unavailable 29 * 2) Does not validate the domain of the user 30 * 3) Handles unencrypted passwords 31 * 32 * The purpose of this module is to defer all authentication decisions (ie: 33 * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc 34 * compatible daemon. This centeralizes all authentication decisions to a 35 * single provider. 36 * 37 * This auth backend is most useful when used in conjunction with pdb_wbc_sam. 38 */ 39 40#include "includes.h" 41 42#undef DBGC_CLASS 43#define DBGC_CLASS DBGC_AUTH 44 45/* Authenticate a user with a challenge/response */ 46 47static NTSTATUS check_wbc_security(const struct auth_context *auth_context, 48 void *my_private_data, 49 TALLOC_CTX *mem_ctx, 50 const auth_usersupplied_info *user_info, 51 auth_serversupplied_info **server_info) 52{ 53 NTSTATUS nt_status; 54 wbcErr wbc_status; 55 struct wbcAuthUserParams params; 56 struct wbcAuthUserInfo *info = NULL; 57 struct wbcAuthErrorInfo *err = NULL; 58 59 if (!user_info || !auth_context || !server_info) { 60 return NT_STATUS_INVALID_PARAMETER; 61 } 62 /* Send off request */ 63 64 params.account_name = user_info->smb_name; 65 params.domain_name = user_info->domain; 66 params.workstation_name = user_info->wksta_name; 67 68 params.flags = 0; 69 params.parameter_control= user_info->logon_parameters; 70 71 /* Handle plaintext */ 72 if (!user_info->encrypted) { 73 DEBUG(3,("Checking plaintext password for %s.\n", 74 user_info->internal_username)); 75 params.level = WBC_AUTH_USER_LEVEL_PLAIN; 76 77 params.password.plaintext = (char *)user_info->plaintext_password.data; 78 } else { 79 DEBUG(3,("Checking encrypted password for %s.\n", 80 user_info->internal_username)); 81 params.level = WBC_AUTH_USER_LEVEL_RESPONSE; 82 83 memcpy(params.password.response.challenge, 84 auth_context->challenge.data, 85 sizeof(params.password.response.challenge)); 86 87 params.password.response.nt_length = user_info->nt_resp.length; 88 params.password.response.nt_data = user_info->nt_resp.data; 89 params.password.response.lm_length = user_info->lm_resp.length; 90 params.password.response.lm_data = user_info->lm_resp.data; 91 92 } 93 94 /* we are contacting the privileged pipe */ 95 become_root(); 96 wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); 97 unbecome_root(); 98 99 if (!WBC_ERROR_IS_OK(wbc_status)) { 100 DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", 101 wbc_status, wbcErrorString(wbc_status))); 102 } 103 104 if (wbc_status == WBC_ERR_NO_MEMORY) { 105 return NT_STATUS_NO_MEMORY; 106 } 107 108 if (wbc_status == WBC_ERR_AUTH_ERROR) { 109 nt_status = NT_STATUS(err->nt_status); 110 wbcFreeMemory(err); 111 return nt_status; 112 } 113 114 if (!WBC_ERROR_IS_OK(wbc_status)) { 115 return NT_STATUS_LOGON_FAILURE; 116 } 117 118 DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); 119 120 nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, 121 user_info->smb_name, 122 user_info->domain, 123 info, server_info); 124 wbcFreeMemory(info); 125 if (!NT_STATUS_IS_OK(nt_status)) { 126 return nt_status; 127 } 128 129 (*server_info)->nss_token |= user_info->was_mapped; 130 131 return nt_status; 132} 133 134/* module initialisation */ 135static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 136{ 137 if (!make_auth_methods(auth_context, auth_method)) { 138 return NT_STATUS_NO_MEMORY; 139 } 140 141 (*auth_method)->name = "wbc"; 142 (*auth_method)->auth = check_wbc_security; 143 144 return NT_STATUS_OK; 145} 146 147NTSTATUS auth_wbc_init(void) 148{ 149 return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc); 150} 151