pstring name1,name2;
extern fstring remote_machine;
extern fstring local_machine;
- char *p;
+ int len;
+ char name_type = 0;
*name1 = *name2 = 0;
smb_setlen(outbuf,0);
switch (msg_type) {
- case 0x81: /* session request */
- CVAL(outbuf,0) = 0x82;
- CVAL(outbuf,3) = 0;
- if (name_len(inbuf+4) > 50 || name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
- DEBUG(0,("Invalid name length in session request\n"));
- return(0);
- }
- name_extract(inbuf,4,name1);
- name_extract(inbuf,4 + name_len(inbuf + 4),name2);
+ case 0x81: /* session request */
+ CVAL(outbuf,0) = 0x82;
+ CVAL(outbuf,3) = 0;
+ if (name_len(inbuf+4) > 50 ||
+ name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
+ DEBUG(0,("Invalid name length in session request\n"));
+ return(0);
+ }
+ name_extract(inbuf,4,name1);
+ name_extract(inbuf,4 + name_len(inbuf + 4),name2);
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
- fstrcpy(remote_machine,name2);
- trim_string(remote_machine," "," ");
- p = strchr(remote_machine,' ');
- strlower(remote_machine);
- if (p) *p = 0;
+ fstrcpy(remote_machine,name2);
+ remote_machine[15] = 0;
+ trim_string(remote_machine," "," ");
+ strlower(remote_machine);
- fstrcpy(local_machine,name1);
- trim_string(local_machine," "," ");
- p = strchr(local_machine,' ');
- strlower(local_machine);
- if (p) *p = 0;
+ fstrcpy(local_machine,name1);
+ len = strlen(local_machine);
+ if (len == 16) {
+ name_type = local_machine[15];
+ local_machine[15] = 0;
+ }
+ trim_string(local_machine," "," ");
+ strlower(local_machine);
+
+ if (name_type == 'R') {
+ /* We are being asked for a pathworks session ---
+ no thanks! */
+ CVAL(outbuf, 0) = 0x83;
+ break;
+ }
- add_session_user(remote_machine);
+ add_session_user(remote_machine);
- reload_services(True);
- reopen_logs();
+ reload_services(True);
+ reopen_logs();
- break;
+ break;
case 0x89: /* session keepalive request
(some old clients produce this?) */
int connection_num;
uint16 vuid = SVAL(inbuf,smb_uid);
int passlen = SVAL(inbuf,smb_vwv3);
- BOOL doencrypt = SMBENCRYPT();
*service = *user = *password = *devicename = 0;
password[passlen]=0;
path = smb_buf(inbuf) + passlen;
- if (!doencrypt || passlen != 24) {
+ if (passlen != 24) {
if (strequal(password," "))
*password = 0;
passlen = strlen(password);
BOOL computer_id=False;
static BOOL done_sesssetup = False;
BOOL doencrypt = SMBENCRYPT();
+ char *domain = "";
*smb_apasswd = 0;
+ *smb_ntpasswd = 0;
smb_bufsize = SVAL(inbuf,smb_vwv2);
smb_mpxmax = SVAL(inbuf,smb_vwv3);
}
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
- if (lp_security() != SEC_SERVER && !doencrypt) {
+ if (!doencrypt && (lp_security() != SEC_SERVER)) {
smb_apasslen = strlen(smb_apasswd);
}
} else {
passlen1 = MIN(passlen1, MAX_PASS_LEN);
passlen2 = MIN(passlen2, MAX_PASS_LEN);
- if(doencrypt) {
+ if(doencrypt || (lp_security() == SEC_SERVER)) {
/* Save the lanman2 password and the NT md4 password. */
smb_apasslen = passlen1;
memcpy(smb_apasswd,p,smb_apasslen);
+ smb_apasswd[smb_apasslen] = 0;
smb_ntpasslen = passlen2;
memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
+ smb_ntpasswd[smb_ntpasslen] = 0;
} else {
/* both Win95 and WinNT stuff up the password lengths for
non-encrypting systems. Uggh.
p += passlen1 + passlen2;
fstrcpy(user,p); p = skip_string(p,1);
+ domain = p;
+
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
- p,skip_string(p,1),skip_string(p,2)));
+ domain,skip_string(p,1),skip_string(p,2)));
}
/* If name ends in $ then I think it's asking about whether a */
/* computer with that name (minus the $) has access. For now */
/* say yes to everything ending in $. */
- if (user[strlen(user) - 1] == '$') {
+ if (user[strlen(user) - 1] == '$')
+ {
#ifdef NTDOMAIN
struct smb_passwd *smb_pass; /* To check if machine account exists */
/*
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)
+ /* non-null user name indicates search by username not by smb userid */
+ smb_pass = get_smbpwd_entry(user, 0);
+
+ if (!smb_pass)
+ {
+ /* lkclXXXX: if workstation entry doesn't exist, indicate logon failure */
+ DEBUG(4,("Workstation trust account %s doesn't exist.",user));
+ SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */
+ CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */
+ return(ERROR(NT_STATUS_LOGON_FAILURE, 0xc000)); /* decimal 109 NT error, 0xc000 */
+ }
+ else
{
/* PAXX: This is the NO LOGON workstation trust account stuff */
- DEBUG(4,("Rejecting workstation trust account %s",user));
+ /* lkclXXXX: if the workstation *does* exist, indicate failure differently! */
+ DEBUG(4,("No 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(NT_STATUS_ALLOTTED_SPACE_EXCEEDED, 0xc000)); /* 0x99 NT error, 0xc00 */
+ return(ERROR(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, 0xc000)); /* decimal 409 NT error, 0xc000 */
}
+
computer_id = True;
#else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */
user[strlen(user) - 1] = '\0';
if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
guest = True;
- if (!guest && !(lp_security() == SEC_SERVER && server_validate(inbuf)) &&
+ if (!guest && !(lp_security() == SEC_SERVER &&
+ server_validate(user, domain,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen)) &&
!check_hosts_equiv(user))
{
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
int fnum = -1;
int smb_mode = SVAL(inbuf,smb_vwv3);
int smb_attr = SVAL(inbuf,smb_vwv5);
- BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ /* Breakout the oplock request bits so we can set the
+ reply bits separately. */
+ BOOL ex_oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
+ BOOL core_oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ BOOL oplock_request = ex_oplock_request | core_oplock_request;
#if 0
int open_flags = SVAL(inbuf,smb_vwv2);
int smb_sattr = SVAL(inbuf,smb_vwv4);
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
return(ERROR(ERRDOS,ERRnoaccess));
}
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ /* If the caller set the extended oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for extended oplock reply.
+ */
+
+ if (ex_oplock_request && lp_fake_oplocks(SNUM(cnum))) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(fsp->granted_oplock) {
+ if(ex_oplock_request && fsp->granted_oplock) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
+ }
+
+ /* If the caller set the core oplock request bit
+ and we granted one (by whatever means) - set the
+ correct bit for core oplock reply.
+ */
+
+ if (core_oplock_request && lp_fake_oplocks(SNUM(cnum))) {
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ }
+
+ if(core_oplock_request && fsp->granted_oplock) {
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
}
+ Files[fnum].reserved = False;
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
int predict=0;
_smb_setlen(header,nread);
+#if USE_READ_PREDICTION
if (!Files[fnum].can_write)
predict = read_predict(fd,startpos,header+4,NULL,nread);
+#endif
if ((nread-predict) > 0)
seek_file(fnum,startpos + predict);
cnum = SVAL(inbuf,smb_tid);
+ /* If it's an IPC, pass off to the pipe handler. */
+ if (IS_IPC(cnum))
+ return reply_pipe_close(inbuf,outbuf);
+
fnum = GETFNUM(inbuf,smb_vwv0);
+
CHECK_FNUM(fnum,cnum);
if(HAS_CACHED_ERROR(fnum)) {
strcpy(fname2,(char *)mktemp(fname));
- if (!check_name(fname2,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
+ if (!check_name(fname2,cnum)) {
+ Files[fnum].reserved = False;
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
/* Open for exclusive use, write only. */
open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
0, NULL, NULL);
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ if (!Files[fnum].open) {
+ Files[fnum].reserved = False;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
/* force it to be a print file */
Files[fnum].print_file = True;
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));
{
error = ERRnoaccess;
sprintf(fname,"%s/%s",directory,dname);
- if (!can_rename(fname,cnum)) continue;
+ if (!can_rename(fname,cnum)) {
+ DEBUG(6,("rename %s refused\n", fname));
+ continue;
+ }
pstrcpy(destname,newname);
- if (!resolve_wildcards(fname,destname)) continue;
+ if (!resolve_wildcards(fname,destname)) {
+ DEBUG(6,("resolve_wildcards %s %s failed\n",
+ fname, destname));
+ continue;
+ }
if (file_exist(destname,NULL)) {
- error = 183;
- continue;
+ DEBUG(6,("file_exist %s\n",
+ destname));
+ error = 183;
+ continue;
}
if (!sys_rename(fname,destname)) count++;
DEBUG(3,("reply_mv : doing rename on %s -> %s\n",fname,destname));
open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
1,0,0,&Access,&action);
- if (!Files[fnum1].open) return(False);
+ if (!Files[fnum1].open) {
+ Files[fnum1].reserved = False;
+ return(False);
+ }
if (!target_is_directory && count)
ofun = 1;
if (!Files[fnum2].open) {
close_file(fnum1,False);
+ Files[fnum2].reserved = False;
return(False);
}
/* Check if this is an oplock break on a file
we have granted an oplock on.
*/
- if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) &&
- (num_ulocks == 0) && (num_locks == 0) &&
- (CVAL(inbuf,smb_vwv0) == 0xFF))
+ if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
{
int token;
files_struct *fsp = &Files[fnum];
/* Remove the oplock flag from the sharemode. */
lock_share_entry(fsp->cnum, dev, inode, &token);
- if(remove_share_oplock( fnum, token)==False)
+ if(remove_share_oplock( fnum, token)==False) {
+ DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
+dev = %x, inode = %x\n",
+ fnum, dev, inode));
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+ } else {
+ unlock_share_entry(fsp->cnum, dev, inode, token);
+
+ /* Clear the granted flag and return. */
+ fsp->granted_oplock = False;
+ }
+
+ /* if this is a pure oplock break request then don't send a reply */
+ if (num_locks == 0 && num_ulocks == 0)
{
- DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", fnum, dev, inode));
- unlock_share_entry(fsp->cnum, dev, inode, token);
+ /* Sanity check - ensure a pure oplock break is not a
+ chained request. */
+ if(CVAL(inbuf,smb_vwv0) != 0xff)
+ DEBUG(0,("reply_lockingX: Error : pure oplock break is a chained %d request !\n",
+ (unsigned int)CVAL(inbuf,smb_vwv0) ));
return -1;
}
- unlock_share_entry(fsp->cnum, dev, inode, token);
-
- /* Clear the granted flag and return. */
-
- fsp->granted_oplock = False;
- return -1;
}
/* Data now points at the beginning of the list