2 Unix SMB/CIFS implementation.
4 Winbind authentication mechnism
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Bartlett 2001 - 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #define DBGC_CLASS DBGC_AUTH
28 /* Authenticate a user with a challenge/response */
30 static NTSTATUS
check_winbind_security(const struct auth_context
*auth_context
,
31 void *my_private_data
,
33 const auth_usersupplied_info
*user_info
,
34 auth_serversupplied_info
**server_info
)
38 struct wbcAuthUserParams params
;
39 struct wbcAuthUserInfo
*info
= NULL
;
40 struct wbcAuthErrorInfo
*err
= NULL
;
43 return NT_STATUS_INVALID_PARAMETER
;
47 DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
48 user_info
->internal_username
));
49 return NT_STATUS_INVALID_PARAMETER
;
52 if (strequal(user_info
->domain
, get_global_sam_name())) {
53 DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
55 return NT_STATUS_NOT_IMPLEMENTED
;
58 /* Send off request */
60 params
.account_name
= user_info
->smb_name
;
61 params
.domain_name
= user_info
->domain
;
62 params
.workstation_name
= user_info
->wksta_name
;
65 params
.parameter_control
= user_info
->logon_parameters
;
67 params
.level
= WBC_AUTH_USER_LEVEL_RESPONSE
;
69 memcpy(params
.password
.response
.challenge
,
70 auth_context
->challenge
.data
,
71 sizeof(params
.password
.response
.challenge
));
73 params
.password
.response
.nt_length
= user_info
->nt_resp
.length
;
74 params
.password
.response
.nt_data
= user_info
->nt_resp
.data
;
75 params
.password
.response
.lm_length
= user_info
->lm_resp
.length
;
76 params
.password
.response
.lm_data
= user_info
->lm_resp
.data
;
78 /* we are contacting the privileged pipe */
80 wbc_status
= wbcAuthenticateUserEx(¶ms
, &info
, &err
);
83 if (!WBC_ERROR_IS_OK(wbc_status
)) {
84 DEBUG(10,("check_winbind_security: wbcAuthenticateUserEx failed: %s\n",
85 wbcErrorString(wbc_status
)));
88 if (wbc_status
== WBC_ERR_NO_MEMORY
) {
89 return NT_STATUS_NO_MEMORY
;
92 if (wbc_status
== WBC_ERR_WINBIND_NOT_AVAILABLE
) {
93 struct auth_methods
*auth_method
=
94 (struct auth_methods
*)my_private_data
;
97 return auth_method
->auth(auth_context
, auth_method
->private_data
,
98 mem_ctx
, user_info
, server_info
);
100 /* log an error since this should not happen */
101 DEBUG(0,("check_winbind_security: ERROR! my_private_data == NULL!\n"));
104 if (wbc_status
== WBC_ERR_AUTH_ERROR
) {
105 nt_status
= NT_STATUS(err
->nt_status
);
110 if (!WBC_ERROR_IS_OK(wbc_status
)) {
111 return NT_STATUS_LOGON_FAILURE
;
114 nt_status
= make_server_info_wbcAuthUserInfo(mem_ctx
,
119 if (!NT_STATUS_IS_OK(nt_status
)) {
123 (*server_info
)->nss_token
|= user_info
->was_mapped
;
128 /* module initialisation */
129 static NTSTATUS
auth_init_winbind(struct auth_context
*auth_context
, const char *param
, auth_methods
**auth_method
)
131 if (!make_auth_methods(auth_context
, auth_method
)) {
132 return NT_STATUS_NO_MEMORY
;
135 (*auth_method
)->name
= "winbind";
136 (*auth_method
)->auth
= check_winbind_security
;
138 if (param
&& *param
) {
139 /* we load the 'fallback' module - if winbind isn't here, call this
142 if (!load_auth_module(auth_context
, param
, &priv
)) {
143 return NT_STATUS_UNSUCCESSFUL
;
145 (*auth_method
)->private_data
= (void *)priv
;
150 NTSTATUS
auth_winbind_init(void)
152 return smb_register_auth(AUTH_INTERFACE_VERSION
, "winbind", auth_init_winbind
);