1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-23 06:50:21 +03:00

added api_lsa_sam_logon() and api_sam_logoff(). that's it. lots of

run-time debugging, now.
(This used to be commit 75f32987d8599d10b294dc4e0c0160eecda7296b)
This commit is contained in:
Luke Leighton 1997-10-10 19:48:51 +00:00
parent 7f296a8f90
commit 422c54ff38

View File

@ -772,29 +772,21 @@ static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
return q - start;
}
static void make_lsa_dom_chal(DOM_CRED *cred, DOM_CHAL *srv_chal, UTIME srv_time)
{
memcpy(cred->challenge.data, srv_chal->data, sizeof(srv_chal->data));
cred->timestamp = srv_time;
}
static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
DOM_CHAL *srv_chal, UTIME srv_time, int status)
DOM_CRED *srv_cred, int status)
{
make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time);
memcpy(&(r_a->srv_cred), srv_cred, sizeof(r_a->srv_cred));
r_a->status = status;
}
static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
DOM_CHAL *srv_cred, UTIME srv_time,
int status)
DOM_CRED *srv_cred, int status)
{
char *start = q;
LSA_R_SRV_PWSET r_s;
/* set up the LSA Server Password Set response */
make_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status);
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);
@ -917,15 +909,14 @@ static void make_lsa_user_info(LSA_USER_INFO *usr,
static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
DOM_CHAL *srv_cred, UTIME srv_time,
LSA_USER_INFO *user_info)
DOM_CRED *srv_cred, LSA_USER_INFO *user_info)
{
char *start = q;
LSA_R_SAM_LOGON r_s;
/* XXXX maybe we want to say 'no', reject the client's credentials */
r_s.buffer_creds = 1; /* yes, we have valid server credentials */
make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
/* store the user information, if there is any. */
r_s.user = user_info;
@ -941,7 +932,7 @@ static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
DOM_CHAL *srv_cred, UTIME srv_time,
DOM_CRED *srv_cred,
uint32 status)
{
char *start = q;
@ -949,7 +940,7 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
/* XXXX maybe we want to say 'no', reject the client's credentials */
r_s.buffer_creds = 1; /* yes, we have valid server credentials */
make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
r_s.status = status;
@ -1284,6 +1275,34 @@ static void api_lsa_auth_2( user_struct *vuser,
}
static BOOL deal_with_credentials(user_struct *vuser,
DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
{
UTIME new_clnt_time;
/* doesn't matter that server time is 0 */
srv_cred->timestamp.time = 0;
/* check that the client credentials are valid */
if (cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key,
&(vuser->dc.srv_cred), clnt_cred->timestamp))
{
return False;
}
/* increment client time by one second */
new_clnt_time.time = clnt_cred->timestamp.time + 1;
/* create server credentials for inclusion in the reply */
cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time,
&(srv_cred->challenge));
/* update the client and server credentials, for use next time... */
*(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
return True;
}
static void api_lsa_srv_pwset( user_struct *vuser,
char *param, char *data,
char **rdata, int *rdata_len )
@ -1291,29 +1310,17 @@ static void api_lsa_srv_pwset( user_struct *vuser,
int reply_len;
LSA_Q_SRV_PWSET q_a;
DOM_CHAL srv_chal;
UTIME srv_time;
UTIME new_clnt_time;
DOM_CRED srv_cred;
srv_time.time = 0;
/* grab the challenge... */
/* grab the challenge and encrypted password ... */
lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data + 0x18, 4);
/* check that the client credentials are valid */
cred_assert(&(q_a.clnt_id.cred.challenge), vuser->dc.sess_key,
&(vuser->dc.srv_cred), srv_time);
new_clnt_time.time = q_a.clnt_id.cred.timestamp.time + 1;
/* create server credentials for inclusion in the reply */
cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, &srv_chal);
*(uint32*)(vuser->dc.srv_cred.data) = ( *(uint32*)(vuser->dc.clnt_cred.data) += new_clnt_time.time );
/* checks and updates credentials. creates reply credentials */
deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
/* construct reply. always indicate failure. nt keeps going... */
reply_len = lsa_reply_srv_pwset(&q_a, *rdata + 0x18, *rdata + 0x18,
&srv_chal, srv_time,
&srv_cred,
NT_STATUS_WRONG_PASSWORD|0xC000000);
/* construct header, now that we know the reply length */
@ -1322,111 +1329,133 @@ static void api_lsa_srv_pwset( user_struct *vuser,
*rdata_len = reply_len;
}
#if 0
case LSASRVPWSET:
DEBUG(1,("LSASRVPWSET\n"));
q = data + 0x18;
dump_data(1,q,128);
logonsrv = q + 16;
q = skip_unicode_string(logonsrv,1)+12;
q = align4(q, data);
accountname = q;
q = skip_unicode_string(accountname,1);
secchanneltype = qSVAL;
q += 12;
q = align4(q, data);
unicomp = q;
q = skip_unicode_string(unicomp,1);
rcvcred[0] = qIVAL;
rcvcred[1] = qIVAL;
clnttime = qIVAL;
DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s\n",
unistr(logonsrv), unistr(accountname), unistr(unicomp)));
checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
DEBUG(3,("PWSET %lx %lx %lx %lx\n", rcvcred[0], rcvcred[1], clnttime, negflags));
newpass = q;
DEBUG(1,("PWSET logonsrv=%s accountname=%s unicomp=%s newpass=%s\n",
unistr(logonsrv), unistr(accountname), unistr(unicomp), newpass));
/* PAXX: For the moment we'll reject these */
/* TODO Need to set newpass in smbpasswd file for accountname */
q = *rdata + 0x18;
makecred(cnum, clnttime+1, q);
q += 8;
qSIVAL(0); /* timestamp. Seems to be ignored */
dcauth[cnum].svrcred[0] = dcauth[cnum].cred[0] = dcauth[cnum].cred[0] + clnttime + 1;
endrpcreply(data, *rdata, q-*rdata, 0xc000006a, rdata_len);
break;
#endif
BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
static void api_lsa_sam_logoff( user_struct *vuser,
char *param, char *data,
char **rdata, int *rdata_len )
{
uint16 opnum = SVAL(data,22);
int pkttype = CVAL(data, 2);
int reply_len;
LSA_Q_SAM_LOGOFF q_l;
user_struct *vuser = get_valid_user_struct(uid);
DOM_CRED srv_cred;
if (pkttype == 0x0b) /* RPC BIND */
/* grab the challenge... */
lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data + 0x18, 4);
/* checks and updates credentials. creates reply credentials */
deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
/* construct reply. always indicate success */
reply_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata + 0x18,
&srv_cred,
0x0);
/* construct header, now that we know the reply length */
reply_len += make_rpc_reply(data, *rdata, reply_len);
*rdata_len = reply_len;
}
static void api_lsa_sam_logon( user_struct *vuser,
char *param, char *data,
char **rdata, int *rdata_len )
{
int reply_len;
LSA_Q_SAM_LOGON q_l;
LSA_USER_INFO usr_info;
LSA_USER_INFO *p_usr_info = NULL;
DOM_CRED srv_creds;
lsa_io_q_sam_logon(True, &q_l, data + 0x18, data + 0x18, 4);
/* checks and updates credentials. creates reply credentials */
deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
if (vuser != NULL)
{
DEBUG(4,("netlogon rpc bind %x\n",pkttype));
LsarpcTNP1(data,rdata,rdata_len);
return True;
}
NTTIME dummy_time;
pstring logon_script;
pstring profile_path;
pstring home_dir;
pstring home_drive;
pstring my_name;
pstring my_workgroup;
pstring dom_sid;
pstring username;
extern pstring myname;
DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum));
dummy_time.low = 0xffffffff;
dummy_time.high = 0x7fffffff;
if (vuser == NULL) return False;
get_myname(myname, NULL);
DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
#if defined(NETGROUP) && defined(AUTOMOUNT)
DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
pstrcpy(logon_script, lp_logon_script());
pstrcpy(profile_path, lp_logon_path ());
pstrcpy(dom_sid , lp_domainsid ());
pstrcpy(my_workgroup, lp_workgroup ());
pstrcpy(username, unistr2(q_l.sam_id.client.login.uni_acct_name.buffer));
pstrcpy(my_name , myname );
strupper(my_name);
pstrcpy(home_drive , "a:" );
#if (defined(NETGROUP) && defined(AUTOMOUNT))
pstrcpy(home_dir , vuser->home_share);
#else
pstrcpy(home_dir , "\\\\%L\\%U");
standard_sub_basic(home_dir);
#endif
switch (opnum)
{
case LSA_REQCHAL:
{
DEBUG(3,("LSA_REQCHAL\n"));
api_lsa_req_chal(vuser, param, data, rdata, rdata_len);
break;
}
p_usr_info = &usr_info;
case LSA_AUTH2:
{
DEBUG(3,("LSA_AUTH2\n"));
api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
break;
}
make_lsa_user_info(p_usr_info,
case LSA_SRVPWSET:
{
DEBUG(3,("LSA_SRVPWSET\n"));
api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
break;
}
&dummy_time, /* logon_time */
&dummy_time, /* logoff_time */
&dummy_time, /* kickoff_time */
&dummy_time, /* pass_last_set_time */
&dummy_time, /* pass_can_change_time */
&dummy_time, /* pass_must_change_time */
default:
{
DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
break;
}
username, /* user_name */
vuser->real_name, /* full_name */
logon_script, /* logon_script */
profile_path, /* profile_path */
home_dir, /* home_dir */
home_drive, /* dir_drive */
0, /* logon_count */
0, /* bad_pw_count */
vuser->uid, /* uint32 user_id */
vuser->gid, /* uint32 group_id */
0, /* uint32 num_groups */
NULL, /* DOM_GID *gids */
0x20, /* uint32 user_flgs */
NULL, /* char sess_key[16] */
my_name, /* char *logon_srv */
my_workgroup, /* char *logon_dom */
dom_sid, /* char *dom_sid */
NULL); /* char *other_sids */
}
return True;
reply_len = lsa_reply_sam_logon(&q_l, *rdata + 0x18, *rdata + 0x18,
&srv_creds, p_usr_info);
/* construct header, now that we know the reply length */
reply_len += make_rpc_reply(data, *rdata, reply_len);
*rdata_len = reply_len;
}
#if 0
case LSASAMLOGON:
DEBUG(1,("LSASAMLOGON\n"));
dump_data(1,data,128);
@ -1616,62 +1645,79 @@ DEBUG(4,("netlogon LINE %d %lx %s ia %d\n",__LINE__, q, p, identauth));
endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
break;
#endif
case LSASAMLOGOFF:
DEBUG(1,("LSASAMLOGOFF\n"));
q = data + 0x18;
logonsrv = q + 16;
DEBUG(1,("SAMLOGOFF %d\n", __LINE__));
unicomp = skip_unicode_string(logonsrv,1)+16;
if (strlen(unistr(logonsrv)) % 2 == 0)
q += 2;
DEBUG(1,("SMLOG %d\n", __LINE__));
q = skip_unicode_string(unicomp,1)+4;
if (strlen(unistr(unicomp)) % 2 == 0)
q += 2;
DEBUG(1,("SMLOG %d\n", __LINE__));
rcvcred[0] = qIVAL;
DEBUG(1,("SMLOG %d\n", __LINE__));
rcvcred[1] = qIVAL;
DEBUG(1,("SMLOG %d\n", __LINE__));
clnttime = qIVAL;
checkcred(cnum, rcvcred[0], rcvcred[1], clnttime);
q += 4;
rtncred[0] = qIVAL; /* all these are ignored */
DEBUG(1,("SMLOG %d\n", __LINE__));
rtncred[1] = qIVAL;
rtntime = qIVAL;
logonlevel = qSVAL;
DEBUG(1,("SMLOG %d\n", __LINE__));
switchval = qSVAL;
switch (switchval)
{
case 1:
q += 4;
domlen = qSVAL;
dommaxlen = qSVAL; q += 4;
paramcontrol = qIVAL;
logonid[0] = qIVAL; /* low part */
logonid[1] = qIVAL; /* high part */
usernamelen = qSVAL;
DEBUG(1,("SMLOG %d\n", __LINE__));
usernamemaxlen = qSVAL; q += 4;
wslen = qSVAL;
wsmaxlen = qSVAL; q += 4;
rc4lmowfpass = q; q += 16;
rc4ntowfpass = q; q += 16;
q += 12; domain = q; q += dommaxlen + 12;
if ((domlen/2) % 2 != 0) q += 2;
username = q; q += usernamemaxlen + 12; /* PAXX: HACK */
if ((usernamelen/2) % 2 != 0) q += 2;
ws = q;
break;
default: DEBUG(0, ("unknown switch in SAMLOGON %d\n",switchval));
}
DEBUG(1,("SAMLOGOFF %s\n", unistr(username)));
default:
DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
int mdrcnt,int mprcnt,
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
uint16 opnum = SVAL(data,22);
int pkttype = CVAL(data, 2);
#endif /* 0 */
user_struct *vuser = get_valid_user_struct(uid);
if (pkttype == 0x0b) /* RPC BIND */
{
DEBUG(4,("netlogon rpc bind %x\n",pkttype));
LsarpcTNP1(data,rdata,rdata_len);
return True;
}
DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum));
if (vuser == NULL) return False;
DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
#if defined(NETGROUP) && defined(AUTOMOUNT)
DEBUG(3,("HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
#endif
switch (opnum)
{
case LSA_REQCHAL:
{
DEBUG(3,("LSA_REQCHAL\n"));
api_lsa_req_chal(vuser, param, data, rdata, rdata_len);
break;
}
case LSA_AUTH2:
{
DEBUG(3,("LSA_AUTH2\n"));
api_lsa_auth_2(vuser, param, data, rdata, rdata_len);
break;
}
case LSA_SRVPWSET:
{
DEBUG(3,("LSA_SRVPWSET\n"));
api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len);
break;
}
case LSA_SAMLOGON:
{
DEBUG(3,("LSA_SAMLOGON\n"));
api_lsa_sam_logon(vuser, param, data, rdata, rdata_len);
break;
}
case LSA_SAMLOGOFF:
{
DEBUG(3,("LSA_SAMLOGOFF\n"));
api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len);
break;
}
default:
{
DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum));
break;
}
}
return True;
}
#endif /* NTDOMAIN */