mirror of
https://github.com/samba-team/samba.git
synced 2025-11-27 08:23:49 +03:00
First stab at cracklib support (password quality checking) in Samba 3.0
This adds a configure test, that tries to find out if we have a working cracklib installation, and tries to pick up the debian hints on where the dictionary might be found. Default is per my Fedora Core 1 system - I'm not sure how much it changes. Andrew Bartlett
This commit is contained in:
@@ -215,6 +215,7 @@ typedef struct
|
|||||||
int change_notify_timeout;
|
int change_notify_timeout;
|
||||||
int map_to_guest;
|
int map_to_guest;
|
||||||
int min_passwd_length;
|
int min_passwd_length;
|
||||||
|
BOOL use_cracklib;
|
||||||
int oplock_break_wait_time;
|
int oplock_break_wait_time;
|
||||||
int winbind_cache_time;
|
int winbind_cache_time;
|
||||||
int iLockSpinCount;
|
int iLockSpinCount;
|
||||||
@@ -787,6 +788,7 @@ static struct parm_struct parm_table[] = {
|
|||||||
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
|
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
|
{"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
|
{"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
|
||||||
|
{"use cracklib", P_BOOL, P_GLOBAL, &Globals.use_cracklib, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
|
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
|
||||||
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
|
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
|
||||||
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
|
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
|
||||||
@@ -1437,6 +1439,7 @@ static void init_globals(void)
|
|||||||
|
|
||||||
Globals.map_to_guest = 0; /* By Default, "Never" */
|
Globals.map_to_guest = 0; /* By Default, "Never" */
|
||||||
Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
|
Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
|
||||||
|
Globals.use_cracklib = False;
|
||||||
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
|
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
|
||||||
Globals.enhanced_browsing = True;
|
Globals.enhanced_browsing = True;
|
||||||
Globals.iLockSpinCount = 3; /* Try 3 times. */
|
Globals.iLockSpinCount = 3; /* Try 3 times. */
|
||||||
@@ -1788,6 +1791,7 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout
|
|||||||
FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
|
FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
|
||||||
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
|
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
|
||||||
FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
|
FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
|
||||||
|
FN_GLOBAL_BOOL(lp_use_cracklib, &Globals.use_cracklib)
|
||||||
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
|
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
|
||||||
FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
|
FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
|
||||||
FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
|
FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
|
||||||
|
|||||||
@@ -2834,11 +2834,17 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
|
|||||||
DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
|
DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
|
||||||
} else {
|
} else {
|
||||||
/* update the UNIX password */
|
/* update the UNIX password */
|
||||||
if (lp_unix_password_sync() )
|
if (lp_unix_password_sync() ) {
|
||||||
if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
|
struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
|
||||||
|
if (!passwd) {
|
||||||
|
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
|
||||||
pdb_free_sam(&pwd);
|
pdb_free_sam(&pwd);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZERO_STRUCT(plaintext_buf);
|
ZERO_STRUCT(plaintext_buf);
|
||||||
@@ -2899,7 +2905,12 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
|
|||||||
} else {
|
} else {
|
||||||
/* update the UNIX password */
|
/* update the UNIX password */
|
||||||
if (lp_unix_password_sync()) {
|
if (lp_unix_password_sync()) {
|
||||||
if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
|
struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
|
||||||
|
if (!passwd) {
|
||||||
|
DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
|
||||||
pdb_free_sam(&pwd);
|
pdb_free_sam(&pwd);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,14 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
#include <crack.h>
|
||||||
|
|
||||||
|
#ifndef HAVE_CRACKLIB_DICTPATH
|
||||||
|
#ifndef CRACKLIB_DICTPATH
|
||||||
|
#define CRACKLIB_DICTPATH SAMBA_CRACKLIB_DICTPATH
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
extern struct passdb_ops pdb_ops;
|
extern struct passdb_ops pdb_ops;
|
||||||
|
|
||||||
static NTSTATUS check_oem_password(const char *user,
|
static NTSTATUS check_oem_password(const char *user,
|
||||||
@@ -441,25 +449,14 @@ while we were waiting\n", WTERMSIG(wstat)));
|
|||||||
return (chstat);
|
return (chstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root)
|
BOOL chgpasswd(const char *name, const struct passwd *pass,
|
||||||
|
const char *oldpass, const char *newpass, BOOL as_root)
|
||||||
{
|
{
|
||||||
pstring passwordprogram;
|
pstring passwordprogram;
|
||||||
pstring chatsequence;
|
pstring chatsequence;
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
struct passwd *pass;
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
DEBUG(1, ("chgpasswd: NULL username specfied !\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
pass = Get_Pwnam(name);
|
|
||||||
if (!pass) {
|
|
||||||
DEBUG(1, ("chgpasswd: Username does not exist in system !\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!oldpass) {
|
if (!oldpass) {
|
||||||
oldpass = "";
|
oldpass = "";
|
||||||
}
|
}
|
||||||
@@ -471,13 +468,6 @@ BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Take the passed information and test it for minimum criteria */
|
/* Take the passed information and test it for minimum criteria */
|
||||||
/* Minimum password length */
|
|
||||||
if (strlen(newpass) < lp_min_passwd_length()) {
|
|
||||||
/* too short, must be at least MINPASSWDLENGTH */
|
|
||||||
DEBUG(0, ("chgpasswd: Password Change: user %s, New password is shorter than minimum password length = %d\n",
|
|
||||||
name, lp_min_passwd_length()));
|
|
||||||
return (False); /* inform the user */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Password is same as old password */
|
/* Password is same as old password */
|
||||||
if (strcmp(oldpass, newpass) == 0) {
|
if (strcmp(oldpass, newpass) == 0) {
|
||||||
@@ -570,7 +560,8 @@ the string %%u, and the given string %s does not.\n", passwordprogram ));
|
|||||||
|
|
||||||
#else /* ALLOW_CHANGE_PASSWORD */
|
#else /* ALLOW_CHANGE_PASSWORD */
|
||||||
|
|
||||||
BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root)
|
BOOL chgpasswd(const char *name, const struct passwd *pass,
|
||||||
|
const char *oldpass, const char *newpass, BOOL as_root)
|
||||||
{
|
{
|
||||||
DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name));
|
DEBUG(0, ("chgpasswd: Password changing not compiled in (user=%s)\n", name));
|
||||||
return (False);
|
return (False);
|
||||||
@@ -909,6 +900,8 @@ static NTSTATUS check_oem_password(const char *user,
|
|||||||
|
|
||||||
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root)
|
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root)
|
||||||
{
|
{
|
||||||
|
struct passwd *pass;
|
||||||
|
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
uint32 min_len;
|
uint32 min_len;
|
||||||
|
|
||||||
@@ -936,7 +929,47 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
|
|||||||
/* return NT_STATUS_PWD_TOO_SHORT; */
|
/* return NT_STATUS_PWD_TOO_SHORT; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add cracklib support here */
|
pass = Get_Pwnam(pdb_get_username(hnd));
|
||||||
|
if (!pass) {
|
||||||
|
DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WORKING_CRACKLIB
|
||||||
|
if (pass) {
|
||||||
|
/* if we can, become the user to overcome internal cracklib sillyness */
|
||||||
|
if (!push_sec_ctx())
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
|
||||||
|
set_re_uid();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp_use_cracklib()) {
|
||||||
|
const char *crack_check_reason;
|
||||||
|
DEBUG(4, ("change_oem_password: Checking password for user [%s]"
|
||||||
|
" against cracklib. \n", pdb_get_username(hnd)));
|
||||||
|
DEBUGADD(4, ("If this is your last message, then something is "
|
||||||
|
"wrong with cracklib, it might be missing it's "
|
||||||
|
"dictionaries at %s\n",
|
||||||
|
CRACKLIB_DICTPATH));
|
||||||
|
dbgflush();
|
||||||
|
|
||||||
|
crack_check_reason = FascistCheck(new_passwd, (char *)CRACKLIB_DICTPATH);
|
||||||
|
if (crack_check_reason) {
|
||||||
|
DEBUG(1, ("Password Change: user [%s], "
|
||||||
|
"New password failed cracklib test - %s\n",
|
||||||
|
pdb_get_username(hnd), crack_check_reason));
|
||||||
|
|
||||||
|
/* get back to where we should be */
|
||||||
|
if (pass)
|
||||||
|
pop_sec_ctx();
|
||||||
|
return NT_STATUS_PASSWORD_RESTRICTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pass)
|
||||||
|
pop_sec_ctx();
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If unix password sync was requested, attempt to change
|
* If unix password sync was requested, attempt to change
|
||||||
@@ -951,7 +984,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if(lp_unix_password_sync() &&
|
if(lp_unix_password_sync() &&
|
||||||
!chgpasswd(pdb_get_username(hnd), old_passwd, new_passwd, as_root)) {
|
!chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) {
|
||||||
return NT_STATUS_ACCESS_DENIED;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
source/tests/crack.c
Normal file
5
source/tests/crack.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
FascistCheck("Foo", CRACKLIB_DICTPATH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user