From d83845241381fb6ff86890d1d43c3d3bf6522a2b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Oct 1997 19:16:38 +0000 Subject: smb.h smbparse.c pipenetlog.c : whoops, the SAM Logon structure was wrong. updated this, and cifsntdomain.txt. more debug info in pipenetlog.c. the crash is somewhere around deal_with_credentials(). byteorder.h : put in uint8, uint16 and uint32 typecasts around debug info, because sign extending was resulting in ffffffe8 being displayed instead of e8. credentials.c : some debugging info, because i'm tracking a coredump. without gdb. nothing like making things difficult. reply.c : whoops, missed this (important) bit from paul's code, which tells the NT workstation that the MACHINE$ entry doesn't already exist, and we're going to create a default entry with a password "machine" right now. proto.h: the usual. (This used to be commit ed606bc7d4e6fb1091e527ea70a3e950d50a1db4) --- source3/include/byteorder.h | 8 ++++---- source3/include/proto.h | 2 ++ source3/include/smb.h | 26 ++++++++++++++++++++++---- source3/libsmb/credentials.c | 3 +-- source3/pipenetlog.c | 36 ++++++++++++++++++++++++++++-------- source3/smbd/reply.c | 25 ++++++++++++++++++++++++- source3/smbparse.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 122 insertions(+), 21 deletions(-) diff --git a/source3/include/byteorder.h b/source3/include/byteorder.h index e11771c3ab..f43159ecf4 100644 --- a/source3/include/byteorder.h +++ b/source3/include/byteorder.h @@ -206,27 +206,27 @@ it also defines lots of intermediate macros, just ignore those :-) RW_PCVAL(read,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), PTR_DIFF(inbuf,base),string)); \ - { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \ + { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (uint8)((outbuf)[idx]))); } } \ DEBUG(5,("\n")); #define DBG_RW_PSVAL(string,depth,base,read,inbuf,outbuf,len) \ RW_PSVAL(read,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), PTR_DIFF(inbuf,base),string)); \ - { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \ + { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (uint16)((outbuf)[idx]))); } } \ DEBUG(5,("\n")); #define DBG_RW_PIVAL(string,depth,base,read,inbuf,outbuf,len) \ RW_PIVAL(read,inbuf,outbuf,len) \ DEBUG(5,("%s%04x %s: ", \ tab_depth(depth), PTR_DIFF(inbuf,base),string)); \ - { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \ + { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (uint32)((outbuf)[idx]))); } } \ DEBUG(5,("\n")); #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \ RW_CVAL(read,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %02x\n", \ - tab_depth(depth), PTR_DIFF(inbuf,base),string, *(inbuf))); + tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint8*)(inbuf)))); #define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \ RW_SVAL(read,inbuf,outbuf,0) \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 6baa945e8b..70a9873d34 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -855,9 +855,11 @@ char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align, int de char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align, int depth); char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align, int depth); char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align, int depth); +char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align, int depth); char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align, int depth); char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align, int depth); char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align, int depth); +char* smb_io_clnt_info2(BOOL io, DOM_CLNT_INFO2 *clnt, char *q, char *base, int align, int depth); char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align, int depth); char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align, int depth); char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align, int depth); diff --git a/source3/include/smb.h b/source3/include/smb.h index c733f29521..03cdc78e03 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -383,6 +383,16 @@ typedef struct domrid2_info } DOM_RID2; +/* DOM_CLNT_SRV - client / server names */ +typedef struct clnt_srv_info +{ + uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */ + UNISTR2 uni_logon_srv; /* logon server name */ + uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */ + UNISTR2 uni_comp_name; /* client machine name */ + +} DOM_CLNT_SRV; + /* DOM_LOG_INFO - login info */ typedef struct log_info { @@ -417,6 +427,14 @@ typedef struct clnt_info } DOM_CLNT_INFO; +/* DOM_CLNT_INFO2 - client info */ +typedef struct clnt_info2 +{ + DOM_CLNT_SRV login; + DOM_CRED cred; + +} DOM_CLNT_INFO2; + /* DOM_LOGON_ID - logon id */ typedef struct logon_info { @@ -452,10 +470,10 @@ typedef struct id_info_1 /* SAM_INFO - sam logon/off id structure */ typedef struct sam_info { - DOM_CLNT_INFO client; - DOM_CRED rtn_cred; /* return credentials */ - uint16 logon_level; - uint32 auth_level; /* undocumented */ + DOM_CLNT_INFO2 client; + DOM_CRED rtn_cred; /* return credentials */ + uint16 logon_level; + uint32 auth_level; /* undocumented */ union { diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index babc8180f2..d56598e98a 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -99,7 +99,7 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); DEBUG(5,(" stor_cred: %lx %lx\n", stor_cred->data[0], stor_cred->data[1])); - DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0), IVAL(timecred, 4))); + DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0) , IVAL(timecred, 4) )); DEBUG(5,(" calc_cred: %lx %lx\n", cred ->data[0], cred ->data[1])); } @@ -129,7 +129,6 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, DEBUG(5,(" challenge : %lx %lx\n", cred->data[0], cred->data[1])); DEBUG(5,(" calculated: %lx %lx\n", cred2.data[0], cred2.data[1])); - DEBUG(5,(" challenge: ")); return memcmp(cred->data, cred2.data, 8) == 0; } diff --git a/source3/pipenetlog.c b/source3/pipenetlog.c index 6d406ee7d2..d221b8e644 100644 --- a/source3/pipenetlog.c +++ b/source3/pipenetlog.c @@ -86,11 +86,15 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base, return PTR_DIFF(q, base); } -static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a, +static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_s, DOM_CRED *srv_cred, int status) { - memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred)); - r_a->status = status; + DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__)); + + memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred)); + r_s->status = status; + + DEBUG(5,("make_lsa_r_srv_pwset: %d\n", __LINE__)); } static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, @@ -98,12 +102,16 @@ static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base, { LSA_R_SRV_PWSET r_s; + DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__)); + /* set up the LSA Server Password Set response */ make_lsa_r_srv_pwset(&r_s, srv_cred, status); /* store the response in the SMB stream */ q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4, 0); + DEBUG(5,("lsa_srv_pwset: %d\n", __LINE__)); + /* return length of SMB data stored */ return PTR_DIFF(q, base); } @@ -395,14 +403,24 @@ static BOOL deal_with_credentials(user_struct *vuser, /* increment client time by one second */ new_clnt_time.time = clnt_cred->timestamp.time + 1; + DEBUG(5,("deal_with_credentials: new_clnt_time=%lx\n", new_clnt_time.time)); + /* create server credentials for inclusion in the reply */ cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, &(srv_cred->challenge)); + + DEBUG(5,("deal_with_credentials: %d\n", __LINE__)); + + DEBUG(5,("deal_with_credentials: clnt_cred[0]=%lx\n", + vuser->dc.clnt_cred.data[0])); + + new_cred = IVAL(vuser->dc.clnt_cred.data, 0); + new_cred += new_clnt_time.time; - /* update the client and server credentials, for use next time... */ - new_cred = IVAL(vuser->dc.clnt_cred.data, 0) + new_clnt_time.time; - SIVAL(vuser->dc.clnt_cred.data, new_cred, 0); - SIVAL(vuser->dc.srv_cred.data , new_cred, 0); + DEBUG(5,("deal_with_credentials: new_cred[0]=%lx\n", new_cred)); + + SIVAL(vuser->dc.clnt_cred.data, 0, new_cred); + SIVAL(vuser->dc.srv_cred .data, 0, new_cred); return True; } @@ -421,6 +439,8 @@ static void api_lsa_srv_pwset( user_struct *vuser, /* checks and updates credentials. creates reply credentials */ deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); + DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__)); + /* construct reply. always indicate failure. nt keeps going... */ *rdata_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata, &srv_cred, @@ -487,7 +507,7 @@ static void api_lsa_sam_logon( user_struct *vuser, pstrcpy(dom_sid , lp_domainsid ()); pstrcpy(my_workgroup, lp_workgroup ()); - pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer)); + pstrcpy(username, unistr2(q_l.sam_id.auth.id1.uni_user_name.buffer)); pstrcpy(my_name , myname ); strupper(my_name); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index baccb76291..dffb6f05bd 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -479,8 +479,31 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* computer with that name (minus the $) has access. For now */ /* say yes to everything ending in $. */ if (user[strlen(user) - 1] == '$') { - computer_id = True; + struct smb_passwd *smb_pass; /* To check if machine account exists */ +#ifdef NTDOMAIN +/* + PAXX: Ack. We don't want to do this. The workstation trust account + with a $ on the end should exist in the local password database + or be mapped to something generic, but not modified. For NT + domain support we must reject this used in certain circumstances + with a code to indicate to the client that it is an invalid use + of a workstation trust account. NTWKS needs this error to join + a domain. This may be the source of future bugs if we cannot + be sure whether to reject this or not. +*/ + smb_pass = get_smbpwnam(user); + if(smb_pass) + { + /* PAXX: This is the NO LOGON workstation trust account stuff */ + DEBUG(4,("Rejecting workstation trust account %s",user)); + SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */ + CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */ + return(ERROR(0x99,0xc000)); /* 0x99 NT error, 0xc00 */ + } + computer_id = True; +#else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */ user[strlen(user) - 1] = '\0'; +#endif } diff --git a/source3/smbparse.c b/source3/smbparse.c index 64a0e640cb..03ef5afe8e 100644 --- a/source3/smbparse.c +++ b/source3/smbparse.c @@ -244,6 +244,27 @@ char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align, i return q; } +/******************************************************************* +reads or writes a DOM_CLNT_SRV structure. +********************************************************************/ +char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align, int depth) +{ + if (log == NULL) return NULL; + + DEBUG(5,("%s%04x smb_io_clnt_srv\n", tab_depth(depth), PTR_DIFF(q, base))); + depth++; + + q = align_offset(q, base, align); + + DBG_RW_IVAL("undoc_buffer ", depth, base, io, q, log->undoc_buffer); q += 4; + q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align, depth); + + DBG_RW_IVAL("undoc_buffer2", depth, base, io, q, log->undoc_buffer); q += 4; + q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, align, depth); + + return q; +} + /******************************************************************* reads or writes a DOM_LOG_INFO structure. ********************************************************************/ @@ -306,6 +327,24 @@ char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align, int d return q; } +/******************************************************************* +reads or writes a DOM_CLNT_INFO2 structure. +********************************************************************/ +char* smb_io_clnt_info2(BOOL io, DOM_CLNT_INFO2 *clnt, char *q, char *base, int align, int depth) +{ + if (clnt == NULL) return NULL; + + DEBUG(5,("%s%04x smb_io_clnt_info2\n", tab_depth(depth), PTR_DIFF(q, base))); + depth++; + + q = align_offset(q, base, align); + + q = smb_io_clnt_srv(io, &(clnt->login), q, base, align, depth); + q = smb_io_cred (io, &(clnt->cred ), q, base, align, depth); + + return q; +} + /******************************************************************* reads or writes a DOM_CLNT_INFO structure. ********************************************************************/ @@ -401,8 +440,8 @@ char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align q = align_offset(q, base, align); - q = smb_io_clnt_info(io, &(sam->client ), q, base, align, depth); - q = smb_io_cred (io, &(sam->rtn_cred), q, base, align, depth); + q = smb_io_clnt_info2(io, &(sam->client ), q, base, align, depth); + q = smb_io_cred (io, &(sam->rtn_cred), q, base, align, depth); DBG_RW_IVAL("logon_level", depth, base, io, q, sam->logon_level); q += 4; DBG_RW_SVAL("auth_level ", depth, base, io, q, sam->auth_level ); q += 4; -- cgit