diff --git a/connect.c b/connect.c index 6c65645..20ede15 100644 --- a/connect.c +++ b/connect.c @@ -16,6 +16,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* history since 01-Sep-00 + * mst:01-Sep-00: pcz:added real unix rights patch from Przemyslaw Czerpak + * + */ + + #include "net.h" #include "unxfile.h" @@ -317,6 +323,45 @@ int in_act_groups(gid_t gid) return(0); } +/* pcz:01-Sep-00 */ +int get_unix_access_rights(struct stat *stb, uint8 *unixname) +/* returns F_OK, R_OK, W_OK, X_OK */ +/* ----- old ----------------------*/ +/* ORED with 0x10 if owner access */ +/* ORED with 0x20 if group access */ +/* ----- corrent-------------------*/ +/* ORED with 0x20 if W_OK access */ +/* --------------------------------*/ +{ + int mode=0; + uid_t ruid, euid, rgid; + + ruid=getuid(); + euid=geteuid(); + rgid=getgid(); + + setreuid(act_uid,0); + setgid(act_gid); + + if (!access(unixname, F_OK)) { + + if (!access(unixname, R_OK)) + mode |= R_OK; + if (!access(unixname, W_OK)) + /* mode |= W_OK; */ + mode |= W_OK | 0x20; + if (!access(unixname, X_OK)) + mode |= X_OK; + + /* mode |= get_unix_eff_rights(stb) & ~(R_OK|W_OK|X_OK); */ + } + setgid(rgid); + setreuid(ruid, euid); + + return(mode); +} + + int get_unix_eff_rights(struct stat *stb) /* returns F_OK, R_OK, W_OK, X_OK */ /* ORED with 0x10 if owner access */ diff --git a/connect.h b/connect.h index f37510b..5d87597 100644 --- a/connect.h +++ b/connect.h @@ -223,6 +223,7 @@ extern void set_guid(int gid, int uid); extern void reset_guid(void); extern void reseteuid(void); extern int in_act_groups(gid_t gid); +extern int get_unix_access_rights(struct stat *stb, uint8 *unixname); extern int get_unix_eff_rights(struct stat *stb); extern void set_nw_user(int gid, int uid, int id_flags, diff --git a/doc/CHANGES b/doc/CHANGES index aaff720..21381c6 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -2,7 +2,7 @@ Sorry, beginning is in German only. User important notes are in the NEWS file. Aenderungen in mars_nwe bis zum: Changes in mars_nwe till: -=> 30-May-00 <= +=> 01-Jun-00 <= -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -537,4 +537,12 @@ Erste 'oeffentliche' Version passwords beginning with '-'. ( tnx Przemyslaw Czerpak ) - trustee fix <----- ^^^^^^^^^^ pl19 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- 01-Jun-00:trustee.c, SIG_SEGV error. +- 22-Jun-00:added patches from Sergey Lentsov +- 14-Aug-00:added patch from Paolo Prandini + (access to printerqueues,nwbind.c) +- 15-Aug-00:correction for unix rights of trustee/attrib directory (x flag) + (hint: Nagy Zoltan Mark) +- 01-Sep-00:added real unix acces rights patch from Przemyslaw Czerpak +<----- ^^^^^^^^^^ pl20 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 7967528..3fd7f73 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -58,6 +58,9 @@ Ruedi Kneubuehler Volker Lendecke helps distributing +Sergey Lentsov + patches + Leslie fixed getpwnam/getspnam problem. diff --git a/doc/NEWS b/doc/NEWS index 431886b..a12a649 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,3 +1,5 @@ +------01-Sep-00--- 0.99.pl20 --------- +- section 1: new volume flag 'x' to work with unix ACLs ------23-Jul-98--- 0.99.pl12 --------- - changed default bindery directory location: /etc -> /var/nwserv/db ( section 45 ) diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 9047b75..82471d7 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,16 +1,15 @@ Begin3 Title: mars_nwe -Version: 0.99.pl19 -Entered-date: 25-Apr-00 +Version: 0.99.pl20 +Entered-date: 01-Sep-00 Description: Full netware 3.xx emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@compu-art.de (Martin Stover) Maintained-by: mstover@compu-art.de (Martin Stover) -Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl19.tgz - 320 kB -Alternate-site: ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/mars_nwe/mars_nwe-0.99.pl19.tgz +Primary-site: ftp://www.compu-art.de/mars_nwe/mars_nwe-0.99.pl20.tgz + 330 kB Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), FreeBSD, UnixWare (2.xx) Copying-policy: GPL End diff --git a/examples/config.h b/examples/config.h index 33e64ce..3549736 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,8 +1,8 @@ -/* config.h: 11-Jul-98 */ +/* config.h: 22-Jun-00 */ /* some of this config is needed by make, others by cc */ #define DO_DEBUG 1 /* compile in debug code */ -#define FUNC_17_02_IS_DEBUG 1 /* allow debugging with mars_dosutils */ +#define FUNC_17_02_IS_DEBUG 0 /* allow debugging with mars_dosutils */ #define DO_TESTING 0 /* set this to "1" to test only */ @@ -85,3 +85,6 @@ #define SHADOW_PWD 0 /* change to '1' for shadow passwds */ #define QUOTA_SUPPORT 0 /* change to '1' for quota support */ +/* for sending 'Request being serviced' replys, /lenz */ +#define CALL_NWCONN_OVER_SOCKET 0 + diff --git a/examples/nw.ini b/examples/nw.ini index 2567302..e7fb1a6 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -2,7 +2,11 @@ # This is the configuration-file for "mars_nwe", a free netware-emulator # for Linux. # -# last changed: 04-Apr-00 +# last changed: 01-Sep-00 +# new volume flag 'x' for unix access rights (Przemyslaw Czerpak) 0.99.pl20 +# comment out second printer and printserver entry in 0.99.pl20 +# debug log section changed some values to '1' in 0.99.pl20 +# # !! section 31 : flags added in 0.99.pl18, but not used # !! section 8 : new flags added in 0.99.pl18 !! # !! section 9 : default directory/file umask changed in 0.99.pl9 !! @@ -129,6 +133,7 @@ # Must only be used for volume which have fix inodes. # A volume with trustees should never be renamed. # For some more notes see 'doc/TRUSTEES'. +# x use unix access rights (for use with ACL) # T volume has trustees & ignore the rights granted in UN*X filesystem # exactly like option "t" except that the unix rights are not added # @@ -711,7 +716,8 @@ # 21 FAXPRINT - /usr/bin/psfaxprn /var/spool/fax/faxqueue # ------------------------------------------------------------------------- 21 LP - lpr - -21 LP_PS +#21 LP_PS + # ========================================================================= @@ -729,7 +735,7 @@ # Examples: # 22 PS1 OCTOPUSS -22 PS_NWE LP_PS 1 +#22 PS_NWE LP_PS 1 # ========================================================================= @@ -815,10 +821,10 @@ 100 0 # debug IPX KERNEL (0 | 1) 101 1 # debug NWSERV -102 0 # debug NCPSERV -103 0 # debug NWCONN +102 1 # debug NCPSERV +103 1 # debug NWCONN 104 0 # debug (start) NWCLIENT, should *always* be '0' ! -105 0 # debug NWBIND +105 1 # debug NWBIND 106 1 # debug NWROUTED # Sections 200-202: logging of "nwserv" diff --git a/ftrustee.c b/ftrustee.c index 848d72d..94406bf 100644 --- a/ftrustee.c +++ b/ftrustee.c @@ -107,6 +107,45 @@ int in_act_groups(gid_t gid) return(0); } +/* pcz:01-Sep-00 */ +int get_unix_access_rights(struct stat *stb, uint8 *unixname) +/* returns F_OK, R_OK, W_OK, X_OK */ +/* ----- old ----------------------*/ +/* ORED with 0x10 if owner access */ +/* ORED with 0x20 if group access */ +/* ----- corrent-------------------*/ +/* ORED with 0x20 if W_OK access */ +/* --------------------------------*/ +{ + int mode=0; + uid_t ruid, euid, rgid; + + ruid=getuid(); + euid=geteuid(); + rgid=getgid(); + + setreuid(act_uid,0); + setgid(act_gid); + + if (!access(unixname, F_OK)) { + + if (!access(unixname, R_OK)) + mode |= R_OK; + if (!access(unixname, W_OK)) + /* mode |= W_OK; */ + mode |= W_OK | 0x20; + if (!access(unixname, X_OK)) + mode |= X_OK; + + /* mode |= get_unix_eff_rights(stb) & ~(R_OK|W_OK|X_OK); */ + } + setgid(rgid); + setreuid(ruid, euid); + + return(mode); +} + + int get_unix_eff_rights(struct stat *stb) /* returns F_OK, R_OK, W_OK, X_OK */ /* ORED with 0x10 if owner access */ diff --git a/makefile.unx b/makefile.unx index 1bb5203..7b90408 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 15-Apr-00 +#makefile.unx 30-May-00 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=99 -P_L=19 +P_L=20 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/ncpserv.c b/ncpserv.c index 6adf2b5..53f3059 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -17,6 +17,10 @@ */ #include "net.h" +#if !CALL_NWCONN_OVER_SOCKET +#include +#include +#endif static int ncp_fd = -1; static uint8 ipx_in_data[IPX_MAX_DATA]; @@ -38,6 +42,12 @@ static int highest_fd = 10; static int station_restrictions=0; static int max_connections=MAX_CONNECTIONS; +#if !CALL_NWCONN_OVER_SOCKET +static char *nwconn_state; /* shared memory segment will be + * attached to this pointer */ +static int nwconn_state_shm_id; +#endif + static void set_highest_fd(int fd) { if (fd > highest_fd) @@ -139,7 +149,6 @@ typedef struct { int pid; /* pid from son */ ipxAddr_t client_adr; /* address client */ int sequence; /* previous sequence */ - int retry; /* one reply being serviced is sent */ time_t last_access; /* time of last 0x2222 request */ } CONNECTION; @@ -312,7 +321,6 @@ static int find_get_conn_nr(ipxAddr_t *addr) /* new process */ char *progname="nwconn"; char pathname[300]; - char pidstr[20]; char connstr[20]; char addrstr[100]; char divstr[50]; @@ -330,12 +338,16 @@ static int find_get_conn_nr(ipxAddr_t *addr) dup2(ncp_fd, 3); /* becomes 3 */ while (j++ < highest_fd) close(j); /* close all > 3 */ - sprintf(pidstr, "%d", akt_pid); sprintf(connstr, "%d", connection); ipx_addr_to_adr(addrstr, addr); +#if !CALL_NWCONN_OVER_SOCKET + l=sprintf(divstr, "()INIT-:%08x,%04x,%04x,%08x-", + akt_pid, sock_nwbind, sock_echo, nwconn_state_shm_id); +#else l=sprintf(divstr, "()INIT-:%08x,%04x,%04x-", akt_pid, sock_nwbind, sock_echo); +#endif if (l < 48) { memset(divstr+l, '-', 48-l); @@ -549,12 +561,12 @@ static void handle_ncp_request(void) #if !CALL_NWCONN_OVER_SOCKET if (ncprequest->sequence == c->sequence - && !c->retry++) { - /* perhaps nwconn is busy */ + && nwconn_state[connection] > 0) { /* check, is nwconn + * actually busy? */ ncp_response(0x9999, ncprequest->sequence, connection, ncprequest->task, 0x0, 0, 0); - XDPRINTF((2, 0, "Send Request being serviced to connection:%d", connection)); + XDPRINTF((2, 0, "Send Request being serviced, connection:%d, func=%x, difftime=%d, task=%d", connection, ncprequest->function, diff_time, ncprequest->task)); return; } #endif @@ -569,7 +581,6 @@ static void handle_ncp_request(void) XDPRINTF((10,0, "write to %d, anz = %d", c->fd, anz)); } c->sequence = ncprequest->sequence; /* save last sequence */ - c->retry = 0; return; } else { /* 0x5555, close connection */ @@ -720,6 +731,22 @@ int main(int argc, char *argv[]) adr_to_ipx_addr(&my_addr, argv[2]); sscanf(argv[3], "%x", &sock_nwbind); sscanf(argv[4], "%x", &sock_echo); + +#if !CALL_NWCONN_OVER_SOCKET + nwconn_state_shm_id = shmget(IPC_PRIVATE, MAX_CONNECTIONS, IPC_CREAT|0600); + if (nwconn_state_shm_id == -1) { + errorp(1, "Can't get shared memory", NULL); + return(1); + } + nwconn_state = shmat(nwconn_state_shm_id, NULL, SHM_R); + if ((int )(nwconn_state) == -1) { + errorp(1, "Can't attach shared memory segment", NULL); + return(1); + } + shmctl(nwconn_state_shm_id, IPC_RMID, NULL); /* mark shm as destroyed, + * it will actually be destroyed + * after program exit. /lenz */ +#endif #ifdef LINUX set_emu_tli(); diff --git a/nwbind.c b/nwbind.c index f0dbe47..1549cb1 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "25-Apr-00" +#define REVISION_DATE "14-Aug-00" /* NCP Bindery SUB-SERVER */ /* authentification and some message and queue handling */ @@ -24,6 +24,7 @@ * * mst:25-Apr-00: added login control routines from Paolo Prandini * mst:25-Apr-00: added simple example for getting nwconn data + * mst:14-Aug-00: added patch from Poalo Prandini * */ @@ -777,7 +778,11 @@ static void handle_fxx(int gelen, int func) result=-0xff; } } - if (!result) { + if ( (!result) && obj.type == 1 ) { + /* ..............^^^^^^^^^^^^^^^ + * This check is necessary to avoid restriction on objects + * other than users! Paolo Prandini,mst:14-Aug-00 + */ internal_act = 1; result = nw_test_adr_time_access(obj.id, &(act_c->client_adr)); internal_act = 0; @@ -884,11 +889,17 @@ static void handle_fxx(int gelen, int func) result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); internal_act = 0; } - if (result > -1) { + + if ( (result>-1) && obj.type == 1 ) { + /* ..............^^^^^^^^^^^^^^^ + * This check is necessary to avoid restriction on objects + * other than users! Paolo Prandini,mst:14-Aug-00 + */ internal_act = 1; result = nw_test_adr_time_access(obj.id, &(act_c->client_adr)); internal_act = 0; } + if (result > -1) data_len = build_login_response(responsedata, obj.id); else { diff --git a/nwconn.c b/nwconn.c index fa3b125..0a7d1fb 100644 --- a/nwconn.c +++ b/nwconn.c @@ -32,6 +32,11 @@ # define LOC_RW_BUFFERSIZE 512 #endif #include +#if !CALL_NWCONN_OVER_SOCKET +#include +#include +#endif + #include "nwvolume.h" #include "nwfile.h" #include "connect.h" @@ -71,6 +76,11 @@ static char *prog_title; static int req_printed=0; +#if !CALL_NWCONN_OVER_SOCKET +static char* nwconn_state; /* shared memory segment will be + * attached to this pointer */ +#endif + #if ENABLE_BURSTMODE typedef struct { BURSTPACKET *sendburst; /* buffer for sending burstpacket @@ -1471,17 +1481,20 @@ static int handle_ncp_serv(void) int fhandle = GET_32 (input->fhandle); uint32 offset= GET_BE32(input->offset); uint32 size = GET_BE32(input->size); + uint16 timeout = GET_BE16(input->timeout); if (function == 0x1a) /* lockfile */ completition = (uint8)(-nw_log_physical_record( fhandle, offset, size, + timeout, (int)input->lock_flag)); else completition = (uint8)(-nw_log_physical_record( fhandle, offset, size, + timeout, -2 /* unlock + unlog */ )); } @@ -2622,16 +2635,34 @@ static void set_sig(void) int main(int argc, char **argv) { +#if !CALL_NWCONN_OVER_SOCKET + int shm_id; +#endif time_t last_time=time(NULL); +#if CALL_NWCONN_OVER_SOCKET if (argc != 4 || 3!=sscanf(argv[3], "()INIT-:%x,%x,%x-", &father_pid, &sock_nwbind, &sock_echo)) { fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock-\n"); exit(1); } +#else + if (argc != 4 || 4!=sscanf(argv[3], "()INIT-:%x,%x,%x,%x-", + &father_pid, &sock_nwbind, &sock_echo, &shm_id)) { + fprintf(stderr, "usage nwconn connid FROM_ADDR ()INIT-:pid,nwbindsock,echosock,shm_id-\n"); + exit(1); + } +#endif prog_title=argv[3]; setuid(0); setgid(0); act_connection = atoi(*(argv+1)); +#if !CALL_NWCONN_OVER_SOCKET + nwconn_state = shmat(shm_id, NULL, SHM_W); + if ((int )(nwconn_state) == -1) { + errorp(0, "Can't attach shared memory segment", NULL); + exit(1); + } +#endif init_tools(NWCONN, 0); memset(saved_readbuff, 0, sizeof(saved_readbuff)); XDPRINTF((3, 0, "FATHER PID=%d, ADDR=%s CON:%d", @@ -2679,8 +2710,19 @@ int main(int argc, char **argv) set_sig(); while ( !(fl_get_int&1) ) { - int data_len = read(0, readbuff, sizeof(readbuff)); - + int data_len; + /* We should reply 'Request Being Processed' if request arrived twice + * or more and nwconn actually busy, if nwconn is free, we are simply + * resend previous reply. + * We are set the flag in shared memory indicating what nwconn is busy + * and check it later in ncpserv. /lenz */ +#if !CALL_NWCONN_OVER_SOCKET + nwconn_state[act_connection] = 0; /* nwconn is free */ +#endif + data_len = read(0, readbuff, sizeof(readbuff)); +#if !CALL_NWCONN_OVER_SOCKET + nwconn_state[act_connection] = 1; /* nwconn is busy */ +#endif /* this read is a pipe or a socket read, * depending on CALL_NWCONN_OVER_SOCKET */ @@ -2724,8 +2766,8 @@ int main(int argc, char **argv) act_time=time(NULL); act_ncpsequence=(int)(ncprequest->sequence); - if (act_time > last_time+300 && saved_sequence == -1) { - /* ca. 5 min. reset wdogs */ + if (act_time > last_time+60 && saved_sequence == -1) { + /* ca. 0.5 min. reset wdogs, 5 min as in original is too long for me. /lenz*/ call_nwbind(1); last_time=act_time; } diff --git a/nwfile.c b/nwfile.c index 280cf31..ad68792 100644 --- a/nwfile.c +++ b/nwfile.c @@ -318,7 +318,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, else { eff_rights = tru_get_eff_rights(volume, unixname, stbuff); dwattrib = get_nw_attrib_dword(volume, unixname, stbuff); - +#if 0 // removed by lenz /* mst: 12-Apr-00 */ if (access & 0x10) { access &= ~0x10; @@ -328,7 +328,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, access |= 0x4; /* deny read */ } } - +#endif #if 0 if ( (dwattrib & FILE_ATTR_SHARE) && (access & 0x10) ) { access &= ~0x10; @@ -779,7 +779,8 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) struct timeval t; FD_ZERO(&fdin); FD_SET(fh->fd, &fdin); - t.tv_sec = 5; /* should be enough */ + /* t.tv_sec = 5; */ /* should be enough */ + t.tv_sec = 30; /* sometimes more time needed */ t.tv_usec = 0; size = select(fh->fd+1, &fdin, NULL, NULL, &t); if (size > 0) @@ -817,12 +818,13 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) */ /* check for lock */ struct flock flockd; - flockd.l_type = F_WRLCK; + flockd.l_type = F_RDLCK; /* if file is not locked exclusive + * we should allow read it. /lenz */ flockd.l_whence = SEEK_SET; flockd.l_start = offset; flockd.l_len = size; fcntl(fh->fd, F_GETLK, &flockd); - if (flockd.l_type == F_UNLCK) { + if (flockd.l_type != F_WRLCK) { while (1) { if (offset < fh->size_mmap) { if (size + offset > fh->size_mmap) @@ -838,7 +840,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) break; } } /* while */ - } else size = -0x93; /* no read privileges */ + } else size = -0xa2; /* I/O lock error. /lenz */ } else { if (fh->offd != (long)offset) { fh->offd=lseek(fh->fd, offset, SEEK_SET); @@ -863,7 +865,7 @@ int nw_read_file(int fhandle, uint8 *data, int size, uint32 offset) } else { XDPRINTF((5,0,"read-file failed in read")); } - } else size = -0x93; /* no read privileges */ + } else size = -0xa2; /* I/O lock error. /lenz */ } else size = -1; } if (size == -1) size=0; @@ -927,7 +929,7 @@ int nw_write_file(int fhandle, uint8 *data, int size, uint32 offset) fh->offd+=(long)size; if (!fh->modified) fh->modified++; - } else size = -0x94; /* no write privileges */ + } else size = -0xa2; /* I/O lock error. /lenz */ } else size = -1; return(size); } else { /* truncate FILE */ @@ -987,7 +989,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset, } int nw_log_physical_record(int fhandle, uint32 offset, - uint32 size, int lock_flag) + uint32 size, uint16 timeout, int lock_flag) { int result=-0x88; /* wrong filehandle */ if (fhandle > HOFFS && (fhandle <= count_fhandles)) { @@ -1033,14 +1035,13 @@ int nw_log_physical_record(int fhandle, uint32 offset, (size==MAX_U32) ? 0 - : size & 0x7fffffff); + : size & 0x7fffffff, + + timeout); - XDPRINTF((4, 0, "nw_log_phy_rec:flag=%2d, result=%d, fh=%d, offset=%d, size=%d", - lock_flag, result, fhandle, offset, size)); + XDPRINTF((4, 0, "nw_log_phy_rec:pid=%d uid=%d flag=%2d, result=%d, fh=%d, offset=%d, size=%d, timeout=%d", + getpid(), geteuid(), lock_flag, result, fhandle, offset, size, timeout)); - if (result) - result= (lock_flag > -1) ? -0xfe : -0xff; - /* 0.99.pl0: changed -0xfd -> -0xfe, hint from Przemyslaw Czerpak */ } else if (fh->fd == -3) result=0; } leave: @@ -1090,10 +1091,11 @@ void log_file_module(FILE *f) while (++k < count_fhandles) { FILE_HANDLE *fh=&(file_handles[k]); if (fh && fh->fd != -1) { - fprintf(f,"%4d %2d %d %4d 0x%04x 0x%04x %2d '%s'\n", + fprintf(f,"%4d %2d %d %4d 0x%04x 0x%04x %2d %04d '%s'\n", k+1, fh->inuse, fh->modified, fh->task, fh->fh_flags, fh->access, fh->volume, - fh->fname); + fh->fd, fh->fname); + dump_locks(fh->st_dev, fh->st_ino, fh->fd, f); handles++; } } diff --git a/nwfile.h b/nwfile.h index 06885d9..7d8975b 100644 --- a/nwfile.h +++ b/nwfile.h @@ -53,7 +53,7 @@ extern int nw_server_copy(int qfhandle, uint32 qoffset, int zfhandle, uint32 zoffset, uint32 size); -extern int nw_log_physical_record(int fhandle, uint32 offset, uint32 size, int do_lock); +extern int nw_log_physical_record(int fhandle, uint32 offset, uint32 size, uint16 timeout, int do_lock); extern int fd_2_fname(int fhandle, char *buf, int bufsize); extern FILE_HANDLE *fd_2_fh(int fhandle); @@ -65,5 +65,5 @@ extern int nw_log_logical_record(int lock_flag, int timeout, int len, uint8 *data); - +extern void dump_locks(int dev, int inode, int fd, FILE *f); #endif diff --git a/nwserv.c b/nwserv.c index e82cb50..5480b94 100644 --- a/nwserv.c +++ b/nwserv.c @@ -357,8 +357,8 @@ static int start_nwbind(char *nwname) # define WDOG_TRIE_AFTER_SEC 1 # define MAX_WDOG_TRIES 1 #else -# define WDOG_TRIE_AFTER_SEC 300 /* ca. 5 min. */ -# define MAX_WDOG_TRIES 11 /* Standardtries */ +# define WDOG_TRIE_AFTER_SEC 60 /* ca. 1 min. */ +# define MAX_WDOG_TRIES 3 /* should be enough */ #endif static void modify_wdog_conn(int conn, int mode); @@ -452,7 +452,7 @@ static void send_wdogs() if (c->last_time) { time_t t_diff = acttime_stamp - c->last_time; if ( (c->counter && t_diff > 50) - || t_diff > WDOG_TRIE_AFTER_SEC) { /* max. 5 minutes */ + || t_diff > WDOG_TRIE_AFTER_SEC) { /* max. 1 minute */ if (c->counter > MAX_WDOG_TRIES) { /* now its enough with trying */ /* clear connection */ diff --git a/nwshare.c b/nwshare.c index 34811ef..fbd8d33 100644 --- a/nwshare.c +++ b/nwshare.c @@ -1,3 +1,4 @@ + /* nwshare.c, 13-Apr-00 */ /* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany * @@ -260,25 +261,35 @@ int share_file(int dev, int inode, int open_mode, int action) if (open_mode & 0xff) { if (!(act_mode & 0x01)) { + /* do not set flockd.l_whence because after F_GETLK kernel + * set it as SEEK_SET */ flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_or, F_GETLK, &flockd); /* read */ if (flockd.l_type != F_UNLCK) act_mode |= 0x01; } if (!(act_mode & 0x04)) { flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_dr, F_GETLK, &flockd); /* deny read */ if (flockd.l_type != F_UNLCK) act_mode |= 0x04; } if (!(act_mode & 0x02)) { flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_ow, F_GETLK, &flockd); /* write */ if (flockd.l_type != F_UNLCK) act_mode |= 0x02; } if (!(act_mode & 0x08)) { flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_dw, F_GETLK, &flockd); /* deny write */ if (flockd.l_type != F_UNLCK) act_mode |= 0x08; @@ -286,6 +297,8 @@ int share_file(int dev, int inode, int open_mode, int action) #if 0 if (!(act_mode & 0x10)) { flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_cm, F_GETLK, &flockd); /* compatible mode */ if (flockd.l_type != F_UNLCK) act_mode |= 0x10; @@ -295,6 +308,8 @@ int share_file(int dev, int inode, int open_mode, int action) if ((open_mode & 0x300) && !(act_mode & 0x100)) { flockd.l_type = F_WRLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_fl, F_GETLK, &flockd); /* lock file */ if (flockd.l_type != F_UNLCK) act_mode |= (flockd.l_type == F_WRLCK) ? 0x100|0x200 : 0x100; @@ -331,31 +346,29 @@ int share_file(int dev, int inode, int open_mode, int action) result = -1; if (action==1 && !result) { /* ADD */ - + flockd.l_type = F_RDLCK; + flockd.l_start = inode; + flockd.l_len = 1; if (open_mode & 0x01) { /* read */ if (!si->or) { - flockd.l_type = F_RDLCK; fcntl(sd->fd_or, F_SETLK, &flockd); } si->or ++; } if (open_mode & 0x04) { /* deny read */ if (!si->dr) { - flockd.l_type = F_RDLCK; fcntl(sd->fd_dr, F_SETLK, &flockd); } si->dr ++; } if (open_mode & 0x02) { /* write */ if (!si->ow) { - flockd.l_type = F_RDLCK; fcntl(sd->fd_ow, F_SETLK, &flockd); } si->ow ++; } if (open_mode & 0x08) { /* deny write */ if (!si->dw) { - flockd.l_type = F_RDLCK; fcntl(sd->fd_dw, F_SETLK, &flockd); } si->dw ++; @@ -363,7 +376,6 @@ int share_file(int dev, int inode, int open_mode, int action) #if 0 if (open_mode & 0x10) { /* compatible mode */ if (!si->cm) { - flockd.l_type = F_RDLCK; fcntl(sd->fd_cm, F_SETLK, &flockd); } si->cm ++; @@ -380,6 +392,8 @@ int share_file(int dev, int inode, int open_mode, int action) } } } else if (action==0) { /* REMOVE */ + flockd.l_start = inode; + flockd.l_len = 1; flockd.l_type = F_UNLCK; if (open_mode & 0x01) /* read */ if (si->or && !(--si->or)) @@ -406,6 +420,8 @@ int share_file(int dev, int inode, int open_mode, int action) } flockd.l_type = F_UNLCK; + flockd.l_start = inode; + flockd.l_len = 1; fcntl(sd->fd_sm, F_SETLK, &flockd); /* realise semaphor */ if (!si->or && !si->ow && !si->dr && !si->dw @@ -454,8 +470,15 @@ static int _get_inode( int dev, int inode, ShareDev **psd, ShareINode **psi ) return 0; } +void catch_alarm (int sig) +{ + signal(sig, SIG_IGN); +} + +#define OFFSET_MAX 0x7fffffff + int share_lock( int dev, int inode, int fd, int action, - int lock_flag, int l_start, int l_len ) + int lock_flag, int l_start, int l_len, int timeout ) /* * action: * 0 = unlock @@ -503,16 +526,33 @@ int share_lock( int dev, int inode, int fd, int action, fcntl( fd, F_SETLK, &flockd ); *psl = sl->next; xfree( sl ); - } else - result = -1; + } else { + XDPRINTF((2, 0, "unlock: can't find proper lock pid=%d uid=%d fd=%d %d, %d", getpid(), geteuid(), fd, l_start, l_len)); + result = -0xff; + } } else { /* lock or test */ if (sl && (l_start < sl->l_start + sl->l_len || !sl->l_len) && (sl->exclusive || lock_flag == 1) ) - result = -1; /* collision */ + result = -0xfd; /* collision */ else { flockd.l_type = (lock_flag == 1) ? F_WRLCK : F_RDLCK; + if (action==1 && timeout > 17) {/* if timeout is relatively short + * do not set the alarm. /lenz */ + signal( SIGALRM, catch_alarm ); + alarm( timeout / 18 ); + result = fcntl( fd, F_SETLKW, &flockd ); + alarm( 0 ); + signal( SIGALRM, SIG_IGN ); + } else { result = fcntl( fd, (action==1) ? F_SETLK : F_GETLK, &flockd ); + } + if (result) { + if (!timeout) /* my NW 3.12 returns 0xff if timeout == 0. /lenz */ + result = -0xff; + else + result = -0xfe; + } if (!result) { if (action == 1) { /* add to list */ @@ -566,6 +606,25 @@ int share_unlock_all( int dev, int inode, int fd ) return result; } +void dump_locks( int dev, int inode, int fd, FILE* f) +{ + ShareDev *sd; + ShareINode *si; + ShareLock *psl; + char tbuf[200]; + sprintf(tbuf,"dev=0x%x,inode=%d,fd=%d", dev, inode, fd); + + if (!_get_inode( dev, inode, &sd, &si )) { + XDPRINTF((1, 0, "Could not find share for unlock_all %s", tbuf)); + } + + for (psl=si->first_lock; psl; ) { + fprintf(f, "fd=%d %d-%d ", psl->fd, psl->l_start, psl->l_len); + psl = psl->next; + } + fprintf(f, "\n"); +} + typedef struct S_SHARESET{ int type; diff --git a/nwshare.h b/nwshare.h index 9c8e5ef..d6e92c2 100644 --- a/nwshare.h +++ b/nwshare.h @@ -7,7 +7,7 @@ /* changed by: Ingmar Thiemann */ extern int share_file(int dev, int inode, int open_mode, int action); extern int share_lock( int dev, int inode, int fd, int action, - int lock_flag, int l_start, int l_len ); + int lock_flag, int l_start, int l_len, int timeout ); extern int share_unlock_all( int dev, int inode, int fd ); extern int share_set_file_add_rm(int lock_flag, int dev, int inode); diff --git a/nwvolume.c b/nwvolume.c index de63874..931c6e1 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,5 +1,5 @@ -/* nwvolume.c 09-Oct-99 */ -/* (C)opyright (C) 1993-1999 Martin Stover, Marburg, Germany +/* nwvolume.c 01-Sep-00 */ +/* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany * * 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 @@ -16,6 +16,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* history since 13-Aug-00 + * + * mst:13-Aug-00 logging in vol_trustee_scan() changed a little bit. + * mst:15-Aug-00 correction of unix rights of trustee and attrib directory. + * mst:01-Sep-00 added real unix right option from Przemyslaw Czerpak + * + */ + + #include "net.h" #include @@ -39,6 +48,7 @@ #include "nwfname.h" #include "nwattrib.h" #include "trustee.h" +#include "unxfile.h" #include "nwvolume.h" #define VOLOPTIONS_DEFAULT VOL_OPTION_ATTRIBUTES @@ -108,11 +118,13 @@ void nw_init_volumes(FILE *f) /* f = inifile Pointer, must be opened !! */ { static int volumes_is_init=0; + int firstinit=0; int what; uint8 buff[256]; int k = -1; if (!volumes_is_init) { volumes_is_init++; + firstinit++; rewind(f); if (get_ini_entry(f, 61, buff, sizeof(buff))) { max_nw_vols=atoi(buff); @@ -214,6 +226,11 @@ void nw_init_volumes(FILE *f) vol->options |= (VOL_OPTION_TRUSTEES | VOL_OPTION_IGNUNXRIGHT); break; + + case 'x' : /* mst:01-Sep-00, option added by Przemyslaw Czerpak */ + vol->options + |= VOL_OPTION_UNX_RIGHT; + break; case 'O' : vol->options |= VOL_NAMESPACE_OS2; @@ -273,6 +290,12 @@ void nw_init_volumes(FILE *f) new_str(path_trustees, buff); } } /* while */ + + if (firstinit) { + /* mst: 15-Aug-00, directory mode corrections */ + unx_add_x_rights(path_attributes, 0111); + unx_add_x_rights(path_trustees, 0111); + } } static int get_unx_home_dir(uint8 *homedir, uint8 *unxlogin) @@ -629,7 +652,13 @@ static void vol_trustee_scan(NW_VOL *v, int volume, memcpy(unixname, v->unixname, v->unixnamlen); /* first UNIXNAME VOLUME */ memcpy(unixname+v->unixnamlen, path, l); unixname[l+v->unixnamlen]='\0'; - XDPRINTF((2, 0, "vol_trustee_scan, trustee path=`%s`", unixname)); + + // XDPRINTF((2, 0, "vol_trustee_scan, trustee path=`%s`", unixname)); + + MDEBUG(D_TRUSTEES,{ + xdprintf(2,0, "vol_trustee_scan, trustee path=`%s`", unixname); + }) + if (!stat(unixname, &stb)) { int trustee=tru_get_id_trustee(volume, unixname, &stb, v->trustee_id); @@ -639,12 +668,14 @@ static void vol_trustee_scan(NW_VOL *v, int volume, up_fn(path); } add_vol_trustee(v, path, l, trustee); - XDPRINTF((2, 0, "trustee=0x%x found", trustee)); + MDEBUG(D_TRUSTEES,{ + xdprintf(1, 0, "path=`%s`,trustee=0x%x found", unixname, trustee); + }) } } else { - XDPRINTF((1, 0, "trustee path=`%s` not found", - unixname)); + XDPRINTF((1, 0, "trustee path=`%s` not found", unixname)); } + } } else if ((!stat(trusteepath, &stb)) && S_ISDIR(stb.st_mode)) { int l=strlen(p); diff --git a/nwvolume.h b/nwvolume.h index 41f96ad..a054572 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -81,6 +81,7 @@ typedef struct { #define VOL_OPTION_TRUSTEES 0x0100 /* Volume use Trustees */ #define VOL_OPTION_ATTRIBUTES 0x0200 /* Volume use 'real' Attributes */ #define VOL_OPTION_IGNUNXRIGHT 0x0400 /* Ignore rights granted in UN*X FS */ +#define VOL_OPTION_UNX_RIGHT 0x0800 /* Use UN*X real rights */ /* namespaces */ #define VOL_NAMESPACE_DOS 0x1000 diff --git a/trustee.c b/trustee.c index c4348aa..dae5cbe 100644 --- a/trustee.c +++ b/trustee.c @@ -18,6 +18,16 @@ /* Trusttee routines for mars_nwe */ +/* history since 01-Jun-00 + * + * mst:01-Jun-00: removed SIG_SEGV in get_eff_rights_by_trustees(), + * when stat error + * mst:01-Sep-00: pcz:added real unix rights patch from Przemyslaw Czerpak + * + * + */ + + #include "net.h" #include #include "unxfile.h" @@ -37,12 +47,20 @@ static int un_nw_rights(int voloptions, uint8 *unixname, struct stat *stb) if (act_uid || is_pipe_command || (voloptions & VOL_OPTION_READONLY)) { int is_dir = S_ISDIR(stb->st_mode); - int acc = get_unix_eff_rights(stb); int norights = TRUSTEE_A; /* no access control rights */ + int acc; + int accp=0; + int isaccp=0; struct stat stbp; uint8 *p = unixname+strlen(unixname); + /* pcz:01-Sep-00 */ + if (voloptions & VOL_OPTION_UNX_RIGHT) + acc=get_unix_access_rights(stb,unixname); + else + acc=get_unix_eff_rights(stb); + memset(&stbp, 0, sizeof(struct stat)); if (p > unixname){ /* now we must get parent rights */ --p; @@ -56,20 +74,27 @@ static int un_nw_rights(int voloptions, uint8 *unixname, struct stat *stb) || !S_ISDIR(stbp.st_mode) ){ /* something wrong here, clear rights */ errorp(0,"un_nw_rights", "wrong path=%s", unixname); - memset(&stbp, 0, sizeof(struct stat)); - } + } else { /* pcz:01-Sep-00 */ + if (voloptions & VOL_OPTION_UNX_RIGHT) + accp=get_unix_access_rights(&stbp,unixname); + else + accp=get_unix_eff_rights(&stbp); + isaccp=1; + } *(p+1)='/'; - } else { - if (stat("/.", &stbp)) - memset(&stbp, 0, sizeof(struct stat)); + } else if (!stat("/.", &stbp)) { /* pcz:01-Sep-00 */ + if (voloptions & VOL_OPTION_UNX_RIGHT) + accp=get_unix_access_rights(&stbp,"/."); + else + accp=get_unix_eff_rights(&stbp); + isaccp=1; } } - if (!stbp.st_mode) { + if (isaccp == 0) { /* pcz:01-Sep-00 */ XDPRINTF((1,0, "no rights to parentdir of %s", unixname)); norights=rights; } else { - int accp=get_unix_eff_rights(&stbp); if (!(accp & X_OK)) norights=rights; else if (!(accp & W_OK)) { @@ -834,7 +859,7 @@ static FILE_TRUSTEE_NODE *find_build_trustee_node(int volume, uint8 *unixname, s errorp(10, "tru_get_eff_rights", "stat error `%s`", unixname); *p='/'; xfree(ugid_trustees); - return(0); + return(NULL); } *p='/'; while (*p=='/')++p; @@ -861,7 +886,7 @@ static int get_eff_rights_by_trustees(int volume, uint8 *unixname, struct stat * return(MAX_TRUSTEE_MASK); /* all rights */ else { FILE_TRUSTEE_NODE *tr = find_build_trustee_node(volume, unixname, stb); - return( (tr->eff_rights > -1) ? tr->eff_rights : 0); + return( (tr && tr->eff_rights > -1) ? tr->eff_rights : 0); } } diff --git a/unxfile.c b/unxfile.c index f822dea..8242479 100644 --- a/unxfile.c +++ b/unxfile.c @@ -1,6 +1,6 @@ -/* unxfile.c: 30-Apr-98*/ +/* unxfile.c: 15-Aug-00 */ -/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany +/* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany * * 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 @@ -97,6 +97,26 @@ int unx_xrmdir(char *unixname) return(rmdir(unixname)); } +int unx_add_x_rights(char *unixname, int mode) +/* set x permiss flag in upper (and current) dirs */ +{ + char *p=unixname; + struct stat stb; + int result=0; + while ( (!result) && (NULL != (p=strchr(p+1, '/')))) { + *p = '\0'; + if ((!stat(unixname, &stb)) && S_ISDIR(stb.st_mode)) + chmod(unixname, stb.st_mode | (0111 & mode) ); + else + result = -1; + *p='/'; + } + if ( (!result) && (!stat(unixname, &stb)) && S_ISDIR(stb.st_mode) ) + chmod(unixname, stb.st_mode | (0111 & mode) ); + return(result); +} + + #if 0 int unx_mvdir(uint8 *oldname, uint8 *newname) { diff --git a/unxfile.h b/unxfile.h index 3e3aaed..30e87af 100644 --- a/unxfile.h +++ b/unxfile.h @@ -21,6 +21,7 @@ extern int unx_mvdir(uint8 *oldname, uint8 *newname); extern int unx_mvfile(uint8 *oldname, uint8 *newname); extern int unx_mvfile_or_dir(uint8 *oldname, uint8 *newname); extern int unx_xmkdir(char *unixname, int mode); +extern int unx_add_x_rights(char *unixname, int mode); extern int unx_xrmdir(char *unixname); extern int unx_ftruncate(int fd, uint32 size);