1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-22 22:04:08 +03:00

This is the checkin that adds the security=domain functionality.

WARNING - so far this has only been tested against a Samba PDC
(still waiting for IS to add me the machine accounts :-).

Still missing is the code in smbpasswd that will add a machine
account password and change it on the domain controller, but
this is not hard, and I will check it in soon.

Jeremy.
(This used to be commit 17b94a7084621b3f0106dd4d3386f05cdfc56d19)
This commit is contained in:
Jeremy Allison 1998-04-29 00:02:57 +00:00
parent 1a25f56066
commit d3832506b2
14 changed files with 235 additions and 173 deletions

View File

@ -60,6 +60,7 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
char **rparam, uint32 *rparam_count,
char **rdata, uint32 *rdata_count);
BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *));
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
void (*fn)(char *, uint32, char *));
BOOL cli_session_setup(struct cli_state *cli,
@ -222,6 +223,44 @@ int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
void interpret_coding_system(char *str);
void initialize_multibyte_vectors( int client_codepage);
/*The following definitions come from lib/rpc/client/cli_login.c */
BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
uint32 smb_userid_low, char *password,
NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
char nt_chal_resp[24],
NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
/*The following definitions come from lib/rpc/client/cli_netlogon.c */
BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
uint32 neg_flags, DOM_CHAL *srv_chal);
BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
NET_USER_INFO_3 *user_info3);
BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
/*The following definitions come from lib/rpc/client/cli_pipe.c */
uint32 get_rpc_call_id(void);
BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
prs_struct *param , prs_struct *data,
prs_struct *rparam, prs_struct *rdata);
BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
prs_struct *data, prs_struct *rdata);
BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state);
BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth);
BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted);
void nt_session_close(struct cli_state *cli);
/*The following definitions come from lib/rpc/parse/parse_lsa.c */
void make_lsa_trans_name(LSA_TRANS_NAME *trn, uint32 sid_name_use, char *name, uint32 idx);
@ -347,9 +386,8 @@ void make_q_auth_2(NET_Q_AUTH_2 *q_a,
DOM_CHAL *clnt_chal, uint32 clnt_flgs);
void net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
void net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
DOM_CRED *cred, char nt_cypher[16]);
void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16]);
void net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
void net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
@ -1707,7 +1745,7 @@ void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key);
void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
void SamOEMhash( unsigned char *data, unsigned char *key, int val);
/*The following definitions come from smbencrypt.c */

View File

@ -301,6 +301,9 @@ typedef struct id_info_1
} NET_ID_INFO_1;
#define INTERACTIVE_LOGON_TYPE 1
#define NET_LOGON_TYPE 2
/* NET_ID_INFO_CTR */
typedef struct net_id_info_ctr_info
{

View File

@ -335,8 +335,8 @@ struct cli_state {
uint16 nt_pipe_fnum; /* Pipe handle. */
unsigned char sess_key[16]; /* Current session key. */
DOM_CRED clnt_cred; /* Client credential. */
fstring mach_acct;
fstring srv_name;
fstring mach_acct; /* MYNAME$. */
fstring srv_name_slash; /* \\remote server. */
};
@ -1070,11 +1070,7 @@ char *Strstr(char *s, char *p);
enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
/* security levels */
#ifdef DOMAIN_CLIENT
enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN};
#else /* DOMAIN_CLIENT */
enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
#endif /* DOMAIN_CLIENT */
/* printing types */
enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,

View File

@ -527,6 +527,8 @@ char *get_nt_error_msg(uint32 nt_code)
strcpy(msg, "Unknown NT error");
nt_code &= 0xFFFF;
while (nt_errs[idx].nt_errstr != NULL)
{
if (nt_errs[idx].nt_errcode == nt_code)
@ -536,6 +538,6 @@ char *get_nt_error_msg(uint32 nt_code)
}
idx++;
}
return NULL;
return msg;
}

View File

@ -347,13 +347,13 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
smbhash(out, buf, key2, 1);
}
void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key)
void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
{
static unsigned char key2[8];
smbhash(out, in, key, 0);
smbhash(out, in, key, forw);
key2[0] = key[7];
smbhash(out + 8, in + 8, key2, 0);
smbhash(out + 8, in + 8, key2, forw);
}
void SamOEMhash( unsigned char *data, unsigned char *key, int val)

View File

