summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-04-29 00:02:57 +0000
committerJeremy Allison <jra@samba.org>1998-04-29 00:02:57 +0000
commitd3832506b2583130c4f4ba4b3edeabca987b7cbb (patch)
tree0f547a84cc7e6ea4b561ce06ab7c70ce84e9589e
parent1a25f56066f950f20cd2ee8cbb15d62ecb9ecc61 (diff)
downloadsamba-d3832506b2583130c4f4ba4b3edeabca987b7cbb.tar.gz
samba-d3832506b2583130c4f4ba4b3edeabca987b7cbb.tar.bz2
samba-d3832506b2583130c4f4ba4b3edeabca987b7cbb.zip
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)
-rw-r--r--source3/include/proto.h46
-rw-r--r--source3/include/rpc_netlogon.h3
-rw-r--r--source3/include/smb.h8
-rw-r--r--source3/libsmb/nterr.c4
-rw-r--r--source3/libsmb/smbdes.c6
-rw-r--r--source3/param/loadparm.c5
-rw-r--r--source3/passdb/smbpass.c3
-rw-r--r--source3/rpc_client/cli_login.c95
-rw-r--r--source3/rpc_client/cli_netlogon.c100
-rw-r--r--source3/rpc_parse/parse_net.c7
-rw-r--r--source3/rpc_server/srv_netlog.c22
-rw-r--r--source3/smbd/password.c97
-rw-r--r--source3/smbd/reply.c6
-rw-r--r--source3/smbd/server.c4
14 files changed, 234 insertions, 172 deletions
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
@@ -34,10 +34,29 @@ 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;
@@ -1935,6 +1933,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
* the NT response to the challenge in local_challenge. Ship
@@ -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 */