2 Unix SMB/Netbios implementation.
4 Authentication utility functions
5 Copyright (C) Andrew Bartlett 2001
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 const struct auth_init_function builtin_auth_init_functions[] = {
25 { "guest", auth_init_guest },
26 { "rhosts", auth_init_rhosts },
27 { "hostsequiv", auth_init_hostsequiv },
28 { "sam", auth_init_sam },
29 { "samstrict", auth_init_samstrict },
30 { "unix", auth_init_unix },
31 { "smbserver", auth_init_smbserver },
32 { "ntdomain", auth_init_ntdomain },
33 { "winbind", auth_init_winbind },
35 { "name_to_ntstatus", auth_init_name_to_ntstatus },
40 /***************************************************************************
41 Make a auth_info struct
42 ***************************************************************************/
44 static BOOL make_auth_info(auth_authsupplied_info **auth_info)
46 *auth_info = malloc(sizeof(**auth_info));
48 DEBUG(0,("make_auth_info: malloc failed!\n"));
51 ZERO_STRUCTP(*auth_info);
56 /***************************************************************************
57 Make a auth_info struct with a specified list.
58 ***************************************************************************/
60 BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list)
62 if (!make_auth_info(auth_info)) {
66 (*auth_info)->auth_method_list = list;
71 /***************************************************************************
72 Make a auth_info struct for the auth subsystem
73 ***************************************************************************/
75 static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list)
77 auth_methods *list = NULL;
78 auth_methods *t = NULL;
83 DEBUG(2,("No auth method list!?\n"));
87 for (;*text_list; text_list++)
89 DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
90 for (i = 0; builtin_auth_init_functions[i].name; i++)
92 if (strequal(builtin_auth_init_functions[i].name, *text_list))
94 DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
95 /* Malloc entry, fill it, link it */
96 t = (auth_methods *)malloc(sizeof(*t));
98 DEBUG(0,("make_pw_chat: malloc failed!\n"));
104 if (builtin_auth_init_functions[i].init(&t)) {
105 DEBUG(5,("auth method %s has a valid init\n", *text_list));
106 t->name = builtin_auth_init_functions[i].name;
107 DLIST_ADD_END(list, t, tmp);
109 DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list));
116 make_auth_info_list(auth_info, list);
121 /***************************************************************************
122 Make a auth_info struct for the auth subsystem
123 ***************************************************************************/
125 BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info)
127 char **auth_method_list = NULL;
129 if (!make_auth_info(auth_info)) {
133 if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
137 if (auth_method_list == NULL) {
138 switch (lp_security())
141 DEBUG(5,("Making default auth method list for security=domain\n"));
142 auth_method_list = lp_list_make("guest samstrict ntdomain");
145 DEBUG(5,("Making default auth method list for security=server\n"));
146 auth_method_list = lp_list_make("guest samstrict smbserver");
149 if (lp_encrypted_passwords()) {
150 DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
151 auth_method_list = lp_list_make("guest sam");
153 DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
154 auth_method_list = lp_list_make("guest unix");
158 if (lp_encrypted_passwords()) {
159 DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
160 auth_method_list = lp_list_make("guest sam");
162 DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
163 auth_method_list = lp_list_make("guest unix");
167 DEBUG(5,("Making default auth method list for security=ADS\n"));
168 auth_method_list = lp_list_make("guest samstrict ads ntdomain");
171 DEBUG(5,("Unknown auth method!\n"));
175 DEBUG(5,("Using specified auth order\n"));
178 if (!make_auth_info_text_list(auth_info, auth_method_list)) {
179 lp_list_free(&auth_method_list);
183 lp_list_free(&auth_method_list);
187 /***************************************************************************
188 Make a auth_info struct with a random challenge
189 ***************************************************************************/
191 BOOL make_auth_info_random(auth_authsupplied_info **auth_info)
194 if (!make_auth_info_subsystem(auth_info)) {
198 generate_random_buffer(chal, sizeof(chal), False);
199 (*auth_info)->challenge = data_blob(chal, sizeof(chal));
201 (*auth_info)->challenge_set_by = "random";
206 /***************************************************************************
207 Make a auth_info struct with a fixed challenge
208 ***************************************************************************/
210 BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8])
212 if (!make_auth_info_subsystem(auth_info)) {
216 (*auth_info)->challenge = data_blob(chal, 8);
220 /***************************************************************************
221 Clear out a auth_info struct that has been allocated
222 ***************************************************************************/
224 void free_auth_info(auth_authsupplied_info **auth_info)
227 if (*auth_info != NULL) {
228 list = (*auth_info)->auth_method_list;
230 auth_methods *old_head = list;
231 if (list->free_private_data) {
232 list->free_private_data(&(list->private_data));
234 DLIST_REMOVE(list, list);
238 data_blob_free(&(*auth_info)->challenge);
239 ZERO_STRUCT(**auth_info);
241 SAFE_FREE(*auth_info);
244 /****************************************************************************
245 Try to get a challenge out of the various authenticaion modules.
246 It is up to the caller to free it.
247 ****************************************************************************/
249 DATA_BLOB auth_get_challenge(auth_authsupplied_info *auth_info)
251 DATA_BLOB challenge = data_blob(NULL, 0);
252 char *challenge_set_by = NULL;
253 auth_methods *auth_method;
255 if (auth_info->challenge.length) {
256 DEBUG(5, ("auth_get_challenge: returning previous challenge (normal)\n"));
257 return data_blob(auth_info->challenge.data, auth_info->challenge.length);
260 for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
262 if (auth_method->get_chal) {
263 DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name));
264 if (challenge_set_by) {
265 DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n",
266 challenge_set_by, auth_method->name));
268 challenge = auth_method->get_chal(&auth_method->private_data, auth_info);
269 if (challenge.length) {
270 DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
271 auth_info->challenge = challenge;
272 challenge_set_by = auth_method->name;
273 auth_info->challenge_set_method = auth_method;
275 DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n",
280 DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
284 if (!challenge_set_by) {
287 generate_random_buffer(chal, sizeof(chal), False);
288 auth_info->challenge = data_blob(chal, sizeof(chal));
290 challenge_set_by = "random";
293 DEBUG(5, ("auth_info challenge created by %s\n", challenge_set_by));
294 DEBUG(5, ("challenge is: \n"));
295 dump_data(5, auth_info->challenge.data, (auth_info)->challenge.length);
297 SMB_ASSERT(auth_info->challenge.length == 8);
299 auth_info->challenge_set_by=challenge_set_by;
301 return data_blob(auth_info->challenge.data, auth_info->challenge.length);