@ -402,14 +402,9 @@ static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANM
{PROTOCOL_COREPLUS, "COREPLUS"},
{PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}};
#ifdef DOMAIN_CLIENT
static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
{SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
{-1, NULL}};
#else /* DOMAIN_CLIENT */
static struct enum_list enum_security[] = {{SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
{SEC_SERVER, "SERVER"}, {-1, NULL}};
#endif /* DOMAIN_CLIENT */
static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
{PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},

View File

@ -1072,8 +1072,6 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
return True;
}
#ifdef DOMAIN_CLIENT
static int mach_passwd_lock_depth;
/************************************************************************
@ -1250,4 +1248,3 @@ machine account is now invalid. Please recreate. Error was %s.\n", strerror(errn
fflush(fp);
return True;
}
#endif /* DOMAIN_CLIENT */

View File

@ -75,67 +75,45 @@ BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
return True;
}
#if 0
/****************************************************************************
server password set
Set machine password.
****************************************************************************/
BOOL do_nt_srv_pwset(struct cli_state *cli,
uint8 sess_key[16], DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
char *new_mach_pwd,
char *dest_host, char *mach_acct, char *myhostname)
BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
{
DOM_CRED cred;
char nt_cypher[16];
uint8 mode = 1;
char nt_owf_new_mach_pwd[16];
unsigned char processed_new_pwd[16];
DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
#ifdef DEBUG_PASSWORD
DEBUG(100,("generating nt owf from new machine pwd: %s\n", new_mach_pwd));
#endif
nt_owf_gen(new_mach_pwd, nt_owf_new_mach_pwd);
#ifdef DEBUG_PASSWORD
dump_data(6, nt_owf_new_mach_pwd, 16);
dump_data(6, new_hashof_mach_pwd, 16);
#endif
if (!obfuscate_pwd(nt_cypher, nt_owf_new_mach_pwd, mode))
{
DEBUG(5,("do_nt_srv_pwset: encrypt mach pwd failed\n"));
return False;
}
clnt_cred->timestamp.time = time(NULL);
memcpy(&cred, clnt_cred, sizeof(cred));
/* calculate credentials */
cred_create(sess_key, &(clnt_cred->challenge),
cred.timestamp, &(cred.challenge));
/* Process the new password. */
cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 0);
/* send client srv_pwset challenge */
return do_net_srv_pwset(cli, fnum, sess_key, clnt_cred,
dest_host, mach_acct, 2, myhostname,
&cred, rtn_cred, nt_cypher);
return cli_net_srv_pwset(cli, processed_new_pwd);
}
/****************************************************************************
make interactive sam login info
NT login - interactive.
*NEVER* use this code. This method of doing a logon (sending the cleartext
password equivalents, protected by the session key) is inherently insecure
given the current design of the NT Domain system. JRA.
****************************************************************************/
void make_nt_login_interactive(NET_ID_INFO_CTR *ctr,
uchar sess_key[16],
char *domain, char *myhostname,
uint32 smb_userid, char *username)
BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
uint32 smb_userid_low, char *password,
NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
{
/****************** SAM Info Preparation *******************/
unsigned char lm_owf_user_pwd[16];
unsigned char nt_owf_user_pwd[16];
BOOL ret;
char *smb_user_passwd = getpass("Enter NT Login Password:");
DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
char lm_owf_user_pwd[16];
char nt_owf_user_pwd[16];
nt_lm_owf_gen(smb_user_passwd, nt_owf_user_pwd, lm_owf_user_pwd);
nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
#ifdef DEBUG_PASSWORD
@ -147,18 +125,35 @@ void make_nt_login_interactive(NET_ID_INFO_CTR *ctr,
#endif
/* indicate an "interactive" login */
ctr->switch_value = 1;
DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
/* this is used in both the SAM Logon and the SAM Logoff */
make_id_info1(&ctr->auth.id1, domain, 0,
smb_userid, 0, username, myhostname,
sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
/* indicate a "network" login */
ctr->switch_value = INTERACTIVE_LOGON_TYPE;
/* Create the structure needed for SAM logon. */
make_id_info1(&ctr->auth.id1, domain, 0,
smb_userid_low, 0,
username, global_myname,
cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
/* Ensure we overwrite all the plaintext password
equivalents. */
memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
/* Send client sam-logon request - update credentials on success. */
ret = cli_net_sam_logon(cli, ctr, user_info3);
memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
return ret;
}
#endif
/****************************************************************************
NT login.
NT login - network.
*ALWAYS* use this call to validate a user as it does not expose plaintext
password equivalents over the network. JRA.
****************************************************************************/
BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,

View File

@ -33,11 +33,30 @@ extern int DEBUGLEVEL;
extern pstring global_myname;
extern fstring global_myworkgroup;
/****************************************************************************
Generate the next creds to use.
****************************************************************************/
static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
{
/*
* Create the new client credentials.
*/
cli->clnt_cred.timestamp.time = time(NULL);
memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
/* Calculate the new credentials. */
cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
}
/****************************************************************************
do a LSA Logon Control2
****************************************************************************/
BOOL do_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
{
prs_struct rbuf;
prs_struct buf;
@ -224,38 +243,33 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
return valid_chal;
}
#if 0
/***************************************************************************
do a LSA Server Password Set
LSA Server Password Set.
****************************************************************************/
BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
uchar sess_key[16], DOM_CRED *sto_clnt_cred,
char *logon_srv, char *mach_acct, uint16 sec_chan_type,
char *comp_name, DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
uint8 nt_owf_new_mach_pwd[16])
BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
{
prs_struct rbuf;
prs_struct buf;
DOM_CRED new_clnt_cred;
NET_Q_SRV_PWSET q_s;
BOOL valid_cred = False;
BOOL ok = False;
uint16 sec_chan_type = 2;
if (srv_cred == NULL || clnt_cred == NULL)
return False;
gen_next_creds( cli, &new_clnt_cred);
prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
/* create and send a MSRPC command with api NET_SRV_PWSET */
DEBUG(4,("LSA Server Password Set: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
cli->srv_name_slash, mach_acct, sec_chan_type, comp_name,
credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time));
DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
/* store the parameters */
make_q_srv_pwset(&q_s, sess_key, logon_srv, mach_acct, sec_chan_type,
comp_name, clnt_cred, nt_owf_new_mach_pwd);
make_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
global_myname, &new_clnt_cred, hashed_mach_pwd);
/* turn parameters into data stream */
net_io_q_srv_pwset("", &q_s, &buf, 0);
@ -264,7 +278,6 @@ BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
{
NET_R_SRV_PWSET r_s;
BOOL ok;
net_io_r_srv_pwset("", &r_s, &rbuf, 0);
ok = (rbuf.offset != 0);
@ -277,31 +290,26 @@ BOOL do_net_srv_pwset(struct cli_state *cli, uint16 fnum,
ok = False;
}
if (ok)
/* Update the credentials. */
if (clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)) == 0)
{
if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_cred)))
{
DEBUG(5, ("do_net_srv_pwset: server credential check OK\n"));
/* ok, at last: we're happy. return the challenge */
memcpy(srv_cred, &(r_s.srv_cred), sizeof(r_s.srv_cred));
valid_cred = True;
}
else
{
DEBUG(5, ("do_net_srv_pwset: server credential check failed\n"));
}
/*
* Server replied with bad credential. Fail.
*/
DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
password ?).\n", cli->desthost ));
ok = False;
}
}
prs_mem_free(&rbuf);
prs_mem_free(&buf );
return valid_cred;
return ok;
}
#endif
/***************************************************************************
LSA SAM Logon.
LSA SAM Logon - interactive or network.
****************************************************************************/
BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
@ -314,17 +322,7 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
NET_Q_SAM_LOGON q_s;
BOOL ok = False;
/*
* Create the new client credentials.
*/
cli->clnt_cred.timestamp.time = time(NULL);
memcpy(&new_clnt_cred, &cli->clnt_cred, sizeof(new_clnt_cred));
/* Calculate the new credentials. */
cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
new_clnt_cred.timestamp, &(new_clnt_cred.challenge));
gen_next_creds( cli, &new_clnt_cred);
prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
@ -400,17 +398,7 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
uint16 validation_level = 3;
BOOL ok = False;
/*
* Create the new client credentials.
*/
cli->clnt_cred.timestamp.time = time(NULL);
memcpy(&new_clnt_cred, &cli->clnt_cred, sizeof(new_clnt_cred));
/* Calculate the new credentials. */
cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
new_clnt_cred.timestamp, &(new_clnt_cred.challenge));
gen_next_creds( cli, &new_clnt_cred);
prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
@ -453,7 +441,7 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
*/
DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \
password ?).\n", cli->desthost ));
ok = False;
ok = False;
}
}

