-/*
+/*
Unix SMB/CIFS implementation.
Password checking
Copyright (C) Andrew Tridgell 1992-1998
-
+
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 3 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, see <http://www.gnu.org/licenses/>.
*/
offset is the first char to try and change (start with 0)
it assumes the string starts lowercased
****************************************************************************/
-static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *),
- int N)
+static NTSTATUS string_combinations2(char *s, int offset,
+ NTSTATUS (*fn)(const char *s,
+ void *private_data),
+ int N, void *private_data)
{
int len = strlen(s);
int i;
#endif
if (N <= 0 || offset >= len)
- return (fn(s));
+ return (fn(s, private_data));
for (i = offset; i < (len - (N - 1)); i++) {
char c = s[i];
if (!islower_ascii(c))
continue;
s[i] = toupper_ascii(c);
- if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) {
- return (nt_status);
+ nt_status = string_combinations2(s, i + 1, fn, N - 1,
+ private_data);
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
+ return nt_status;
}
s[i] = c;
}
offset is the first char to try and change (start with 0)
it assumes the string starts lowercased
****************************************************************************/
-static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N)
+static NTSTATUS string_combinations(char *s,
+ NTSTATUS (*fn)(const char *s,
+ void *private_data),
+ int N, void *private_data)
{
int n;
NTSTATUS nt_status;
- for (n = 1; n <= N; n++)
- if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, 0, fn, n), NT_STATUS_WRONG_PASSWORD))
+ for (n = 1; n <= N; n++) {
+ nt_status = string_combinations2(s, 0, fn, n, private_data);
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
return nt_status;
+ }
+ }
return NT_STATUS_WRONG_PASSWORD;
}
/****************************************************************************
core of password checking routine
****************************************************************************/
-static NTSTATUS password_check(const char *password)
+static NTSTATUS password_check(const char *password, void *private_data)
{
#ifdef WITH_PAM
- return smb_pam_passcheck(get_this_user(), password);
+ const char *rhost = (const char *)private_data;
+ return smb_pam_passcheck(get_this_user(), rhost, password);
#else
bool ret;
#endif /* WITH_DFS */
#ifdef OSF1_ENH_SEC
-
+
ret = (strcmp(osf1_bigcrypt(password, get_this_salt()),
get_this_crypted()) == 0);
if (!ret) {
} else {
return NT_STATUS_WRONG_PASSWORD;
}
-
+
#endif /* OSF1_ENH_SEC */
-
+
#ifdef ULTRIX_AUTH
ret = (strcmp((char *)crypt16(password, get_this_salt()), get_this_crypted()) == 0);
if (ret) {
} else {
return NT_STATUS_WRONG_PASSWORD;
}
-
+
#endif /* ULTRIX_AUTH */
-
+
#ifdef LINUX_BIGCRYPT
ret = (linux_bigcrypt(password, get_this_salt(), get_this_crypted()));
if (ret) {
return NT_STATUS_WRONG_PASSWORD;
}
#endif /* LINUX_BIGCRYPT */
-
+
#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
-
+
/*
* Some systems have bigcrypt in the C library but might not
* actually use it for the password hashes (HPUX 10.20) is
return NT_STATUS_WRONG_PASSWORD;
}
#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
-
+
#ifdef HAVE_BIGCRYPT
ret = (strcmp(bigcrypt(password, get_this_salt()), get_this_crypted()) == 0);
if (ret) {
return NT_STATUS_WRONG_PASSWORD;
}
#endif /* HAVE_BIGCRYPT */
-
+
#ifndef HAVE_CRYPT
DEBUG(1, ("Warning - no crypt available\n"));
return NT_STATUS_LOGON_FAILURE;
return NT_STATUS_OK on correct match, appropriate error otherwise
****************************************************************************/
-NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password,
- int pwlen, bool (*fn) (const char *, const char *), bool run_cracker)
+NTSTATUS pass_check(const struct passwd *pass,
+ const char *user,
+ const char *password,
+ bool run_cracker)
{
char *pass2 = NULL;
int level = lp_passwordlevel();
NTSTATUS nt_status;
+ const char *rhost;
+ char addr[INET6_ADDRSTRLEN];
+
+ rhost = client_name(smbd_server_fd());
+ if (strequal(rhost,"UNKNOWN"))
+ rhost = client_addr(smbd_server_fd(), addr, sizeof(addr));
+
#ifdef DEBUG_PASSWORD
DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password));
#endif
if (!password)
return NT_STATUS_LOGON_FAILURE;
- if (((!*password) || (!pwlen)) && !lp_null_passwords())
+ if ((!*password) && !lp_null_passwords())
return NT_STATUS_LOGON_FAILURE;
#if defined(WITH_PAM)
return NT_STATUS_NO_MEMORY;
}
- DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen));
+ DEBUG(4, ("pass_check: Checking (PAM) password for user %s\n", user));
#else /* Not using PAM */
- DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen));
+ DEBUG(4, ("pass_check: Checking password for user %s\n", user));
if (!pass) {
DEBUG(3, ("Couldn't find user %s\n", user));
#endif /* defined(WITH_PAM) */
/* try it as it came to us */
- nt_status = password_check(password);
+ nt_status = password_check(password, (void *)rhost);
if NT_STATUS_IS_OK(nt_status) {
- if (fn) {
- fn(user, password);
- }
return (nt_status);
} else if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
/* No point continuing if its not the password thats to blame (ie PAM disabled). */
/* try all lowercase if it's currently all uppercase */
if (strhasupper(pass2)) {
strlower_m(pass2);
- if NT_STATUS_IS_OK(nt_status = password_check(pass2)) {
- if (fn)
- fn(user, pass2);
+ nt_status = password_check(pass2, (void *)rhost);
+ if (NT_STATUS_IS_OK(nt_status)) {
return (nt_status);
}
}
/* last chance - all combinations of up to level chars upper! */
strlower_m(pass2);
-
- if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) {
- if (fn)
- fn(user, pass2);
+
+ nt_status = string_combinations(pass2, password_check, level,
+ (void *)rhost);
+ if (NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
-
+
return NT_STATUS_WRONG_PASSWORD;
}