mirror of
https://github.com/samba-team/samba.git
synced 2025-12-23 00:23:53 +03:00
Makefile :
adding bits for new nt domain code
byteorder.h :
trying to get macros right, and not to crash on SUNOS5...
client.c :
added #ifdef NTDOMAIN, and created do_nt_login() function. don't
want to have to recompile client.c unless absolutely necessary.
credentials.c :
moved deal_with_creds() [possibly inappropriately] into credentials.c
ipc.c reply.c server.c uid.c :
attempting to make (un)become_root() functions calleable from smbclient.
this is a little tricky: smbclient might have to be another setuid
root program, immediately setuid'ing to non-root, so that we can
reset-uid to root to get at the smbpasswd file. or, have a secure
pipe mechanism to smbd to grab smbpasswd entries. or the like.
smbdes.c smbencrypt.c :
created a function to generate lm and nt owf hashes.
lsaparse.c ntclient.c smbparse.c :
added nt client LSA_AUTH2 code. it works, too!
pipenetlog.c pipentlsa.c pipesrvsvc.c :
simplification. code-shuffling. getting that damn offset right
for the opcode in RPC_HDR.
smb.h :
changed dcinfo xxx_creds to DOM_CRED structures instead of DOM_CHAL.
we might need to store the server times as well.
proto.h :
the usual.
(This used to be commit 82436a3d99)
This commit is contained in:
@@ -3886,6 +3886,8 @@ static void usage(char *pname)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#ifdef NTDOMAIN
|
||||
|
||||
if (nt_domain_logon)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -3897,25 +3899,17 @@ static void usage(char *pname)
|
||||
|
||||
if (cli_open_sockets(port))
|
||||
{
|
||||
DOM_CHAL srv_chal;
|
||||
|
||||
if (!cli_send_login(NULL,NULL,True,True)) return(1);
|
||||
|
||||
if (!cli_lsa_req_chal(&srv_chal, desthost, myhostname, Client, cnum))
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
#if 0
|
||||
cli_lsa_auth2();
|
||||
cli_lsa_sam_logon();
|
||||
cli_lsa_sam_logoff();
|
||||
#endif
|
||||
do_nt_login(desthost, myhostname, Client, cnum);
|
||||
|
||||
cli_send_logout();
|
||||
close_sockets();
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cli_open_sockets(port))
|
||||
{
|
||||
|
||||
@@ -29,11 +29,65 @@ extern int DEBUGLEVEL;
|
||||
|
||||
#define CLIENT_TIMEOUT (30*1000)
|
||||
|
||||
#ifdef NTDOMAIN
|
||||
|
||||
/****************************************************************************
|
||||
open an rpc pipe (\NETLOGON or \srvsvc for example)
|
||||
****************************************************************************/
|
||||
static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname, int Client, int cnum)
|
||||
{
|
||||
int fnum;
|
||||
char *p;
|
||||
|
||||
DEBUG(5,("open_rpc_pipe: %s\n", rname));
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,15,1 + strlen(rname),True);
|
||||
|
||||
CVAL(outbuf,smb_com) = SMBopenX;
|
||||
SSVAL(outbuf,smb_tid, cnum);
|
||||
cli_setup_pkt(outbuf);
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,0xFF);
|
||||
SSVAL(outbuf,smb_vwv2,1);
|
||||
SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
|
||||
SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
|
||||
SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
|
||||
SSVAL(outbuf,smb_vwv8,1);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
strcpy(p,rname);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT);
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0)
|
||||
{
|
||||
if (CVAL(inbuf,smb_rcls) == ERRSRV &&
|
||||
SVAL(inbuf,smb_err) == ERRnoresource &&
|
||||
cli_reopen_connection(inbuf,outbuf))
|
||||
{
|
||||
return open_rpc_pipe(inbuf, outbuf, rname, Client, cnum);
|
||||
}
|
||||
DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf)));
|
||||
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
fnum = SVAL(inbuf, smb_vwv2);
|
||||
|
||||
DEBUG(5,("opening pipe: fnum %d\n", fnum));
|
||||
|
||||
return fnum;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
do a LSA Request Challenge
|
||||
****************************************************************************/
|
||||
static BOOL do_lsa_req_chal(uint16 fnum,
|
||||
char *desthost, char *myhostname, DOM_CHAL *srv_chal)
|
||||
char *desthost, char *myhostname,
|
||||
DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
|
||||
{
|
||||
char *rparam = NULL;
|
||||
char *rdata = NULL;
|
||||
@@ -42,22 +96,18 @@ static BOOL do_lsa_req_chal(uint16 fnum,
|
||||
pstring data; /* only 1024 bytes */
|
||||
uint16 setup[2]; /* only need 2 uint16 setup parameters */
|
||||
LSA_Q_REQ_CHAL q_c;
|
||||
DOM_CHAL clnt_chal;
|
||||
int call_id = 0x1;
|
||||
BOOL valid_chal = False;
|
||||
|
||||
if (srv_chal == NULL) return False;
|
||||
if (srv_chal == NULL || clnt_chal == NULL) return False;
|
||||
|
||||
/* create and send a MSRPC command with api LSA_REQCHAL */
|
||||
|
||||
clnt_chal.data[0] = 0x11111111;
|
||||
clnt_chal.data[1] = 0x22222222;
|
||||
|
||||
DEBUG(4,("LSA Request Challenge from %s to %s: %lx %lx\n",
|
||||
desthost, myhostname, clnt_chal.data[0], clnt_chal.data[1]));
|
||||
desthost, myhostname, clnt_chal->data[0], clnt_chal->data[1]));
|
||||
|
||||
/* store the parameters */
|
||||
make_q_req_chal(&q_c, desthost, myhostname, &clnt_chal);
|
||||
make_q_req_chal(&q_c, desthost, myhostname, clnt_chal);
|
||||
|
||||
|
||||
/* turn parameters into data stream */
|
||||
@@ -133,66 +183,137 @@ static BOOL do_lsa_req_chal(uint16 fnum,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
open an rpc pipe (\NETLOGON or \srvsvc for example)
|
||||
****************************************************************************/
|
||||
static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname, int Client, int cnum)
|
||||
do a LSA Authenticate 2
|
||||
****************************************************************************/
|
||||
static BOOL do_lsa_auth2(uint16 fnum,
|
||||
char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
|
||||
DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
|
||||
{
|
||||
int fnum;
|
||||
char *rparam = NULL;
|
||||
char *rdata = NULL;
|
||||
char *p;
|
||||
int rdrcnt,rprcnt;
|
||||
pstring data; /* only 1024 bytes */
|
||||
uint16 setup[2]; /* only need 2 uint16 setup parameters */
|
||||
LSA_Q_AUTH_2 q_a;
|
||||
int call_id = 0x1;
|
||||
BOOL valid_chal = False;
|
||||
|
||||
DEBUG(5,("open_rpc_pipe: %s\n", rname));
|
||||
if (srv_chal == NULL || clnt_chal == NULL) return False;
|
||||
|
||||
bzero(outbuf,smb_size);
|
||||
set_message(outbuf,15,1 + strlen(rname),True);
|
||||
/* create and send a MSRPC command with api LSA_AUTH2 */
|
||||
|
||||
CVAL(outbuf,smb_com) = SMBopenX;
|
||||
SSVAL(outbuf,smb_tid, cnum);
|
||||
cli_setup_pkt(outbuf);
|
||||
DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %lx %lx neg: %lx\n",
|
||||
logon_srv, acct_name, sec_chan, comp_name,
|
||||
clnt_chal->data[0], clnt_chal->data[1], neg_flags));
|
||||
|
||||
SSVAL(outbuf,smb_vwv0,0xFF);
|
||||
SSVAL(outbuf,smb_vwv2,1);
|
||||
SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
|
||||
SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
|
||||
SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
|
||||
SSVAL(outbuf,smb_vwv8,1);
|
||||
/* store the parameters */
|
||||
make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
|
||||
clnt_chal, neg_flags);
|
||||
|
||||
p = smb_buf(outbuf);
|
||||
strcpy(p,rname);
|
||||
p = skip_string(p,1);
|
||||
/* turn parameters into data stream */
|
||||
p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0);
|
||||
|
||||
send_smb(Client,outbuf);
|
||||
receive_smb(Client,inbuf,CLIENT_TIMEOUT);
|
||||
/* create the request RPC_HDR _after_ the main data: length is now known */
|
||||
create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data));
|
||||
|
||||
if (CVAL(inbuf,smb_rcls) != 0)
|
||||
/* create setup parameters. */
|
||||
SIVAL(setup, 0, 0x0026); /* 0x26 indicates "transact named pipe" */
|
||||
SIVAL(setup, 2, fnum); /* file handle, from the SMBcreateX pipe, earlier */
|
||||
|
||||
/* send the data on \PIPE\ */
|
||||
if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
|
||||
BUFFER_SIZE,
|
||||
&rprcnt,&rdrcnt,
|
||||
NULL, data, setup,
|
||||
&rparam,&rdata))
|
||||
{
|
||||
if (CVAL(inbuf,smb_rcls) == ERRSRV &&
|
||||
SVAL(inbuf,smb_err) == ERRnoresource &&
|
||||
cli_reopen_connection(inbuf,outbuf))
|
||||
{
|
||||
return open_rpc_pipe(inbuf, outbuf, rname, Client, cnum);
|
||||
}
|
||||
DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf)));
|
||||
LSA_R_AUTH_2 r_a;
|
||||
RPC_HDR hdr;
|
||||
int hdr_len;
|
||||
int pkt_len;
|
||||
|
||||
return 0xffff;
|
||||
DEBUG(5, ("cli_call_api: return OK\n"));
|
||||
|
||||
p = rdata;
|
||||
|
||||
if (p) p = smb_io_rpc_hdr (True, &hdr, p, rdata, 4, 0);
|
||||
if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
|
||||
|
||||
hdr_len = PTR_DIFF(p, rdata);
|
||||
|
||||
if (p && hdr_len != hdr.frag_len - hdr.alloc_hint)
|
||||
{
|
||||
/* header length not same as calculated header length */
|
||||
DEBUG(2,("do_lsa_auth2: hdr_len %x != frag_len-alloc_hint\n",
|
||||
hdr_len, hdr.frag_len - hdr.alloc_hint));
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
fnum = SVAL(inbuf, smb_vwv2);
|
||||
if (p) p = lsa_io_r_auth_2(True, &r_a, p, rdata, 4, 0);
|
||||
|
||||
DEBUG(5,("opening pipe: fnum %d\n", fnum));
|
||||
pkt_len = PTR_DIFF(p, rdata);
|
||||
|
||||
return fnum;
|
||||
if (p && pkt_len != hdr.frag_len)
|
||||
{
|
||||
/* packet data size not same as reported fragment length */
|
||||
DEBUG(2,("do_lsa_auth2: pkt_len %x != frag_len \n",
|
||||
pkt_len, hdr.frag_len));
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p && r_a.status != 0)
|
||||
{
|
||||
/* report error code */
|
||||
DEBUG(0,("LSA_AUTH2: nt_status error %lx\n", r_a.status));
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
|
||||
{
|
||||
/* report different neg_flags */
|
||||
DEBUG(0,("LSA_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n",
|
||||
q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
if (p)
|
||||
{
|
||||
/* ok, at last: we're happy. return the challenge */
|
||||
memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
|
||||
valid_chal = True;
|
||||
}
|
||||
}
|
||||
|
||||
if (rparam) free(rparam);
|
||||
if (rdata) free(rdata);
|
||||
|
||||
return valid_chal;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
experimental nt login.
|
||||
****************************************************************************/
|
||||
BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname,
|
||||
BOOL do_nt_login(char *desthost, char *myhostname,
|
||||
int Client, int cnum)
|
||||
{
|
||||
DOM_CHAL clnt_chal;
|
||||
DOM_CHAL srv_chal;
|
||||
|
||||
DOM_CHAL auth2_clnt_chal;
|
||||
DOM_CHAL auth2_srv_chal;
|
||||
|
||||
UTIME zerotime;
|
||||
|
||||
uint32 sess_key[2];
|
||||
char nt_owf_mach_pwd[16];
|
||||
fstring mach_acct;
|
||||
fstring mach_pwd;
|
||||
|
||||
uint16 fnum;
|
||||
char *inbuf,*outbuf;
|
||||
|
||||
if (srv_chal == NULL) return False;
|
||||
zerotime.time = 0;
|
||||
|
||||
inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
|
||||
outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
|
||||
@@ -204,19 +325,72 @@ BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname,
|
||||
}
|
||||
|
||||
/* open the \PIPE\NETLOGON file */
|
||||
fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum);
|
||||
|
||||
if (fnum != 0xffff)
|
||||
if ((fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum)) == 0xffff)
|
||||
{
|
||||
do_lsa_req_chal(fnum, desthost, myhostname, srv_chal);
|
||||
|
||||
/* close \PIPE\NETLOGON */
|
||||
cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
|
||||
|
||||
free(inbuf); free(outbuf);
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
fstrcpy(mach_acct, myhostname);
|
||||
strlower(mach_pwd);
|
||||
|
||||
fstrcpy(mach_pwd , myhostname);
|
||||
strcat(mach_acct, "$");
|
||||
|
||||
clnt_chal.data[0] = 0x11111111;
|
||||
clnt_chal.data[1] = 0x22222222;
|
||||
|
||||
/* send a client challenge; receive a server challenge */
|
||||
if (!do_lsa_req_chal(fnum, desthost, myhostname, &clnt_chal, &srv_chal))
|
||||
{
|
||||
cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
|
||||
free(inbuf); free(outbuf);
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* DAMN! can't get the machine password - need become_root() to do it! */
|
||||
/* get the machine password */
|
||||
if (!get_md4pw(mach_acct, nt_owf_mach_pwd))
|
||||
{
|
||||
cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
|
||||
free(inbuf); free(outbuf);
|
||||
return False;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
char lm_owf_mach_pwd[16];
|
||||
nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd);
|
||||
DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
|
||||
dump_data(6, nt_owf_mach_pwd, 16);
|
||||
}
|
||||
|
||||
/* calculate the session key */
|
||||
cred_session_key(&clnt_chal, &srv_chal, nt_owf_mach_pwd, sess_key);
|
||||
|
||||
/* calculate auth-2 credentials */
|
||||
cred_create(sess_key, &clnt_chal, zerotime, &auth2_clnt_chal);
|
||||
|
||||
/* send client auth-2 challenge; receive an auth-2 challenge */
|
||||
if (!do_lsa_auth2(fnum, desthost, mach_acct, 2, myhostname,
|
||||
&auth2_clnt_chal, 0x000001ff, &auth2_srv_chal))
|
||||
{
|
||||
cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
|
||||
free(inbuf); free(outbuf);
|
||||
return False;
|
||||
}
|
||||
|
||||
#if 0
|
||||
cli_lsa_sam_logon();
|
||||
cli_lsa_sam_logoff();
|
||||
#endif
|
||||
|
||||
cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
|
||||
free(inbuf); free(outbuf);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -226,15 +226,15 @@ it also defines lots of intermediate macros, just ignore those :-)
|
||||
#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, *((uint8*)(inbuf))));
|
||||
tab_depth(depth), PTR_DIFF(inbuf,base),string, CVAL(inbuf, 0)));
|
||||
|
||||
#define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \
|
||||
RW_SVAL(read,inbuf,outbuf,0) \
|
||||
DEBUG(5,("%s%04x %s: %04x\n", \
|
||||
tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint16*)(inbuf))));
|
||||
tab_depth(depth), PTR_DIFF(inbuf,base),string, SVAL(inbuf, 0)));
|
||||
|
||||
#define DBG_RW_IVAL(string,depth,base,read,inbuf,outbuf) \
|
||||
RW_IVAL(read,inbuf,outbuf,0) \
|
||||
DEBUG(5,("%s%04x %s: %08x\n", \
|
||||
tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint32*)(inbuf))));
|
||||
tab_depth(depth), PTR_DIFF(inbuf,base),string, IVAL(inbuf, 0)));
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp,
|
||||
DOM_CHAL *cred);
|
||||
int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred,
|
||||
UTIME timestamp);
|
||||
BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred);
|
||||
BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred);
|
||||
|
||||
/*The following definitions come from dir.c */
|
||||
|
||||
@@ -378,6 +380,9 @@ void make_q_req_chal(LSA_Q_REQ_CHAL *q_c,
|
||||
DOM_CHAL *clnt_chal);
|
||||
char* lsa_io_q_req_chal(BOOL io, LSA_Q_REQ_CHAL *q_c, char *q, char *base, int align, int depth);
|
||||
char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int align, int depth);
|
||||
void make_q_auth_2(LSA_Q_AUTH_2 *q_a,
|
||||
char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
|
||||
DOM_CHAL *clnt_chal, uint32 clnt_flgs);
|
||||
char* lsa_io_q_auth_2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align, int depth);
|
||||
char* lsa_io_r_auth_2(BOOL io, LSA_R_AUTH_2 *r_a, char *q, char *base, int align, int depth);
|
||||
char* lsa_io_q_srv_pwset(BOOL io, LSA_Q_SRV_PWSET *q_s, char *q, char *base, int align, int depth);
|
||||
@@ -633,7 +638,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
|
||||
|
||||
/*The following definitions come from ntclient.c */
|
||||
|
||||
BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname,
|
||||
BOOL do_nt_login(char *desthost, char *myhostname,
|
||||
int Client, int cnum);
|
||||
|
||||
/*The following definitions come from params.c */
|
||||
@@ -673,6 +678,7 @@ void pcap_printer_fn(void (*fn)());
|
||||
|
||||
/*The following definitions come from pipenetlog.c */
|
||||
|
||||
BOOL get_md4pw(char *md4pw, char *mach_acct);
|
||||
BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
|
||||
int mdrcnt,int mprcnt,
|
||||
char **rdata,char **rparam,
|
||||
@@ -884,6 +890,7 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
|
||||
void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
|
||||
void E_md4hash(uchar *passwd, uchar *p16);
|
||||
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
|
||||
void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]);
|
||||
|
||||
/*The following definitions come from smbparse.c */
|
||||
|
||||
@@ -904,6 +911,8 @@ char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align, i
|
||||
void make_dom_rid2(DOM_RID2 *rid2, uint32 rid);
|
||||
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);
|
||||
void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
|
||||
uint16 sec_chan, char *comp_name);
|
||||
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);
|
||||
@@ -1015,7 +1024,7 @@ char *ufc_crypt(char *key,char *salt);
|
||||
|
||||
void init_uid(void);
|
||||
BOOL become_guest(void);
|
||||
BOOL become_user(int cnum, uint16 vuid);
|
||||
BOOL become_user(connection_struct *conn, int cnum, uint16 vuid);
|
||||
BOOL unbecome_user(void );
|
||||
int smbrun(char *cmd,char *outfile,BOOL shared);
|
||||
void become_root(BOOL save_dir) ;
|
||||
|
||||
@@ -550,7 +550,7 @@ typedef struct rpc_hdr_info
|
||||
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
|
||||
uint16 context_id; /* 0 - presentation context identifier */
|
||||
uint8 cancel_count; /* 0 - cancel count */
|
||||
uint8 reserved; /* 0 - reserved */
|
||||
uint8 opnum; /* request: 0 - reserved. response: opnum */
|
||||
|
||||
} RPC_HDR;
|
||||
|
||||
@@ -1185,8 +1185,8 @@ struct dcinfo
|
||||
{
|
||||
DOM_CHAL clnt_chal; /* Initial challenge received from client */
|
||||
DOM_CHAL srv_chal; /* Initial server challenge */
|
||||
DOM_CHAL clnt_cred; /* Last client credential */
|
||||
DOM_CHAL srv_cred; /* Last server credential */
|
||||
DOM_CRED clnt_cred; /* Last client credential */
|
||||
DOM_CRED srv_cred; /* Last server credential */
|
||||
|
||||
uint32 sess_key[2]; /* Session key */
|
||||
uchar md4pw[16]; /* md4(machine password) */
|
||||
|
||||
@@ -135,3 +135,110 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
checks credentials; generates next step in the credential chain
|
||||
****************************************************************************/
|
||||
BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred)
|
||||
{
|
||||
UTIME new_clnt_time;
|
||||
uint32 new_cred;
|
||||
|
||||
DEBUG(5,("deal_with_creds: %d\n", __LINE__));
|
||||
|
||||
/* check that the client credentials are valid */
|
||||
if (!cred_assert(&(clnt_cred->challenge), dc->sess_key,
|
||||
&(dc->clnt_cred.challenge), clnt_cred->timestamp))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
/* increment client time by one second */
|
||||
new_clnt_time.time = clnt_cred->timestamp.time + 1;
|
||||
|
||||
/* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
|
||||
new_cred = IVAL(dc->clnt_cred.challenge.data, 0);
|
||||
new_cred += new_clnt_time.time;
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred));
|
||||
|
||||
/* doesn't matter that server time is 0 */
|
||||
srv_cred->timestamp.time = 0;
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time));
|
||||
|
||||
/* create return credentials for inclusion in the reply */
|
||||
cred_create(dc->sess_key, &(dc->clnt_cred.challenge), new_clnt_time,
|
||||
&(srv_cred->challenge));
|
||||
|
||||
DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n",
|
||||
dc->clnt_cred.challenge.data[0]));
|
||||
|
||||
/* store new seed in client and server credentials */
|
||||
SIVAL(dc->clnt_cred.challenge.data, 0, new_cred);
|
||||
SIVAL(dc->srv_cred .challenge.data, 0, new_cred);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/****************************************************************************
|
||||
checks credentials; generates next step in the credential chain
|
||||
****************************************************************************/
|
||||
BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred)
|
||||
{
|
||||
UTIME new_clnt_time;
|
||||
uint32 new_cred;
|
||||
|
||||
DEBUG(5,("deal_with_creds: %d\n", __LINE__));
|
||||
|
||||
/* setup new client time */
|
||||
dc->clnt_cred.timestamp.time = time(NULL);
|
||||
|
||||
/* create sent credentials for inclusion in the reply */
|
||||
cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred);
|
||||
|
||||
/* increment client time by one second */
|
||||
(dc->clnt_cred.timestamp.time)++;
|
||||
|
||||
/* create expected return credentials to be received from server */
|
||||
cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred);
|
||||
|
||||
|
||||
|
||||
/* check that the server credentials are valid */
|
||||
if (!cred_assert(&(srv_cred->challenge), dc->sess_key,
|
||||
&(dc->clnt_cred), clnt_cred->timestamp))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
/* increment client time by one second */
|
||||
new_clnt_time = (dc->clnt_cred.timestamp.time += 1);
|
||||
|
||||
/* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
|
||||
new_cred = IVAL(dc->clnt_cred.data, 0);
|
||||
new_cred += new_clnt_time.time;
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred));
|
||||
|
||||
/* create new client credentials */
|
||||
cred_create(dc->sess_key, new_cred, new_clnt_time, clnt_cred);
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time));
|
||||
|
||||
/* create return credentials for inclusion in the reply
|
||||
cred_create(dc->sess_key, srv_cred, new_clnt_time,
|
||||
clnt_cred);
|
||||
*/
|
||||
DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n",
|
||||
dc->clnt_cred.data[0]));
|
||||
|
||||
/* store new seed in client and server credentials */
|
||||
SIVAL(dc->clnt_cred.data, 0, new_cred);
|
||||
SIVAL(dc->srv_cred .data, 0, new_cred);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -329,6 +329,11 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
|
||||
{
|
||||
unsigned char buf[8];
|
||||
static unsigned char key2[8];
|
||||
int i;
|
||||
|
||||
for (i=0;i<8;i++) {
|
||||
key2[i] = 0;
|
||||
}
|
||||
|
||||
smbhash(buf, in, key);
|
||||
key2[0] = key[7];
|
||||
|
||||
@@ -109,3 +109,27 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
|
||||
E_P24(p21, c8, p24);
|
||||
}
|
||||
|
||||
/* Does both the NT and LM owfs of a user's password */
|
||||
|
||||
void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16])
|
||||
{
|
||||
char passwd[129];
|
||||
strncpy(passwd, pwd, 129);
|
||||
|
||||
/* Calculate the MD4 hash (NT compatible) of the password */
|
||||
memset(nt_p16, '\0', 16);
|
||||
E_md4hash((uchar *)passwd, nt_p16);
|
||||
|
||||
/* Mangle the passwords into Lanman format */
|
||||
passwd[14] = '\0';
|
||||
strupper(passwd);
|
||||
|
||||
/* Calculate the SMB (lanman) hash functions of the password */
|
||||
|
||||
memset(p16, '\0', 16);
|
||||
E_P16((uchar *) passwd, p16);
|
||||
|
||||
/* clear out local copy of user's password (just being paranoid). */
|
||||
bzero(passwd, sizeof(passwd));
|
||||
}
|
||||
|
||||
|
||||
@@ -295,6 +295,24 @@ char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int a
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
void make_q_auth_2(LSA_Q_AUTH_2 *q_a,
|
||||
char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
|
||||
DOM_CHAL *clnt_chal, uint32 clnt_flgs)
|
||||
{
|
||||
if (q_a == NULL) return;
|
||||
|
||||
DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
|
||||
|
||||
make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
|
||||
memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
|
||||
q_a->clnt_flgs.neg_flags = clnt_flgs;
|
||||
|
||||
DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a structure.
|
||||
********************************************************************/
|
||||
|
||||
@@ -46,14 +46,14 @@ static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c,
|
||||
}
|
||||
|
||||
static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
|
||||
DOM_CHAL *srv_chal)
|
||||
DOM_CHAL *srv_chal, uint32 srv_time)
|
||||
{
|
||||
LSA_R_REQ_CHAL r_c;
|
||||
|
||||
DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__));
|
||||
|
||||
/* set up the LSA REQUEST CHALLENGE response */
|
||||
make_lsa_r_req_chal(&r_c, srv_chal, 0);
|
||||
make_lsa_r_req_chal(&r_c, srv_chal, srv_time);
|
||||
|
||||
/* store the response in the SMB stream */
|
||||
q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0);
|
||||
@@ -284,26 +284,23 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
|
||||
return PTR_DIFF(q, base);
|
||||
}
|
||||
|
||||
|
||||
static BOOL update_dcinfo(int cnum, uint16 vuid,
|
||||
struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct)
|
||||
/****************************************************************************
|
||||
gets a machine password entry
|
||||
****************************************************************************/
|
||||
BOOL get_md4pw(char *md4pw, char *mach_acct)
|
||||
{
|
||||
struct smb_passwd *smb_pass;
|
||||
int i;
|
||||
|
||||
unbecome_user();
|
||||
become_root(True);
|
||||
smb_pass = get_smbpwnam(mach_acct);
|
||||
if (!become_user(cnum, vuid))
|
||||
{
|
||||
DEBUG(0,("update_dcinfo: become_user failed\n"));
|
||||
return False;
|
||||
}
|
||||
unbecome_root(True);
|
||||
|
||||
if (smb_pass != NULL)
|
||||
{
|
||||
memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw));
|
||||
DEBUG(5,("dc->md4pw(%d) :", sizeof(dc->md4pw)));
|
||||
dump_data(5, dc->md4pw, 16);
|
||||
memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
|
||||
dump_data(5, md4pw, 16);
|
||||
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -312,32 +309,6 @@ static BOOL update_dcinfo(int cnum, uint16 vuid,
|
||||
DEBUG(1,("No account in domain for %s\n", mach_acct));
|
||||
return False;
|
||||
}
|
||||
|
||||
{
|
||||
fstring foo;
|
||||
for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]);
|
||||
DEBUG(4,("pass %s %s\n", mach_acct, foo));
|
||||
}
|
||||
|
||||
/* copy the client credentials */
|
||||
memcpy(dc->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
|
||||
memcpy(dc->clnt_cred.data, clnt_chal->data, sizeof(clnt_chal->data));
|
||||
|
||||
/* create a server challenge for the client */
|
||||
/* PAXX: set these to random values. */
|
||||
/* lkcl: paul, you mentioned that it doesn't really matter much */
|
||||
dc->srv_chal.data[0] = 0x11111111;
|
||||
dc->srv_chal.data[1] = 0x11111111;
|
||||
dc->srv_cred.data[0] = 0x11111111;
|
||||
dc->srv_cred.data[1] = 0x11111111;
|
||||
|
||||
/* from client / server challenges and md4 password, generate sess key */
|
||||
cred_session_key(&(dc->clnt_chal), &(dc->srv_chal),
|
||||
dc->md4pw, dc->sess_key);
|
||||
|
||||
DEBUG(6,("update_dcinfo: %d\n", __LINE__));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void api_lsa_req_chal( int cnum, uint16 vuid,
|
||||
@@ -360,11 +331,28 @@ static void api_lsa_req_chal( int cnum, uint16 vuid,
|
||||
DEBUG(6,("q_r.clnt_chal.data: %lx %lx\n",
|
||||
q_r.clnt_chal.data[0], q_r.clnt_chal.data[1]));
|
||||
|
||||
update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct);
|
||||
if (get_md4pw(vuser->dc.md4pw, mach_acct))
|
||||
{
|
||||
/* copy the client credentials */
|
||||
memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
|
||||
memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
|
||||
|
||||
/* create a server challenge for the client */
|
||||
/* PAXX: set these to random values. */
|
||||
/* lkcl: paul, you mentioned that it doesn't really matter much */
|
||||
vuser->dc.srv_chal.data[0] = 0x11111111;
|
||||
vuser->dc.srv_chal.data[1] = 0x11111111;
|
||||
vuser->dc.srv_cred.challenge.data[0] = vuser->dc.srv_chal.data[0];
|
||||
vuser->dc.srv_cred.challenge.data[1] = vuser->dc.srv_chal.data[1];
|
||||
|
||||
/* from client / server challenges and md4 password, generate sess key */
|
||||
cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
|
||||
vuser->dc.md4pw, vuser->dc.sess_key);
|
||||
}
|
||||
|
||||
/* construct reply. return status is always 0x0 */
|
||||
*rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata,
|
||||
&(vuser->dc.srv_chal));
|
||||
&(vuser->dc.srv_chal), 0);
|
||||
|
||||
}
|
||||
|
||||
@@ -384,14 +372,14 @@ static void api_lsa_auth_2( user_struct *vuser,
|
||||
|
||||
/* check that the client credentials are valid */
|
||||
cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
|
||||
&(vuser->dc.clnt_cred), srv_time);
|
||||
&(vuser->dc.clnt_cred.challenge), srv_time);
|
||||
|
||||
/* create server challenge for inclusion in the reply */
|
||||
cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred), srv_time, &srv_cred);
|
||||
cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
|
||||
|
||||
/* copy the received client credentials for use next time */
|
||||
memcpy(vuser->dc.clnt_cred.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
|
||||
memcpy(vuser->dc.srv_cred .data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
|
||||
memcpy(vuser->dc.clnt_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
|
||||
memcpy(vuser->dc.srv_cred .challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
|
||||
|
||||
/* construct reply. */
|
||||
*rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata,
|
||||
@@ -399,49 +387,6 @@ 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;
|
||||
uint32 new_cred;
|
||||
|
||||
DEBUG(5,("deal_with_credentials: %d\n", __LINE__));
|
||||
|
||||
/* increment client time by one second */
|
||||
new_clnt_time.time = clnt_cred->timestamp.time + 1;
|
||||
|
||||
/* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
|
||||
new_cred = IVAL(vuser->dc.clnt_cred.data, 0);
|
||||
new_cred += new_clnt_time.time;
|
||||
|
||||
DEBUG(5,("deal_with_credentials: new_cred[0]=%lx\n", new_cred));
|
||||
|
||||
/* 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.clnt_cred), clnt_cred->timestamp))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
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: clnt_cred[0]=%lx\n",
|
||||
vuser->dc.clnt_cred.data[0]));
|
||||
|
||||
/* store new seed in client and server credentials */
|
||||
SIVAL(vuser->dc.clnt_cred.data, 0, new_cred);
|
||||
SIVAL(vuser->dc.srv_cred .data, 0, new_cred);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static void api_lsa_srv_pwset( user_struct *vuser,
|
||||
char *param, char *data,
|
||||
char **rdata, int *rdata_len )
|
||||
@@ -454,7 +399,7 @@ static void api_lsa_srv_pwset( user_struct *vuser,
|
||||
lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0);
|
||||
|
||||
/* checks and updates credentials. creates reply credentials */
|
||||
deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred);
|
||||
srv_deal_with_creds(&(vuser->dc), &(q_a.clnt_id.cred), &srv_cred);
|
||||
|
||||
DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__));
|
||||
|
||||
@@ -477,7 +422,7 @@ static void api_lsa_sam_logoff( user_struct *vuser,
|
||||
lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0);
|
||||
|
||||
/* checks and updates credentials. creates reply credentials */
|
||||
deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred);
|
||||
srv_deal_with_creds(&(vuser->dc), &(q_l.sam_id.client.cred), &srv_cred);
|
||||
|
||||
/* construct reply. always indicate success */
|
||||
*rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata,
|
||||
@@ -498,7 +443,7 @@ static void api_lsa_sam_logon( user_struct *vuser,
|
||||
lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0);
|
||||
|
||||
/* checks and updates credentials. creates reply credentials */
|
||||
deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds);
|
||||
srv_deal_with_creds(&(vuser->dc), &(q_l.sam_id.client.cred), &srv_creds);
|
||||
|
||||
usr_info.ptr_user_info = 0;
|
||||
|
||||
@@ -645,13 +590,13 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
|
||||
return True;
|
||||
}
|
||||
|
||||
DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.reserved));
|
||||
DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.opnum));
|
||||
|
||||
if ((vuser = get_valid_user_struct(uid)) == NULL) return False;
|
||||
|
||||
DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name));
|
||||
|
||||
switch (hdr.reserved)
|
||||
switch (hdr.opnum)
|
||||
{
|
||||
case LSA_REQCHAL:
|
||||
{
|
||||
@@ -695,7 +640,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
|
||||
|
||||
default:
|
||||
{
|
||||
DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.reserved));
|
||||
DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.opnum));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,9 +317,9 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
|
||||
return True;
|
||||
}
|
||||
|
||||
DEBUG(4,("lsarpc TransactNamedPipe op %x\n",hdr.reserved));
|
||||
DEBUG(4,("lsarpc TransactNamedPipe op %x\n",hdr.opnum));
|
||||
|
||||
switch (hdr.reserved)
|
||||
switch (hdr.opnum)
|
||||
{
|
||||
case LSA_OPENPOLICY:
|
||||
{
|
||||
@@ -416,7 +416,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
|
||||
|
||||
default:
|
||||
{
|
||||
DEBUG(4, ("NTLSARPC, unknown code: %lx\n", hdr.reserved));
|
||||
DEBUG(4, ("NTLSARPC, unknown code: %lx\n", hdr.opnum));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,9 +205,9 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data,
|
||||
return True;
|
||||
}
|
||||
|
||||
DEBUG(4,("srvsvc TransactNamedPipe op %x\n",hdr.reserved));
|
||||
DEBUG(4,("srvsvc TransactNamedPipe op %x\n",hdr.opnum));
|
||||
|
||||
switch (hdr.reserved)
|
||||
switch (hdr.opnum)
|
||||
{
|
||||
case NETSHAREENUM:
|
||||
{
|
||||
@@ -261,7 +261,7 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data,
|
||||
|
||||
default:
|
||||
{
|
||||
DEBUG(4, ("srvsvc, unknown code: %lx\n", hdr.reserved));
|
||||
DEBUG(4, ("srvsvc, unknown code: %lx\n", hdr.opnum));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1606,11 +1606,12 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
|
||||
if (Files[i].open && Files[i].print_file)
|
||||
{
|
||||
pstring wd;
|
||||
int fcnum = Files[i].cnum;
|
||||
GetWd(wd);
|
||||
unbecome_user();
|
||||
|
||||
if (!become_user(Files[i].cnum,vuid) ||
|
||||
!become_service(Files[i].cnum,True))
|
||||
if (!become_user(&Connections[fcnum], fcnum,vuid) ||
|
||||
!become_service(fcnum,True))
|
||||
break;
|
||||
|
||||
if (sys_rename(Files[i].name,name) == 0)
|
||||
|
||||
@@ -2614,7 +2614,7 @@ int reply_printqueue(char *inbuf,char *outbuf)
|
||||
DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum));
|
||||
}
|
||||
|
||||
if (!become_user(cnum,vuid))
|
||||
if (!become_user(&Connections[cnum], cnum, vuid))
|
||||
return(ERROR(ERRSRV,ERRinvnid));
|
||||
|
||||
{
|
||||
|
||||
@@ -94,7 +94,7 @@ BOOL global_oplock_break = False;
|
||||
|
||||
extern fstring remote_machine;
|
||||
|
||||
pstring OriginalDir;
|
||||
extern pstring OriginalDir;
|
||||
|
||||
/* these can be set by some functions to override the error codes */
|
||||
int unix_ERR_class=SUCCESS;
|
||||
@@ -3462,7 +3462,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de
|
||||
smbrun(cmd,NULL,False);
|
||||
}
|
||||
|
||||
if (!become_user(cnum,pcon->vuid))
|
||||
if (!become_user(&Connections[cnum], cnum,pcon->vuid))
|
||||
{
|
||||
DEBUG(0,("Can't become connected user!\n"));
|
||||
pcon->open = False;
|
||||
@@ -4019,7 +4019,7 @@ void close_cnum(int cnum, uint16 vuid)
|
||||
dptr_closecnum(cnum);
|
||||
|
||||
/* execute any "postexec = " line */
|
||||
if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
|
||||
if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid))
|
||||
{
|
||||
pstring cmd;
|
||||
strcpy(cmd,lp_postexec(SNUM(cnum)));
|
||||
@@ -4542,7 +4542,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
|
||||
unbecome_user();
|
||||
|
||||
/* does this protocol need to be run as the connected user? */
|
||||
if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
|
||||
if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) {
|
||||
if (flags & AS_GUEST)
|
||||
flags &= ~AS_USER;
|
||||
else
|
||||
|
||||
@@ -23,15 +23,13 @@
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern connection_struct Connections[];
|
||||
|
||||
static int initial_uid;
|
||||
static int initial_gid;
|
||||
|
||||
/* what user is current? */
|
||||
struct current_user current_user;
|
||||
|
||||
extern pstring OriginalDir;
|
||||
pstring OriginalDir;
|
||||
|
||||
/****************************************************************************
|
||||
initialise the uid routines
|
||||
@@ -183,19 +181,19 @@ BOOL become_guest(void)
|
||||
/*******************************************************************
|
||||
check if a username is OK
|
||||
********************************************************************/
|
||||
static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
|
||||
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<Connections[cnum].uid_cache.entries;i++)
|
||||
if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
|
||||
for (i=0;i<conn->uid_cache.entries;i++)
|
||||
if (conn->uid_cache.list[i] == vuser->uid) return(True);
|
||||
|
||||
if (!user_ok(vuser->name,snum)) return(False);
|
||||
|
||||
i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
|
||||
Connections[cnum].uid_cache.list[i] = vuser->uid;
|
||||
i = conn->uid_cache.entries % UID_CACHE_SIZE;
|
||||
conn->uid_cache.list[i] = vuser->uid;
|
||||
|
||||
if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
|
||||
Connections[cnum].uid_cache.entries++;
|
||||
if (conn->uid_cache.entries < UID_CACHE_SIZE)
|
||||
conn->uid_cache.entries++;
|
||||
|
||||
return(True);
|
||||
}
|
||||
@@ -204,7 +202,7 @@ static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
|
||||
/****************************************************************************
|
||||
become the user of a connection number
|
||||
****************************************************************************/
|
||||
BOOL become_user(int cnum, uint16 vuid)
|
||||
BOOL become_user(connection_struct *conn, int cnum, uint16 vuid)
|
||||
{
|
||||
user_struct *vuser = get_valid_user_struct(vuid);
|
||||
int snum,gid;
|
||||
@@ -217,23 +215,23 @@ BOOL become_user(int cnum, uint16 vuid)
|
||||
|
||||
unbecome_user();
|
||||
|
||||
if (!OPEN_CNUM(cnum)) {
|
||||
if (!(VALID_CNUM(cnum) && conn->open)) {
|
||||
DEBUG(2,("Connection %d not open\n",cnum));
|
||||
return(False);
|
||||
}
|
||||
|
||||
snum = Connections[cnum].service;
|
||||
snum = conn->service;
|
||||
|
||||
if (Connections[cnum].force_user ||
|
||||
if (conn->force_user ||
|
||||
lp_security() == SEC_SHARE ||
|
||||
!(vuser) || (vuser->guest) ||
|
||||
!check_user_ok(cnum,vuser,snum))
|
||||
!check_user_ok(conn, vuser, snum))
|
||||
{
|
||||
uid = Connections[cnum].uid;
|
||||
gid = Connections[cnum].gid;
|
||||
current_user.groups = Connections[cnum].groups;
|
||||
current_user.igroups = Connections[cnum].igroups;
|
||||
current_user.ngroups = Connections[cnum].ngroups;
|
||||
uid = conn->uid;
|
||||
gid = conn->gid;
|
||||
current_user.groups = conn->groups;
|
||||
current_user.igroups = conn->igroups;
|
||||
current_user.ngroups = conn->ngroups;
|
||||
current_user.attrs = vuser->attrs;
|
||||
}
|
||||
else
|
||||
@@ -246,7 +244,7 @@ BOOL become_user(int cnum, uint16 vuid)
|
||||
if(!*lp_force_group(snum))
|
||||
gid = vuser->gid;
|
||||
else
|
||||
gid = Connections[cnum].gid;
|
||||
gid = conn->gid;
|
||||
current_user.ngroups = vuser->n_groups;
|
||||
current_user.groups = vuser->groups;
|
||||
current_user.igroups = vuser->igroups;
|
||||
@@ -258,7 +256,7 @@ BOOL become_user(int cnum, uint16 vuid)
|
||||
if (!become_gid(gid)) return(False);
|
||||
|
||||
#ifndef NO_SETGROUPS
|
||||
if (!IS_IPC(cnum)) {
|
||||
if (!(VALID_CNUM(cnum) && conn->ipc)) {
|
||||
/* groups stuff added by ih/wreu */
|
||||
if (current_user.ngroups > 0)
|
||||
if (setgroups(current_user.ngroups,current_user.groups)<0)
|
||||
@@ -266,7 +264,7 @@ BOOL become_user(int cnum, uint16 vuid)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Connections[cnum].admin_user && !become_uid(uid))
|
||||
if (!conn->admin_user && !become_uid(uid))
|
||||
return(False);
|
||||
}
|
||||
|
||||
|
||||
@@ -381,6 +381,26 @@ char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align
|
||||
return q;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
makes a DOM_LOG_INFO structure.
|
||||
********************************************************************/
|
||||
void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
|
||||
uint16 sec_chan, char *comp_name)
|
||||
{
|
||||
if (log == NULL) return;
|
||||
|
||||
DEBUG(5,("make_log_info %d\n", __LINE__));
|
||||
|
||||
log->undoc_buffer = 1;
|
||||
|
||||
make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv));
|
||||
make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name));
|
||||
|
||||
log->sec_chan = sec_chan;
|
||||
|
||||
make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
reads or writes a DOM_LOG_INFO structure.
|
||||
********************************************************************/
|
||||
@@ -626,8 +646,8 @@ void make_rpc_header(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type,
|
||||
hdr->call_id = call_id; /* call identifier - match incoming RPC */
|
||||
hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */
|
||||
hdr->context_id = 0; /* presentation context identifier */
|
||||
hdr->cancel_count = opnum; /* reply: cancel count. request: opnum */
|
||||
hdr->reserved = 0; /* reserved */
|
||||
hdr->cancel_count = 0; /* cancel count */
|
||||
hdr->opnum = opnum; /* opnum */
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@@ -651,7 +671,7 @@ char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int
|
||||
DBG_RW_IVAL("alloc_hint", depth, base, io, q, rpc->alloc_hint); q += 4;
|
||||
DBG_RW_CVAL("context_id", depth, base, io, q, rpc->context_id); q++;
|
||||
DBG_RW_CVAL("cancel_ct ", depth, base, io, q, rpc->cancel_count); q++;
|
||||
DBG_RW_CVAL("reserved ", depth, base, io, q, rpc->reserved); q++;
|
||||
DBG_RW_CVAL("opnum ", depth, base, io, q, rpc->opnum); q++;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user