View File

@ -499,9 +499,8 @@ void net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
/*******************************************************************
reads or writes a structure.
********************************************************************/
void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
DOM_CRED *cred, char nt_cypher[16])
void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
{
if (q_s == NULL || cred == NULL) return;
@ -748,7 +747,7 @@ void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
}
/*******************************************************************
reads or writes an NET_ID_INFO_1 structure.
reads or writes an NET_ID_INFO_2 structure.
********************************************************************/
void net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth)
{

View File

@ -383,14 +383,14 @@ static void api_net_srv_pwset( int uid,
DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
q_a.clnt_id.login.uni_acct_name.uni_str_len));
pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
q_a.clnt_id.login.uni_acct_name.uni_str_len));
DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
become_root(True);
smb_pass = getsmbpwnam(mach_acct);
unbecome_root(True);
become_root(True);
smb_pass = getsmbpwnam(mach_acct);
unbecome_root(True);
if (smb_pass != NULL)
{
@ -402,7 +402,7 @@ static void api_net_srv_pwset( int uid,
DEBUG(100,("%02X ", q_a.pwd[i]));
DEBUG(100,("\n"));
cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key);
cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 1);
/* lies! nt and lm passwords are _not_ the same: don't care */
smb_pass->smb_passwd = pwd;
@ -515,13 +515,13 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
user_struct *vuser)
{
DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
id2->lm_chal_resp.str_str_len,
id2->nt_chal_resp.str_str_len));
id2->hdr_lm_chal_resp.str_str_len,
id2->hdr_nt_chal_resp.str_str_len));
/* JRA. Check the NT password first if it exists - this is a higher quality
password, if it exists and it doesn't match - fail. */
if (id2->nt_chal_resp.str_str_len == 24 &&
if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
smb_pass->smb_nt_passwd != NULL)
{
if(smb_password_check(id2->nt_chal_resp.buffer,
@ -540,7 +540,7 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
not do, for various security-hole reasons).
*/
if (id2->lm_chal_resp.str_str_len == 24 &&
if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
smb_password_check(id2->lm_chal_resp.buffer,
smb_pass->smb_passwd,
id2->lm_chal))

View File

@ -32,6 +32,7 @@ extern int Protocol;
static pstring session_users="";
extern pstring global_myname;
extern fstring global_myworkgroup;
/* these are kept here to keep the string_combinations function simple */
static char this_user[100]="";
@ -1865,7 +1866,6 @@ use this machine as the password server.\n"));
return(True);
}
#ifdef DOMAIN_CLIENT
/***********************************************************************
Do the same as security=server, but using NT Domain calls and a session
key from the machine password.
@ -1875,17 +1875,20 @@ BOOL domain_client_validate( char *user, char *domain,
char *smb_apasswd, int smb_apasslen,
char *smb_ntpasswd, int smb_ntpasslen)
{
unsigned char local_lm_hash[21];
unsigned char local_nt_hash[21];
unsigned char local_challenge[8];
unsigned char local_lm_response[24];
unsigned char local_nt_reponse[24];
BOOL encrypted = True;
unsigned char machine_passwd[16];
time_t lct;
fstring remote_machine;
char *p;
struct in_addr dest_ip;
NET_ID_INFO_CTR ctr;
NET_USER_INFO_3 info3;
struct cli_state cli;
uint32 smb_uid_low;
BOOL connected_ok = False;
void *vp;
/*
* Check that the requested domain is not our own machine name.
@ -1909,14 +1912,9 @@ BOOL domain_client_validate( char *user, char *domain,
*/
DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n"));
encrypted = False;
memset(local_lm_hash, '\0', sizeof(local_lm_hash));
E_P16((uchar *) smb_apasswd, local_lm_hash);
memset(local_nt_hash, '\0', sizeof(local_nt_hash));
E_md4hash((uchar *) smb_ntpasswd, local_nt_hash);
generate_random_buffer( local_challenge, 8, False);
E_P24(local_lm_hash, local_challenge, local_lm_response);
E_P24(local_nt_hash, local_challenge, local_nt_reponse);
SMBencrypt( smb_apasswd, local_challenge, local_lm_response);
SMBNTencrypt( smb_ntpasswd, local_challenge, local_nt_reponse);
smb_apasslen = 24;
smb_ntpasslen = 24;
smb_apasswd = (char *)local_lm_response;
@ -1934,6 +1932,29 @@ BOOL domain_client_validate( char *user, char *domain,
}
}
/*
* Get the machine account password.
*/
if((vp = machine_password_lock( global_myworkgroup, global_myname, False)) == NULL) {
DEBUG(0,("domain_client_validate: unable to open the machine account password file for \
machine %s in domain %s.\n", global_myname, global_myworkgroup ));
return False;
}
if(get_machine_account_password( vp, machine_passwd, &lct) == False) {
DEBUG(0,("domain_client_validate: unable to read the machine account password for \
machine %s in domain %s.\n", global_myname, global_myworkgroup ));
machine_password_unlock(vp);
return False;
}
machine_password_unlock(vp);
/*
* Here we should check the last change time to see if the machine
* password needs changing..... TODO... JRA.
*/
/*
* At this point, smb_apasswd points to the lanman response to
* the challenge in local_challenge, and smb_ntpasswd points to
@ -1942,6 +1963,12 @@ BOOL domain_client_validate( char *user, char *domain,
* see if they were valid.
*/
memset(&cli, '\0', sizeof(struct cli_state));
if(cli_initialise(&cli) == False) {
DEBUG(0,("domain_client_validate: unable to initialize client connection.\n"));
return False;
}
/*
* Treat each name in the 'password server =' line as a potential
* PDC/BDC. Contact each in turn and try and authenticate.
@ -1963,8 +1990,6 @@ BOOL domain_client_validate( char *user, char *domain,
continue;
}
memset(&cli, '\0', sizeof(struct cli_state));
if (!cli_connect(&cli, remote_machine, &dest_ip)) {
DEBUG(0,("domain_client_validate: unable to connect to SMB server on \
machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
@ -2032,7 +2057,6 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
return False;
}
#if 0 /* for now... JRA */
/*
* Ok - we have an anonymous connection to the IPC$ share.
* Now start the NT Domain stuff :-).
@ -2041,14 +2065,49 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) {
DEBUG(0,("domain_client_validate: unable to open the domain client session to \
machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
cli_close(&cli, fnum);
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return False;
}
if(cli_nt_setup_creds(&cli,) HERE
#endif
return False;
if(cli_nt_setup_creds(&cli, machine_passwd) == False) {
DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \
%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return False;
}
/* We really don't care what LUID we give the user. */
generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
if(cli_nt_login_network(&cli, domain, user, smb_uid_low, local_challenge,
smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) {
DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return False;
}
/*
* Here, if we really want it, we have lots of info about the user in info3.
*/
if(cli_nt_logoff(&cli, &ctr) == False) {
DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return False;
}
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return True;
}
#endif /* DOMAIN_CLIENT */

