From d3832506b2583130c4f4ba4b3edeabca987b7cbb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 00:02:57 +0000 Subject: 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) --- source3/include/proto.h | 46 ++++++++++++++++-- source3/include/rpc_netlogon.h | 3 ++ source3/include/smb.h | 8 +-- source3/libsmb/nterr.c | 4 +- source3/libsmb/smbdes.c | 6 +-- source3/param/loadparm.c | 5 -- source3/passdb/smbpass.c | 3 -- source3/rpc_client/cli_login.c | 95 +++++++++++++++++------------------- source3/rpc_client/cli_netlogon.c | 100 +++++++++++++++++--------------------- source3/rpc_parse/parse_net.c | 7 ++- source3/rpc_server/srv_netlog.c | 22 ++++----- source3/smbd/password.c | 97 ++++++++++++++++++++++++++++-------- source3/smbd/reply.c | 6 --- source3/smbd/server.c | 4 -- 14 files changed, 234 insertions(+), 172 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index b999e6a4b6..60f04bde87 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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 */ diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h index 1fc6596821..ca8231fc5b 100644 --- a/source3/include/rpc_netlogon.h +++ b/source3/include/rpc_netlogon.h @@ -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 { diff --git a/source3/include/smb.h b/source3/include/smb.h index 1bf5b318b3..33b38706df 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -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, diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index dca97ab923..0788ae1b60 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -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; } diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index cf46e53ff5..4daf616588 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -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) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c96669dba4..2249c8b473 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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"}, diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index f3b38c43e7..15f1d4d37f 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -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 */ diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c index fe00c39e4c..1feda1cfe3 100644 --- a/source3/rpc_client/cli_login.c +++ b/source3/rpc_client/cli_login.c @@ -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]; -#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); + DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); #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 *******************/ - - char *smb_user_passwd = getpass("Enter NT Login Password:"); + unsigned char lm_owf_user_pwd[16]; + unsigned char nt_owf_user_pwd[16]; + BOOL ret; - char lm_owf_user_pwd[16]; - char nt_owf_user_pwd[16]; + DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__)); - 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, diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 91dbd27421..a8aba1c5dc 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -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; } } diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c index c5dd23a00e..84a88e4b92 100644 --- a/source3/rpc_parse/parse_net.c +++ b/source3/rpc_parse/parse_net.c @@ -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) { diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c index 6aa1cd707e..1f76d545f6 100644 --- a/source3/rpc_server/srv_netlog.c +++ b/source3/rpc_server/srv_netlog.c @@ -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)) diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0e9ec620b1..21424592f1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -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 */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index fe1de65be3..a8a0c2f98c 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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)) { diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 167911e497..ac18bb4038 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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 */ -- cgit