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 struct auth_usersupplied_info
*user_info
,
34 struct auth_serversupplied_info
**server_info
)
38 struct wbcAuthUserParams params
;
39 struct wbcAuthUserInfo
*info
= NULL
;
40 struct wbcAuthErrorInfo
*err
= NULL
;
45 return NT_STATUS_INVALID_PARAMETER
;
48 DEBUG(10, ("Check auth for: [%s]\n", user_info
->mapped
.account_name
));
51 DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
52 user_info
->mapped
.account_name
));
53 return NT_STATUS_INVALID_PARAMETER
;
56 if (strequal(user_info
->mapped
.domain_name
, get_global_sam_name())) {
57 DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
58 user_info
->mapped
.domain_name
));
59 return NT_STATUS_NOT_IMPLEMENTED
;
62 /* Send off request */
64 params
.account_name
= user_info
->client
.account_name
;
65 params
.domain_name
= user_info
->mapped
.domain_name
;
66 params
.workstation_name
= user_info
->workstation_name
;
69 params
.parameter_control
= user_info
->logon_parameters
;
71 params
.level
= WBC_AUTH_USER_LEVEL_RESPONSE
;
73 memcpy(params
.password
.response
.challenge
,
74 auth_context
->challenge
.data
,
75 sizeof(params
.password
.response
.challenge
));
77 if (user_info
->password
.response
.nt
.length
!= 0) {
78 params
.password
.response
.nt_length
=
79 user_info
->password
.response
.nt
.length
;
80 params
.password
.response
.nt_data
=
81 user_info
->password
.response
.nt
.data
;
83 if (user_info
->password
.response
.lanman
.length
!= 0) {
84 params
.password
.response
.lm_length
=
85 user_info
->password
.response
.lanman
.length
;
86 params
.password
.response
.lm_data
=
87 user_info
->password
.response
.lanman
.data
;
90 /* we are contacting the privileged pipe */
92 wbc_status
= wbcAuthenticateUserEx(¶ms
, &info
, &err
);
95 if (!WBC_ERROR_IS_OK(wbc_status
)) {
96 DEBUG(10,("check_winbind_security: wbcAuthenticateUserEx failed: %s\n",
97 wbcErrorString(wbc_status
)));
100 if (wbc_status
== WBC_ERR_NO_MEMORY
) {
101 return NT_STATUS_NO_MEMORY
;
104 if (wbc_status
== WBC_ERR_WINBIND_NOT_AVAILABLE
) {
105 struct auth_methods
*auth_method
=
106 (struct auth_methods
*)my_private_data
;
109 return auth_method
->auth(auth_context
, auth_method
->private_data
,
110 mem_ctx
, user_info
, server_info
);
111 return NT_STATUS_LOGON_FAILURE
;
114 if (wbc_status
== WBC_ERR_AUTH_ERROR
) {
115 nt_status
= NT_STATUS(err
->nt_status
);
120 if (!WBC_ERROR_IS_OK(wbc_status
)) {
121 return NT_STATUS_LOGON_FAILURE
;
124 nt_status
= make_server_info_wbcAuthUserInfo(mem_ctx
,
125 user_info
->client
.account_name
,
126 user_info
->mapped
.domain_name
,
129 if (!NT_STATUS_IS_OK(nt_status
)) {
133 (*server_info
)->nss_token
|= user_info
->was_mapped
;
138 /* module initialisation */
139 static NTSTATUS
auth_init_winbind(struct auth_context
*auth_context
, const char *param
, auth_methods
**auth_method
)
141 struct auth_methods
*result
;
143 result
= TALLOC_ZERO_P(auth_context
, struct auth_methods
);
144 if (result
== NULL
) {
145 return NT_STATUS_NO_MEMORY
;
147 result
->name
= "winbind";
148 result
->auth
= check_winbind_security
;
150 if (param
&& *param
) {
151 /* we load the 'fallback' module - if winbind isn't here, call this
154 if (!load_auth_module(auth_context
, param
, &priv
)) {
155 return NT_STATUS_UNSUCCESSFUL
;
157 result
->private_data
= (void *)priv
;
160 *auth_method
= result
;
164 NTSTATUS
auth_winbind_init(void)
166 return smb_register_auth(AUTH_INTERFACE_VERSION
, "winbind", auth_init_winbind
);