View File

@ -516,11 +516,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
passlen1 = MIN(passlen1, MAX_PASS_LEN);
passlen2 = MIN(passlen2, MAX_PASS_LEN);
#ifdef DOMAIN_CLIENT
if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
#else /* DOMAIN_CLIENT */
if(doencrypt || lp_security() == SEC_SERVER) {
#endif /* DOMAIN_CLIENT */
/* Save the lanman2 password and the NT md4 password. */
smb_apasslen = passlen1;
memcpy(smb_apasswd,p,smb_apasslen);
@ -608,12 +604,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
server_validate(user, domain,
smb_apasswd, smb_apasslen,
smb_ntpasswd, smb_ntpasslen)) &&
#ifdef DOMAIN_CLIENT
!(lp_security() == SEC_DOMAIN &&
domain_client_validate(user, domain,
smb_apasswd, smb_apasslen,
smb_ntpasswd, smb_ntpasslen)) &&
#endif /* DOMAIN_CLIENT */
!check_hosts_equiv(user))
{

View File

@ -4133,11 +4133,7 @@ static int reply_negprot(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz
/* a special case to stop password server loops */
if (Index == 1 && strequal(remote_machine,myhostname) &&
#ifdef DOMAIN_CLIENT
(lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
#else /* DOMAIN_CLIENT */
lp_security()==SEC_SERVER)
#endif /* DOMAIN_CLIENT */
exit_server("Password server loop!");
/* Check for protocols, most desirable first */