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/>.
25 #include "nsswitch/libwbclient/wbclient.h"
28 #define DBGC_CLASS DBGC_AUTH
30 /* Authenticate a user with a challenge/response */
32 static NTSTATUS
check_winbind_security(const struct auth_context
*auth_context
,
33 void *my_private_data
,
35 const struct auth_usersupplied_info
*user_info
,
36 struct auth_serversupplied_info
**server_info
)
40 struct wbcAuthUserParams params
;
41 struct wbcAuthUserInfo
*info
= NULL
;
42 struct wbcAuthErrorInfo
*err
= NULL
;
47 return NT_STATUS_INVALID_PARAMETER
;
50 DEBUG(10, ("Check auth for: [%s]\n", user_info
->mapped
.account_name
));
53 DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
54 user_info
->mapped
.account_name
));
55 return NT_STATUS_INVALID_PARAMETER
;
58 if (strequal(user_info
->mapped
.domain_name
, get_global_sam_name())) {
59 DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
60 user_info
->mapped
.domain_name
));
61 return NT_STATUS_NOT_IMPLEMENTED
;
64 /* Send off request */
66 params
.account_name
= user_info
->client
.account_name
;
67 params
.domain_name
= user_info
->mapped
.domain_name
;
68 params
.workstation_name
= user_info
->workstation_name
;
71 params
.parameter_control
= user_info
->logon_parameters
;
73 params
.level
= WBC_AUTH_USER_LEVEL_RESPONSE
;
75 memcpy(params
.password
.response
.challenge
,
76 auth_context
->challenge
.data
,
77 sizeof(params
.password
.response
.challenge
));
79 if (user_info
->password
.response
.nt
.length
!= 0) {
80 params
.password
.response
.nt_length
=
81 user_info
->password
.response
.nt
.length
;
82 params
.password
.response
.nt_data
=
83 user_info
->password
.response
.nt
.data
;
85 if (user_info
->password
.response
.lanman
.length
!= 0) {
86 params
.password
.response
.lm_length
=
87 user_info
->password
.response
.lanman
.length
;
88 params
.password
.response
.lm_data
=
89 user_info
->password
.response
.lanman
.data
;
92 /* we are contacting the privileged pipe */
94 wbc_status
= wbcAuthenticateUserEx(¶ms
, &info
, &err
);
97 if (!WBC_ERROR_IS_OK(wbc_status
)) {
98 DEBUG(10,("check_winbind_security: wbcAuthenticateUserEx failed: %s\n",
99 wbcErrorString(wbc_status
)));
102 if (wbc_status
== WBC_ERR_NO_MEMORY
) {
103 return NT_STATUS_NO_MEMORY
;
106 if (wbc_status
== WBC_ERR_WINBIND_NOT_AVAILABLE
) {
107 struct auth_methods
*auth_method
=
108 (struct auth_methods
*)my_private_data
;
111 return auth_method
->auth(auth_context
, auth_method
->private_data
,
112 mem_ctx
, user_info
, server_info
);
113 return NT_STATUS_LOGON_FAILURE
;
116 if (wbc_status
== WBC_ERR_AUTH_ERROR
) {
117 nt_status
= NT_STATUS(err
->nt_status
);
122 if (!WBC_ERROR_IS_OK(wbc_status
)) {
123 return NT_STATUS_LOGON_FAILURE
;
126 nt_status
= make_server_info_wbcAuthUserInfo(mem_ctx
,
127 user_info
->client
.account_name
,
128 user_info
->mapped
.domain_name
,
131 if (!NT_STATUS_IS_OK(nt_status
)) {
135 (*server_info
)->nss_token
|= user_info
->was_mapped
;
140 /* module initialisation */
141 static NTSTATUS
auth_init_winbind(struct auth_context
*auth_context
, const char *param
, auth_methods
**auth_method
)
143 struct auth_methods
*result
;
145 result
= talloc_zero(auth_context
, struct auth_methods
);
146 if (result
== NULL
) {
147 return NT_STATUS_NO_MEMORY
;
149 result
->name
= "winbind";
150 result
->auth
= check_winbind_security
;
152 if (param
&& *param
) {
153 /* we load the 'fallback' module - if winbind isn't here, call this
156 if (!load_auth_module(auth_context
, param
, &priv
)) {
157 return NT_STATUS_UNSUCCESSFUL
;
159 result
->private_data
= (void *)priv
;
162 *auth_method
= result
;
166 NTSTATUS
auth_winbind_init(void)
168 return smb_register_auth(AUTH_INTERFACE_VERSION
, "winbind", auth_init_winbind
);