X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Fsmbd%2Fserver.c;h=51710b7b77959517bff320749b797f5ae2ba305c;hb=3ab97ebe6db1a5a4a0573c7c8482c94876bbce9a;hp=2d47816ff7686656d875d622e660db06b414fe11;hpb=691632e555274853dbefccf4accc6f5ee5e42e27;p=kai%2Fsamba.git diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 2d47816ff76..51710b7b779 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Main SMB server routines - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ pstring servicesf = CONFIGFILE; extern pstring debugf; extern pstring sesssetup_user; +extern fstring myworkgroup; char *InBuffer = NULL; char *OutBuffer = NULL; @@ -33,8 +34,6 @@ char *last_inbuf = NULL; int am_parent = 1; int atexit_set = 0; -BOOL share_mode_pending = False; - /* the last message the was processed */ int last_message = -1; @@ -67,7 +66,17 @@ int max_file_fd_used = 0; extern int Protocol; -int maxxmit = BUFFER_SIZE; +/* + * Size of data we can send to client. Set + * by the client for all protocols above CORE. + * Set by us for CORE protocol. + */ +int max_send = BUFFER_SIZE; +/* + * Size of the data we can receive. Set by us. + * Can be modified by the max xmit parameter. + */ +int max_recv = BUFFER_SIZE; /* a fnum to use when chaining */ int chain_fnum = -1; @@ -103,6 +112,7 @@ static int find_free_connection(int hash); void *dflt_sig(void) { exit_server("caught signal"); + return 0; /* Keep -Wall happy :-) */ } /**************************************************************************** Send a SIGTERM to our process group. @@ -130,19 +140,21 @@ mode_t unix_mode(int cnum,int dosmode) if ( !IS_DOS_READONLY(dosmode) ) result |= (S_IWUSR | S_IWGRP | S_IWOTH); - if (IS_DOS_DIR(dosmode)) + if (IS_DOS_DIR(dosmode)) { result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR); - - if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode)) - result |= S_IXUSR; + result &= (lp_dir_mode(SNUM(cnum)) | 0700); + } else { + if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode)) + result |= S_IXUSR; - if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode)) - result |= S_IXGRP; + if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode)) + result |= S_IXGRP; - if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode)) - result |= S_IXOTH; + if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode)) + result |= S_IXOTH; - result &= CREATE_MODE(cnum); + result &= CREATE_MODE(cnum); + } return(result); } @@ -300,7 +312,7 @@ static BOOL mangled_equal(char *name1, char *name2) { pstring tmpname; - if (is_8_3(name2)) + if (is_8_3(name2, True)) return(False); strcpy(tmpname,name2); @@ -398,18 +410,29 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component) unix_format(name); unix_clean_name(name); - if (!case_sensitive && - (!case_preserve || (is_8_3(name) && !short_case_preserve))) - strnorm(name); - /* names must be relative to the root of the service - trim any leading /. also trim trailing /'s */ trim_string(name,"/","/"); + /* + * Ensure saved_last_component is valid even if file exists. + */ + if(saved_last_component) { + end = strrchr(name, '/'); + if(end) + strcpy(saved_last_component, end + 1); + else + strcpy(saved_last_component, name); + } + + if (!case_sensitive && + (!case_preserve || (is_8_3(name, False) && !short_case_preserve))) + strnorm(name); + /* check if it's a printer file */ if (Connections[cnum].printer) { - if ((! *name) || strchr(name,'/') || !is_8_3(name)) + if ((! *name) || strchr(name,'/') || !is_8_3(name, True)) { char *s; fstring name2; @@ -422,17 +445,6 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component) return(True); } - /* - * Ensure saved_last_component is valid even if file exists. - */ - if(saved_last_component) { - end = strrchr(name, '/'); - if(end) - strcpy(saved_last_component, end + 1); - else - strcpy(saved_last_component, name); - } - /* stat the name - if it exists then we are all done! */ if (sys_stat(name,&st) == 0) return(True); @@ -825,8 +837,8 @@ file_fd_struct *fd_get_already_open(struct stat *sbuf) for(i = 0; i <= max_file_fd_used; i++) { fd_ptr = &FileFd[i]; if((fd_ptr->ref_count > 0) && - (((int32)sbuf->st_dev) == fd_ptr->dev) && - (((int32)sbuf->st_ino) == fd_ptr->inode)) { + (((uint32)sbuf->st_dev) == fd_ptr->dev) && + (((uint32)sbuf->st_ino) == fd_ptr->inode)) { fd_ptr->ref_count++; DEBUG(3, ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n", @@ -849,8 +861,8 @@ file_fd_struct *fd_get_new() for(i = 0; i < MAX_OPEN_FILES; i++) { fd_ptr = &FileFd[i]; if(fd_ptr->ref_count == 0) { - fd_ptr->dev = (int32)-1; - fd_ptr->inode = (int32)-1; + fd_ptr->dev = (uint32)-1; + fd_ptr->inode = (uint32)-1; fd_ptr->fd = -1; fd_ptr->fd_readonly = -1; fd_ptr->fd_writeonly = -1; @@ -915,8 +927,8 @@ int fd_attempt_close(file_fd_struct *fd_ptr) fd_ptr->fd_readonly = -1; fd_ptr->fd_writeonly = -1; fd_ptr->real_open_flags = -1; - fd_ptr->dev = -1; - fd_ptr->inode = -1; + fd_ptr->dev = (uint32)-1; + fd_ptr->inode = (uint32)-1; } } return fd_ptr->ref_count; @@ -925,7 +937,7 @@ int fd_attempt_close(file_fd_struct *fd_ptr) /**************************************************************************** open a file ****************************************************************************/ -void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf) +static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf) { extern struct current_user current_user; pstring fname; @@ -1021,14 +1033,6 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s return; } - /* - * If O_TRUNC was set, ensure we truncate the file. - * open_file_shared explicitly clears this flag before - * calling open_file, so we can safely do this here. - */ - if(flags & O_TRUNC) - ftruncate(fd_ptr->fd, 0); - } else { int open_flags; /* We need to allocate a new file_fd_struct (this increments the @@ -1049,7 +1053,15 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s /* Set the flags as needed without the read/write modes. */ open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY); fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode); + /* + * On some systems opening a file for R/W access on a read only + * filesystems sets errno to EROFS. + */ +#ifdef EROFS + if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) { +#else /* No EROFS */ if((fd_ptr->fd == -1) && (errno == EACCES)) { +#endif /* EROFS */ if(flags & O_WRONLY) { fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode); fd_ptr->real_open_flags = O_WRONLY; @@ -1104,8 +1116,8 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s sbuf = &statbuf; } /* Set the correct entries in fd_ptr. */ - fd_ptr->dev = (int32)sbuf->st_dev; - fd_ptr->inode = (int32)sbuf->st_ino; + fd_ptr->dev = (uint32)sbuf->st_dev; + fd_ptr->inode = (uint32)sbuf->st_ino; Files[fnum].fd_ptr = fd_ptr; Connections[cnum].num_files_open++; @@ -1121,7 +1133,6 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s Files[fnum].can_read = ((flags & O_WRONLY)==0); Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0); Files[fnum].share_mode = 0; - Files[fnum].share_pending = False; Files[fnum].print_file = Connections[cnum].printer; Files[fnum].modified = False; Files[fnum].cnum = cnum; @@ -1155,7 +1166,7 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s { Files[fnum].mmap_size = file_size(fname); Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size, - PROT_READ,MAP_SHARED,Files[fnum].fd,0); + PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0); if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr) { @@ -1221,38 +1232,49 @@ close a file - possibly invalidating the read prediction ****************************************************************************/ void close_file(int fnum) { - int cnum = Files[fnum].cnum; - invalidate_read_prediction(Files[fnum].fd_ptr->fd); - Files[fnum].open = False; + files_struct *fs_p = &Files[fnum]; + int cnum = fs_p->cnum; + uint32 dev = fs_p->fd_ptr->dev; + uint32 inode = fs_p->fd_ptr->inode; + share_lock_token token; + + invalidate_read_prediction(fs_p->fd_ptr->fd); + fs_p->open = False; Connections[cnum].num_files_open--; - if(Files[fnum].wbmpx_ptr) + if(fs_p->wbmpx_ptr) { - free((char *)Files[fnum].wbmpx_ptr); - Files[fnum].wbmpx_ptr = NULL; + free((char *)fs_p->wbmpx_ptr); + fs_p->wbmpx_ptr = NULL; } #if USE_MMAP - if(Files[fnum].mmap_ptr) + if(fs_p->mmap_ptr) { - munmap(Files[fnum].mmap_ptr,Files[fnum].mmap_size); - Files[fnum].mmap_ptr = NULL; + munmap(fs_p->mmap_ptr,fs_p->mmap_size); + fs_p->mmap_ptr = NULL; } #endif if (lp_share_modes(SNUM(cnum))) - del_share_mode(fnum); + { + lock_share_entry( cnum, dev, inode, &token); + del_share_mode(token, fnum); + } - fd_attempt_close(Files[fnum].fd_ptr); + fd_attempt_close(fs_p->fd_ptr); + + if (lp_share_modes(SNUM(cnum))) + unlock_share_entry( cnum, dev, inode, token); /* NT uses smbclose to start a print - weird */ - if (Files[fnum].print_file) + if (fs_p->print_file) print_file(fnum); /* check for magic scripts */ check_magic(fnum,cnum); DEBUG(2,("%s %s closed file %s (numopen=%d)\n", - timestring(),Connections[cnum].user,Files[fnum].name, + timestring(),Connections[cnum].user,fs_p->name, Connections[cnum].num_files_open)); } @@ -1314,17 +1336,44 @@ return True if sharing doesn't prevent the operation ********************************************************************/ BOOL check_file_sharing(int cnum,char *fname) { - int pid=0; - int share_mode = get_share_mode_byname(cnum,fname,&pid); + int i; + int ret = False; + min_share_mode_entry *old_shares = 0; + int num_share_modes; + struct stat sbuf; + share_lock_token token; + int pid = getpid(); - if (!pid || !share_mode) return(True); - - if (share_mode == DENY_DOS) - return(pid == getpid()); + if(!lp_share_modes(SNUM(cnum))) + return True; + + if (stat(fname,&sbuf) == -1) return(True); + + lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token); + num_share_modes = get_share_modes(cnum, token, + (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares); + + for( i = 0; i < num_share_modes; i++) + { + if (old_shares[i].share_mode != DENY_DOS) + goto free_and_exit; + + if(old_shares[i].pid != pid) + goto free_and_exit; + } /* XXXX exactly what share mode combinations should be allowed for deleting/renaming? */ - return(False); + /* If we got here then either there were no share modes or + all share modes were DENY_DOS and the pid == getpid() */ + ret = True; + +free_and_exit: + + unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token); + if(old_shares != NULL) + free((char *)old_shares); + return(ret); } /**************************************************************************** @@ -1332,11 +1381,19 @@ BOOL check_file_sharing(int cnum,char *fname) Helper for open_file_shared. Truncate a file after checking locking; close file if locked. **************************************************************************/ -static void truncate_unless_locked(int fnum, int cnum) +static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, + BOOL *share_locked) { if (Files[fnum].can_write){ if (is_locked(fnum,cnum,0x3FFFFFFF,0)){ + /* If share modes are in force for this connection we + have the share entry locked. Unlock it before closing. */ + if (*share_locked && lp_share_modes(SNUM(cnum))) + unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, + Files[fnum].fd_ptr->inode, token); close_file(fnum); + /* Share mode no longer locked. */ + *share_locked = False; errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRlock; @@ -1353,25 +1410,31 @@ open a file with a share mode void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, int mode,int *Access,int *action) { + files_struct *fs_p = &Files[fnum]; int flags=0; int flags2=0; int deny_mode = (share_mode>>4)&7; struct stat sbuf; BOOL file_existed = file_exist(fname,&sbuf); + BOOL share_locked = False; BOOL fcbopen = False; - int share_pid=0; + share_lock_token token; + uint32 dev = 0; + uint32 inode = 0; - Files[fnum].open = False; - Files[fnum].fd_ptr = 0; + fs_p->open = False; + fs_p->fd_ptr = 0; /* this is for OS/2 EAs - try and say we don't support them */ - if (strstr(fname,".+,;=[].")) { + if (strstr(fname,".+,;=[].")) + { unix_ERR_class = ERRDOS; unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; return; } - if ((ofun & 0x3) == 0 && file_existed) { + if ((ofun & 0x3) == 0 && file_existed) + { errno = EEXIST; return; } @@ -1385,7 +1448,7 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, append does not mean the same thing under dos and unix */ switch (share_mode&0xF) - { + { case 1: flags = O_WRONLY; break; @@ -1399,18 +1462,21 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, default: flags = O_RDONLY; break; - } + } if (flags != O_RDONLY && file_existed && - (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) { - if (!fcbopen) { + (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf)))) + { + if (!fcbopen) + { errno = EACCES; return; } flags = O_RDONLY; } - if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) { + if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB) + { DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname)); errno = EINVAL; return; @@ -1418,21 +1484,36 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (deny_mode == DENY_FCB) deny_mode = DENY_DOS; - if (lp_share_modes(SNUM(cnum))) { - int old_share=0; + if (lp_share_modes(SNUM(cnum))) + { + int num_shares = 0; + int i; + min_share_mode_entry *old_shares = 0; + if (file_existed) - old_share = get_share_mode(cnum,&sbuf,&share_pid); + { + dev = (uint32)sbuf.st_dev; + inode = (uint32)sbuf.st_ino; + lock_share_entry(cnum, dev, inode, &token); + share_locked = True; + num_shares = get_share_modes(cnum, token, dev, inode, &old_shares); + } - if (share_pid) { + for(i = 0; i < num_shares; i++) + { /* someone else has a share lock on it, check to see if we can too */ - int old_open_mode = old_share&0xF; - int old_deny_mode = (old_share>>4)&7; + int old_open_mode = old_shares[i].share_mode &0xF; + int old_deny_mode = (old_shares[i].share_mode >>4)&7; - if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) { + if (deny_mode > 4 || old_deny_mode > 4 || old_open_mode > 2) + { DEBUG(2,("Invalid share mode (%d,%d,%d) on file %s\n", deny_mode,old_deny_mode,old_open_mode,fname)); + free((char *)old_shares); + if(share_locked) + unlock_share_entry(cnum, dev, inode, token); errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadshare; @@ -1441,21 +1522,25 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, { int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode, - share_pid,fname); + old_shares[i].pid,fname); if ((access_allowed == AFAIL) || (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) || (access_allowed == AREAD && flags == O_WRONLY) || - (access_allowed == AWRITE && flags == O_RDONLY)) { + (access_allowed == AWRITE && flags == O_RDONLY)) + { DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n", deny_mode,old_deny_mode,old_open_mode, - share_pid,fname, + old_shares[i].pid,fname, access_allowed)); + free((char *)old_shares); + if(share_locked) + unlock_share_entry(cnum, dev, inode, token); errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadshare; return; - } + } if (access_allowed == AREAD) flags = O_RDONLY; @@ -1464,76 +1549,72 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, flags = O_WRONLY; } } + if(old_shares != 0) + free((char *)old_shares); } DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n", flags,flags2,mode)); open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0); - if (!Files[fnum].open && flags==O_RDWR && errno!=ENOENT && fcbopen) { + if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen) + { flags = O_RDONLY; open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 ); } - if (Files[fnum].open) { + if (fs_p->open) + { int open_mode=0; - switch (flags) { - case O_RDONLY: - open_mode = 0; - break; - case O_RDWR: - open_mode = 2; - break; - case O_WRONLY: - open_mode = 1; - break; + + if((share_locked == False) && lp_share_modes(SNUM(cnum))) + { + /* We created the file - thus we must now lock the share entry before creating it. */ + dev = fs_p->fd_ptr->dev; + inode = fs_p->fd_ptr->inode; + lock_share_entry(cnum, dev, inode, &token); + share_locked = True; + } + + switch (flags) + { + case O_RDONLY: + open_mode = 0; + break; + case O_RDWR: + open_mode = 2; + break; + case O_WRONLY: + open_mode = 1; + break; } - Files[fnum].share_mode = (deny_mode<<4) | open_mode; - Files[fnum].share_pending = True; + fs_p->share_mode = (deny_mode<<4) | open_mode; - if (Access) { + if (Access) (*Access) = open_mode; - } - - if (action) { + + if (action) + { if (file_existed && !(flags2 & O_TRUNC)) *action = 1; if (!file_existed) *action = 2; if (file_existed && (flags2 & O_TRUNC)) *action = 3; } - - if (!share_pid) - share_mode_pending = True; + /* We must create the share mode entry before truncate as + truncate can fail due to locking and have to close the + file (which expects the share_mode_entry to be there). + */ + if (lp_share_modes(SNUM(cnum))) + set_share_mode(token, fnum); if ((flags2&O_TRUNC) && file_existed) - truncate_unless_locked(fnum,cnum); + truncate_unless_locked(fnum,cnum,token,&share_locked); } -} - - -/******************************************************************* -check for files that we should now set our share modes on -********************************************************************/ -static void check_share_modes(void) -{ - int i; - for (i=0;i=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; @@ -2582,7 +2668,8 @@ int reply_lanman1(char *outbuf) } CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ - SSVAL(outbuf,smb_vwv2,maxxmit); + SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ + SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */ SSVAL(outbuf,smb_vwv4,1); SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support @@ -2605,6 +2692,11 @@ int reply_lanman2(char *outbuf) int secword=0; BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); + /* We need to save and restore this as it can be destroyed + if we call another server if security=server + Thanks to Paul Nelson @ Thursby for pointing this out. + */ + uint16 mid = SVAL(outbuf, smb_mid); if (lp_security()>=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; @@ -2629,7 +2721,8 @@ int reply_lanman2(char *outbuf) } CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ - SSVAL(outbuf,smb_vwv2,maxxmit); + SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ + SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); SSVAL(outbuf,smb_vwv4,1); SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */ @@ -2639,32 +2732,72 @@ int reply_lanman2(char *outbuf) return (smb_len(outbuf)+4); } + /**************************************************************************** reply for the nt protocol ****************************************************************************/ int reply_nt1(char *outbuf) { - int capabilities=0x300; /* has dual names + lock_and_read */ + /* dual names + lock_and_read + nt SMBs + remote API calls */ + int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ; +/* + other valid capabilities which we may support at some time... + CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS; + CAP_LARGE_FILES|CAP_LARGE_READX| + CAP_STATUS32|CAP_LEVEL_II_OPLOCKS; + */ + int secword=0; BOOL doencrypt = SMBENCRYPT(); time_t t = time(NULL); + int data_len; + int encrypt_len; + char challenge_len = 8; + /* We need to save and restore this as it can be destroyed + if we call another server if security=server + Thanks to Paul Nelson @ Thursby for pointing this out. + */ + uint16 mid = SVAL(outbuf, smb_mid); + + if (lp_readraw() && lp_writeraw()) + { + capabilities |= CAP_RAW_MODE; + } if (lp_security()>=SEC_USER) secword |= 1; if (doencrypt) secword |= 2; - set_message(outbuf,17,doencrypt?8:0,True); + /* decide where (if) to put the encryption challenge, and + follow it with the OEM'd domain name + */ + encrypt_len = doencrypt?challenge_len:0; +#if UNICODE + data_len = encrypt_len + 2*(strlen(myworkgroup)+1); +#else + data_len = encrypt_len + strlen(myworkgroup) + 1; +#endif + + set_message(outbuf,17,data_len,True); + +#if UNICODE + /* put the OEM'd domain name */ + PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup); +#else + strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup); +#endif + CVAL(outbuf,smb_vwv1) = secword; #ifdef SMB_PASSWD /* Create a token value and add it to the outgoing packet. */ - if (doencrypt) { + if (doencrypt) + { generate_next_challenge(smb_buf(outbuf)); + /* Tell the nt machine how long the challenge is. */ - SSVALS(outbuf,smb_vwv16+1,8); + SSVALS(outbuf,smb_vwv16+1,challenge_len); } #endif - SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */ - Protocol = PROTOCOL_NT1; if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { @@ -2674,21 +2807,20 @@ int reply_nt1(char *outbuf) #endif } - if (lp_readraw() && lp_writeraw()) - capabilities |= 1; - + SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */ - SIVAL(outbuf,smb_vwv3+1,0xFFFF); /* max buffer */ - SIVAL(outbuf,smb_vwv5+1,0xFFFF); /* raw size */ + SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */ + SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */ + SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */ SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */ put_long_date(outbuf+smb_vwv11+1,t); SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60); + SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */ return (smb_len(outbuf)+4); } - /* these are the protocol lists used for auto architecture detection: WinNT 3.51: @@ -3205,9 +3337,9 @@ void exit_server(char *reason) #endif } -#if FAST_SHARE_MODES +#ifdef FAST_SHARE_MODES stop_share_mode_mgmt(); -#endif +#endif /* FAST_SHARE_MODES */ DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:"")); exit(0); @@ -3685,24 +3817,6 @@ static void process(void) if (lp_readprediction()) do_read_prediction(); - { - extern pstring share_del_pending; - if (*share_del_pending) { - unbecome_user(); - if (!unlink(share_del_pending)) - DEBUG(3,("Share file deleted %s\n",share_del_pending)); - else - DEBUG(2,("Share del failed of %s\n",share_del_pending)); - share_del_pending[0] = 0; - } - } - - if (share_mode_pending) { - unbecome_user(); - check_share_modes(); - share_mode_pending=False; - } - errno = 0; for (counter=SMBD_SELECT_LOOP; @@ -3734,6 +3848,7 @@ static void process(void) if (!(counter%SMBD_RELOAD_CHECK)) reload_services(True); +#if 0 /* JRA */ /* check the share modes every 10 secs */ if (!(counter%SHARE_MODES_CHECK)) check_share_modes(); @@ -3741,6 +3856,7 @@ static void process(void) /* clean the share modes every 5 minutes */ if (!(counter%SHARE_MODES_CLEAN)) clean_share_modes(); +#endif /* JRA */ /* automatic timeout if all connections are closed */ if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) { @@ -3803,7 +3919,7 @@ static void process(void) if (msg_type == 0) show_msg(InBuffer); - nread = construct_reply(InBuffer,OutBuffer,nread,maxxmit); + nread = construct_reply(InBuffer,OutBuffer,nread,max_send); if(nread > 0) { if (CVAL(OutBuffer,0) == 0) @@ -4029,6 +4145,8 @@ static void usage(char *pname) if (!reload_services(False)) return(-1); + strcpy(myworkgroup, lp_workgroup()); + #ifndef NO_SIGNAL_TEST signal(SIGHUP,SIGNAL_CAST sig_hup); #endif @@ -4075,15 +4193,15 @@ static void usage(char *pname) if (!open_sockets(is_daemon,port)) exit(1); -#if FAST_SHARE_MODES +#ifdef FAST_SHARE_MODES if (!start_share_mode_mgmt()) exit(1); -#endif +#endif /* FAST_SHARE_MODES */ /* possibly reload the services file. */ reload_services(True); - maxxmit = MIN(lp_maxxmit(),BUFFER_SIZE); + max_recv = MIN(lp_maxxmit(),BUFFER_SIZE); if (*lp_rootdir()) {