summaryrefslogtreecommitdiffstats
path: root/source/auth/auth_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/auth/auth_info.c')
-rw-r--r--source/auth/auth_info.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/source/auth/auth_info.c b/source/auth/auth_info.c
new file mode 100644
index 00000000000..cc13d5a8b95
--- /dev/null
+++ b/source/auth/auth_info.c
@@ -0,0 +1,291 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0.
+ Authentication utility functions
+ Copyright (C) Andrew Bartlett 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+const struct auth_init_function builtin_auth_init_functions[] = {
+ { "guest", auth_init_guest },
+ { "rhosts", auth_init_rhosts },
+ { "hostsequiv", auth_init_hostsequiv },
+ { "sam", auth_init_sam },
+ { "samstrict", auth_init_samstrict },
+ { "unix", auth_init_unix },
+ { "smbserver", auth_init_smbserver },
+ { "ntdomain", auth_init_ntdomain },
+ { "winbind", auth_init_winbind },
+#ifdef DEVELOPER
+ { "name_to_ntstatus", auth_init_name_to_ntstatus },
+#endif
+ { NULL, NULL}
+};
+
+/***************************************************************************
+ Make a auth_info struct
+***************************************************************************/
+
+static BOOL make_auth_info(auth_authsupplied_info **auth_info)
+{
+ *auth_info = malloc(sizeof(**auth_info));
+ if (!*auth_info) {
+ DEBUG(0,("make_auth_info: malloc failed!\n"));
+ return False;
+ }
+ ZERO_STRUCTP(*auth_info);
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a specified list.
+***************************************************************************/
+
+BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list)
+{
+ if (!make_auth_info(auth_info)) {
+ return False;
+ }
+
+ (*auth_info)->auth_method_list = list;
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list)
+{
+ auth_methods *list = NULL;
+ auth_methods *t = NULL;
+ auth_methods *tmp;
+ int i;
+
+ if (!text_list) {
+ DEBUG(2,("No auth method list!?\n"));
+ return False;
+ }
+
+ for (;*text_list; text_list++)
+ {
+ DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
+ for (i = 0; builtin_auth_init_functions[i].name; i++)
+ {
+ if (strequal(builtin_auth_init_functions[i].name, *text_list))
+ {
+ DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
+ if (builtin_auth_init_functions[i].init(&t)) {
+ DEBUG(5,("auth method %s has a valid init\n", *text_list));
+ t->name = builtin_auth_init_functions[i].name;
+ DLIST_ADD_END(list, t, tmp);
+ } else {
+ DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list));
+ }
+ break;
+ }
+ }
+ }
+
+ make_auth_info_list(auth_info, list);
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info)
+{
+ char **auth_method_list = NULL;
+
+ if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
+ return False;
+ }
+
+ if (auth_method_list == NULL) {
+ switch (lp_security())
+ {
+ case SEC_DOMAIN:
+ DEBUG(5,("Making default auth method list for security=domain\n"));
+ auth_method_list = lp_list_make("guest samstrict ntdomain");
+ break;
+ case SEC_SERVER:
+ DEBUG(5,("Making default auth method list for security=server\n"));
+ auth_method_list = lp_list_make("guest samstrict smbserver");
+ break;
+ case SEC_USER:
+ if (lp_encrypted_passwords()) {
+ DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
+ auth_method_list = lp_list_make("guest sam");
+ } else {
+ DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
+ auth_method_list = lp_list_make("guest unix");
+ }
+ break;
+ case SEC_SHARE:
+ if (lp_encrypted_passwords()) {
+ DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
+ auth_method_list = lp_list_make("guest sam");
+ } else {
+ DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
+ auth_method_list = lp_list_make("guest unix");
+ }
+ break;
+ case SEC_ADS:
+ DEBUG(5,("Making default auth method list for security=ADS\n"));
+ auth_method_list = lp_list_make("guest samstrict ads ntdomain");
+ break;
+ default:
+ DEBUG(5,("Unknown auth method!\n"));
+ return False;
+ }
+ } else {
+ DEBUG(5,("Using specified auth order\n"));
+ }
+
+ if (!make_auth_info_text_list(auth_info, auth_method_list)) {
+ lp_list_free(&auth_method_list);
+ return False;
+ }
+
+ lp_list_free(&auth_method_list);
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a random challenge
+***************************************************************************/
+
+BOOL make_auth_info_random(auth_authsupplied_info **auth_info)
+{
+ uchar chal[8];
+ if (!make_auth_info_subsystem(auth_info)) {
+ return False;
+ }
+
+ generate_random_buffer(chal, sizeof(chal), False);
+ (*auth_info)->challenge = data_blob(chal, sizeof(chal));
+
+ (*auth_info)->challenge_set_by = "random";
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a fixed challenge
+***************************************************************************/
+
+BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8])
+{
+ if (!make_auth_info_subsystem(auth_info)) {
+ return False;
+ }
+
+ (*auth_info)->challenge = data_blob(chal, 8);
+ return True;
+}
+
+/***************************************************************************
+ Clear out a auth_info struct that has been allocated
+***************************************************************************/
+
+void free_auth_info(auth_authsupplied_info **auth_info)
+{
+ auth_methods *list;
+ if (*auth_info != NULL) {
+ list = (*auth_info)->auth_method_list;
+ while (list) {
+ auth_methods *old_head = list;
+ if (list->free_private_data) {
+ list->free_private_data(&(list->private_data));
+ }
+ DLIST_REMOVE(list, list);
+ SAFE_FREE(old_head);
+ }
+
+ data_blob_free(&(*auth_info)->challenge);
+ ZERO_STRUCT(**auth_info);
+ }
+ SAFE_FREE(*auth_info);
+}
+
+/****************************************************************************
+ Try to get a challenge out of the various authenticaion modules.
+ It is up to the caller to free it.
+****************************************************************************/
+
+DATA_BLOB auth_get_challenge(auth_authsupplied_info *auth_info)
+{
+ DATA_BLOB challenge = data_blob(NULL, 0);
+ char *challenge_set_by = NULL;
+ auth_methods *auth_method;
+
+ if (auth_info->challenge.length) {
+ DEBUG(5, ("auth_get_challenge: returning previous challenge (normal)\n"));
+ return data_blob(auth_info->challenge.data, auth_info->challenge.length);
+ }
+
+ for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
+ {
+ if (auth_method->get_chal) {
+ DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name));
+ if (challenge_set_by) {
+ DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n",
+ challenge_set_by, auth_method->name));
+ } else {
+ challenge = auth_method->get_chal(&auth_method->private_data, auth_info);
+ if (challenge.length) {
+ DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
+ auth_info->challenge = challenge;
+ challenge_set_by = auth_method->name;
+ auth_info->challenge_set_method = auth_method;
+ } else {
+ DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n",
+ auth_method->name));
+ }
+ }
+ } else {
+ DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
+ }
+ }
+
+ if (!challenge_set_by) {
+ uchar chal[8];
+
+ generate_random_buffer(chal, sizeof(chal), False);
+ auth_info->challenge = data_blob(chal, sizeof(chal));
+
+ challenge_set_by = "random";
+ }
+
+ DEBUG(5, ("auth_info challenge created by %s\n", challenge_set_by));
+ DEBUG(5, ("challenge is: \n"));
+ dump_data(5, auth_info->challenge.data, (auth_info)->challenge.length);
+
+ SMB_ASSERT(auth_info->challenge.length == 8);
+
+ auth_info->challenge_set_by=challenge_set_by;
+
+ return data_blob(auth_info->challenge.data, auth_info->challenge.length);
+}
+
+