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:
parent
1a25f56066
commit
d3832506b2
@ -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 */
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"},
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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))
|
||||
|
@ -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 */
|
||||
|
@ -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))
|
||||
{
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user