From 07843f212ba1fcb11e57e602549513b5aec740f2 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 13 Nov 2011 00:38:57 +0100 Subject: [PATCH] mars_nwe-0.97.pl07 --- connect.c | 53 ++++++++++++---- connect.h | 5 +- doc/CHANGES | 13 +++- doc/CREDITS | 5 ++ doc/mars_nwe.lsm | 6 +- emutli.c | 3 +- emutli1.c | 6 +- makefile.unx | 2 +- ncpserv.c | 31 +++++++-- net.h | 14 +++++ nwbind.c | 77 ++++++++++++----------- nwconn.c | 65 ++++++++----------- nwcrypt.c | 86 +++++++++++++++++++++++++ nwcrypt.h | 6 +- nwdbm.c | 160 +++++++++++++++++++++++++++++++++++------------ nwdbm.h | 5 ++ nwfile.c | 71 +++++++++++++-------- nwfile.h | 11 +++- nwqueue.c | 2 - nwserv.c | 4 ++ tools.c | 9 +++ tools.h | 1 + 22 files changed, 465 insertions(+), 170 deletions(-) diff --git a/connect.c b/connect.c index 38ae5ff..412c69a 100644 --- a/connect.c +++ b/connect.c @@ -132,6 +132,10 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath) fh->vol_options = nw_volumes[fh->volume].options; fh->inode = inode; fh->timestamp = akttime; + + fh->sequence = 0; + fh->dirpos = (off_t)0; + if (fh->vol_options & VOL_OPTION_REMOUNT) { closedir(fh->f); fh->f = NULL; @@ -219,10 +223,11 @@ static int x_str_match(uint8 *s, uint8 *p) switch (state){ case 0 : switch (pc) { - case 255: if (*p == '*' || *p == '?' || *p==0xaa || *p==0xae) continue; + case 255: if (*p == '*' || *p == '?' + || *p==0xaa || *p==0xae || *p=='.') continue; break; - case '\\': /* beliebiges Folgezeichen */ + case '\\': /* any following char */ if (*p++ != *s++) return(0); break; @@ -394,7 +399,8 @@ static int get_dir_entry(NW_PATH *nwpath, char xkpath[256]; uint8 entry[256]; int volume = nwpath->volume; - int soptions; + int soptions; + int akt_sequence=0; if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ else soptions = nw_volumes[volume].options; strcpy((char*)entry, (char*)nwpath->fn); @@ -409,10 +415,17 @@ static int get_dir_entry(NW_PATH *nwpath, char *kpath=xkpath+strlen(xkpath); *kpath++ = '/'; if (*sequence == MAX_U16) *sequence = 0; - else seekdir(f, (long)*sequence); + + while (akt_sequence++ < *sequence) { + if (NULL == readdir(f)) { + closedir(f); + return(0); + } + } while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ okflag = 0; + (*sequence)++; if (dirbuff->d_ino) { uint8 *name=(uint8*)(dirbuff->d_name); okflag = (name[0] != '.' && @@ -436,7 +449,6 @@ static int get_dir_entry(NW_PATH *nwpath, XDPRINTF((6,0, "NAME=:%s: OKFLAG %d", name, okflag)); } /* if */ } /* while */ - *sequence = (int) telldir(f); closedir(f); } /* if */ return(okflag); @@ -477,13 +489,30 @@ static int get_dh_entry(DIR_HANDLE *dh, if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry); if ( (uint16)*sequence == MAX_U16) *sequence = 0; - seekdir(f, (long) *sequence); - XDPRINTF((5,0,"get_dh_entry attrib=0x%x path:%s:, entry:%s:", - attrib, dh->unixname, entry)); + if (*sequence < dh->sequence) { + dh->dirpos = (off_t)0; + dh->sequence = 0; + } + seekdir(f, dh->dirpos); + + if (dh->sequence != *sequence) { + while (dh->sequence < *sequence) { + if (NULL == readdir(f)) { + dh->dirpos = telldir(f); + release_dh_f(dh); + return(0); + } + dh->sequence++; + } + dh->dirpos = telldir(f); + } + XDPRINTF((5,0,"get_dh_entry seq=x%x, attrib=0x%x path:%s:, entry:%s:", + *sequence, attrib, dh->unixname, entry)); while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ okflag = 0; + dh->sequence++; if (dirbuff->d_ino) { uint8 *name=(uint8*)(dirbuff->d_name); okflag = (name[0] != '.' && ( @@ -508,9 +537,12 @@ static int get_dh_entry(DIR_HANDLE *dh, } } /* if */ } /* while */ + dh->kpath[0] = '\0'; - *sequence = (int) telldir(f); + *sequence = dh->sequence; + dh->dirpos = telldir(f); release_dh_f(dh); + } /* if */ return(okflag); } @@ -1294,7 +1326,7 @@ int nw_open_dir_handle( int dir_handle, *volume = fh->volume; *dir_id = completition; *searchsequence = MAX_U16; - completition = 0xff; /* Alle Rechte */ + completition = 0xff; /* all rights */ } XDPRINTF((5,0,"NW_OPEN_DIR_2: completition = 0x%x", completition)); @@ -1414,7 +1446,6 @@ static int s_nw_scan_dir_info(int dir_handle, if (rights > -1) { DIR_HANDLE *dh = &(dir_handles[dir_id-1]); struct stat stbuff; - int searchsequence = MAX_U16; uint16 dirsequenz = GET_BE16(subnr); uint16 aktsequenz = 0; uint8 dirname[256]; diff --git a/connect.h b/connect.h index 3f60cca..e3823da 100644 --- a/connect.h +++ b/connect.h @@ -7,8 +7,11 @@ typedef struct { ino_t inode; /* Unix Inode */ time_t timestamp; /* fr letzte Allocierung */ char *kpath; /* Ein Zeichen nach unixname */ - int vol_options; /* Suchoptions */ + int vol_options; /* searchoptions */ int volume; /* Volume Number */ + + int sequence; /* Search sequence */ + off_t dirpos; /* Current pos in unix dir */ } DIR_HANDLE; typedef struct { diff --git a/doc/CHANGES b/doc/CHANGES index 3a27fd5..e69c0e2 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,5 +1,5 @@ Sorry, this is in German only. -Aenderungen in mars_nwe bis zum : 07-May-96 +Aenderungen in mars_nwe bis zum : 20-Jun-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -127,6 +127,17 @@ Erste 'oeffentliche' Version - Zugriffsrechte Bindery erweitert und korrigiert. - Volume option -r fuer readonly eingebaut. <----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- setgroups u. initgroups in set_guid() eingebaut. +<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- SIG_PIPE wird nun in nwconn abgefangen. +<----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- Die Message Calls unter optimierten Kernel Mode wieder + zum Laufen gebracht. +- Routine 'get vol restriction' korrigiert. + Lieferte immer 0 als freien Userspeicherplatz zurueck. +- Bug beim Listen von grossen Direktories korrigiert. (Fritz Elfert) +- CRYPTED CHANGE PASSWORD Routine implementiert. (Guntram Blohm) +<----- ^^^^^^^^^^ pl7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 340f713..556df5a 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -5,6 +5,7 @@ Michael Beddow Guntram Blohm testing router code on token ring + wrote the 'crypted change password' routines ! Uwe Bonnes many testings+notes @@ -15,6 +16,9 @@ Hardy Buchholz Ales Dryak his linware gave the kick +Fritz Elfert + gives Bugreport and Patches + Volker Lendecke helps distributing @@ -27,3 +31,4 @@ Jiri A. Randus Winfried Truemper : re-wrote `INSTALL' and added explanations to `nw.ini' + diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 9e551c0..20d173a 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.97.pl6 -Entered-date: 21-May-96 +Version: 0.97.pl7 +Entered-date: 20-Jun-96 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@freeway.de (Martin Stover) Maintained-by: mstover@freeway.de (Martin Stover) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs - 140kB mars_nwe-0.97.pl6.tgz + 160kB mars_nwe-0.97.pl7.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Platforms: Linux (1.2.xx, 1.3.xx), UnixWare 2.0x Copying-policy: GNU diff --git a/emutli.c b/emutli.c index 87ae528..8ab86d7 100644 --- a/emutli.c +++ b/emutli.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "net.h" #include @@ -61,7 +62,7 @@ void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i) memcpy(&so->sipx_port, i->sock, 2); } -void set_emu_tli() +void set_emu_tli(void) { int i = get_ini_int(100); if (i > -1) locipxdebug = i; diff --git a/emutli1.c b/emutli1.c index 7710716..46db2b6 100644 --- a/emutli1.c +++ b/emutli1.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "net.h" #include @@ -243,7 +244,8 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug) # endif #endif if ((sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0) { - errorp(1, "EMUTLI:init_ipx", NULL); + errorp(1, "EMUTLI:init_ipx", NULL); + errorp(10, "Problem", "probably kernel-IPX is not setup correctly"); exit(1); } else { ipx_config_data cfgdata; @@ -252,7 +254,7 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug) auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces; set_sock_debug(sock); result=0; - /* makes new internal net */ + /* build new internal net */ if (network) { struct sockaddr_ipx ipxs; memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); diff --git a/makefile.unx b/makefile.unx index 2e1b179..e709677 100644 --- a/makefile.unx +++ b/makefile.unx @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=97 -P_L=6 +P_L=7 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/ncpserv.c b/ncpserv.c index 266760d..acd746c 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -143,8 +143,9 @@ static int open_ipx_sockets(void) } typedef struct { - int fd; /* writepipe */ - /* or if CALL_NWCONN_OVER_SOCKET then sock_nr of nwconn */ + int fd; /* writepipe */ + /* or if CALL_NWCONN_OVER_SOCKET */ + /* then sock_nr of nwconn */ int pid; /* pid from son */ ipxAddr_t client_adr; /* address client */ int sequence; /* previous sequence */ @@ -499,6 +500,8 @@ static void handle_ncp_request(void) { if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){ int type; + int compl; + int cstat; in_len = ud.udata.len; time(&akttime); XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr))); @@ -518,6 +521,7 @@ static void handle_ncp_request(void) if (diff_time > 50) /* after max. 50 seconds */ nwserv_reset_wdog(connection); /* tell the wdog there's no need to look */ + #if !CALL_NWCONN_OVER_SOCKET if (ncprequest->sequence == c->sequence && !c->retry++) { @@ -568,13 +572,23 @@ static void handle_ncp_request(void) XDPRINTF((1,0, "GOT 0x%x connection=%d of %d conns not OK", type, ncprequest->connection, anz_connect)); + if (type == 0x5555 || (type == 0x2222 && ncprequest->function == 0x19)) { + compl = 0; + cstat = 0; + } else { + compl = 0; + cstat = 1; + } + ncp_response(0x3333, ncprequest->sequence, ncprequest->connection, - 0, /* task */ - 0xfe, /* completition */ - 0xf0, /* conn status */ + 1, /* task */ + compl, /* completition */ + cstat, /* conn status */ 0); + + #if !CALL_NWCONN_OVER_SOCKET /* here comes a call from nwbind */ } else if (type == 0x3333 @@ -615,6 +629,13 @@ static void handle_ncp_request(void) && IPXCMPNET (from_addr.net, my_addr.net)) { /* comes from nwserv */ handle_ctrl(); +#if _MAR_TESTS_ + } else if (type == 0xc000) { + /* rprinter */ + int connection = (int)ncprequest->connection; + int sequence = (int)ncprequest->sequence; + ncp_response(0x3333, sequence, connection, 1, 0x0, 0, 0); +#endif } else { int connection = (int)ncprequest->connection; int sequence = (int)ncprequest->sequence; diff --git a/net.h b/net.h index 236b1c4..0f3a863 100644 --- a/net.h +++ b/net.h @@ -36,6 +36,7 @@ #include #include #include +#include #include extern int errno; @@ -211,6 +212,18 @@ extern int errno; # define IPX_MAX_DATA 546 #endif +#ifndef DO_TESTING +# define DO_TESTING 0 +#endif + +#if !DO_TESTING +# undef _MAR_TESTS_ +#endif + +#ifndef _MAR_TESTS_ +# define _MAR_TESTS_ 0 +#endif + #ifdef LINUX # ifdef IN_NWROUTED # undef INTERNAL_RIP_SAP @@ -362,6 +375,7 @@ typedef struct S_OWN_DATA OWN_DATA; #define SOCK_RIP 0x0453 /* Routing Information Packet */ #define SOCK_NETBIOS 0x0455 /* NET BIOS Packet */ #define SOCK_DIAGNOSE 0x0456 /* Diagnostic Packet */ +#define SOCK_PSERVER 0x8060 /* Print Server's Socket */ #define SOCK_NVT 0x8063 /* NVT (Network Virtual Terminal) */ /* PACKET TYPES */ diff --git a/nwbind.c b/nwbind.c index ad24e20..e5926d2 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "08-May-96" +#define REVISION_DATE "19-Jun-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -374,20 +374,20 @@ static void handle_fxx(int gelen, int func) uint8 maxconnections[2]; uint8 connection_in_use[2]; uint8 max_volumes[2]; - uint8 os_revision; - uint8 sft_level; - uint8 tts_level; + uint8 os_revision; /* 0 */ + uint8 sft_level; /* 2 */ + uint8 tts_level; /* 1 */ uint8 peak_connection[2]; - uint8 accounting_version; - uint8 vap_version; - uint8 queuing_version; - uint8 print_server_version; - uint8 virtual_console_version; - uint8 security_level; - uint8 internet_bridge_version; + uint8 accounting_version; /* 1 */ + uint8 vap_version; /* 1 */ + uint8 queuing_version; /* 1 */ + uint8 print_server_version; /* 0 */ + uint8 virtual_console_version; /* 1 */ + uint8 security_level; /* 1 */ + uint8 internet_bridge_version; /* 1 */ uint8 reserved[60]; } *xdata = (struct XDATA*) responsedata; - int k, i; + int k, i, h; memset(xdata, 0, sizeof(struct XDATA)); strcpy(xdata->servername, my_nwname); if (!tells_server_version) { @@ -401,13 +401,30 @@ static void handle_fxx(int gelen, int func) } i=0; + h=0; for (k=0; k < MAX_CONNECTIONS; k++) { - if (connections[k].active) i++; + if (connections[k].active) { + i++; + h = k+1; + } } U16_TO_BE16(i, xdata->connection_in_use); U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections); - U16_TO_BE16(MAX_CONNECTIONS, xdata->peak_connection); + U16_TO_BE16(h, xdata->peak_connection); U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes); +#ifdef _MAR_TESTS_1 + xdata->security_level=1; + xdata->sft_level=2; + xdata->tts_level=1; + + xdata->accounting_version=1; + xdata->vap_version=1; + xdata->queuing_version=1; + + xdata->virtual_console_version=1; + xdata->security_level=1; + xdata->internet_bridge_version=1; +#endif data_len = sizeof(struct XDATA); } break; @@ -539,12 +556,8 @@ static void handle_fxx(int gelen, int func) uint8 *p = act_c->crypt_key; uint8 *pp = responsedata; data_len = k; - while (k--) *pp++ = *p++ = -#ifndef _MAR_TESTS_ - (uint8) rand(); -#else - (uint8) k; -#endif + while (k--) *pp++ = *p++ = (uint8) rand(); + /* if all here are same (1 or 2) then the resulting key is */ /* 00000000 */ if (password_scheme & PW_SCHEME_GET_KEY_FAIL) @@ -1030,7 +1043,6 @@ static void handle_fxx(int gelen, int func) } break; -#ifdef _CHANGE_PASSWD_TESTING_ case 0x4b : { /* keyed change pasword */ uint8 *p = rdata+sizeof(act_c->crypt_key); NETOBJ obj; @@ -1039,26 +1051,21 @@ static void handle_fxx(int gelen, int func) p+=2; strmaxcpy((char*)obj.name, (char*)(p+1), *p); upstr(obj.name); - p += (*p+1); /* here is now password-type ?? 0x60,0x66 */ + /* from Guntram Blohm */ + p += (*p+1); /* here is crypted password length */ if (0 == (result = find_obj_id(&obj, 0))) { - internal_act = 1; - result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); - internal_act = 0; - } -#if 0 - if (result > -1) { - internal_act = 1; - result=nw_set_enpasswd(obj.id, p+1); - internal_act = 0; - } -#endif + internal_act=1; + result=nw_keychange_passwd(obj.id, act_c->crypt_key, + rdata, (int)*p, p+1, act_c->object_id); + internal_act = 0; + } + if (result< 0) completition = (uint8) -result; - XDPRINTF((1, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", + XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", obj.name, result)); } break; -#endif case 0x4c : { /* List Relations of an Object */ XDPRINTF((1, 0, "TODO:List Relations of an Object")); diff --git a/nwconn.c b/nwconn.c index 8f0bda2..3d7b7ea 100644 --- a/nwconn.c +++ b/nwconn.c @@ -221,6 +221,9 @@ static int handle_ncp_serv(void) } break; + case 0x15 : + return(-1); /* nwbind must do this call */ + case 0x16 : { /* uint8 len = *(requestdata+1); */ @@ -330,7 +333,7 @@ static int handle_ncp_serv(void) int result = nw_get_volume_name((int)*(p+1), xdata->name); if (result > -1) { xdata->namelen = (uint8) result; - data_len = sizeof(struct XDATA); + data_len = result+1; } else completition = (uint8) -result; } else if (*p == 0xa){ /* legt Verzeichnis an */ /******** Create Dir *********************/ @@ -575,11 +578,13 @@ static int handle_ncp_serv(void) uint8 volnr = *(p+1); uint32 id = GET_BE32(p+2); struct XDATA { - uint8 weisnicht[8]; /* ?????? */ + uint8 restriction[4]; + uint8 inuse[4]; } *xdata = (struct XDATA*) responsedata; XDPRINTF((5,0, "Get vol restriction vol=%d, id=0x%lx", (int)volnr, id)); - memset(xdata, 0, sizeof(struct XDATA)); + U32_TO_32(0x40000000, xdata->restriction); + U32_TO_32(0x0, xdata->inuse); data_len=sizeof(struct XDATA); } else if (*p == 0x2a){ /* Get Eff. Rights of DIR's and Files ??*/ @@ -795,6 +800,7 @@ static int handle_ncp_serv(void) case 0x18 : /* End of Job */ nw_free_handles((ncprequest->task > 0) ? (int) (ncprequest->task) : 1); + break; case 0x19 : /* logout, some of this call is handled in ncpserv. */ @@ -1296,7 +1302,7 @@ static int handle_ncp_serv(void) break; #endif -#ifdef _MAR_TESTS_ +#ifdef _MAR_TESTS_XX case 0x5f : { /* ????????????? UNIX Client */ struct INPUT { uint8 header[7]; /* Requestheader */ @@ -1480,12 +1486,6 @@ static void set_sig(void) int main(int argc, char **argv) { -#if CALL_NWCONN_OVER_SOCKET - uint8 i_ipx_pack_typ; - ipxAddr_t x_from_addr; - ipxAddr_t client_addr; - struct t_unitdata iud; -#endif if (argc != 5) { fprintf(stderr, "usage nwconn PID FROM_ADDR Connection nwbindsock\n"); exit(1); @@ -1496,14 +1496,11 @@ int main(int argc, char **argv) init_tools(NWCONN, atoi(*(argv+3))); memset(saved_readbuff, 0, sizeof(saved_readbuff)); - XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s", father_pid, *(argv+2), *(argv+3))); + XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s", + father_pid, *(argv+2), *(argv+3))); adr_to_ipx_addr(&from_addr, *(argv+2)); -#if CALL_NWCONN_OVER_SOCKET - adr_to_ipx_addr(&client_addr, *(argv+2)); -#endif - if (nw_init_connect()) exit(1); sscanf(argv[4], "%x", &sock_nwbind); @@ -1513,6 +1510,7 @@ int main(int argc, char **argv) #endif last_sequence = -9999; if (get_ipx_addr(&my_addr)) exit(1); + #if CALL_NWCONN_OVER_SOCKET # if 1 # ifdef SIOCIPXNCPCONN @@ -1535,35 +1533,19 @@ int main(int argc, char **argv) ud.addr.maxlen = sizeof(ipxAddr_t); ud.addr.buf = (char*)&from_addr; ud.udata.buf = (char*)&ipxdata; + U16_TO_BE16(0x3333, ncpresponse->type); ncpresponse->task = (uint8) 1; /* allways 1 */ ncpresponse->reserved = (uint8) 0; /* allways 0 */ ncpresponse->connection = (uint8) atoi(*(argv+3)); -#if CALL_NWCONN_OVER_SOCKET - iud.opt.len = sizeof(i_ipx_pack_typ); - iud.opt.maxlen = sizeof(i_ipx_pack_typ); - iud.opt.buf = (char*)&i_ipx_pack_typ; /* gets actual Typ */ - - iud.addr.len = sizeof(ipxAddr_t); - iud.addr.maxlen = sizeof(ipxAddr_t); - iud.addr.buf = (char*)&x_from_addr; - - iud.udata.len = IPX_MAX_DATA; - iud.udata.maxlen = IPX_MAX_DATA; - iud.udata.buf = (char*)readbuff; -#endif - set_sig(); while (1) { -#if CALL_NWCONN_OVER_SOCKET - int rcv_flags = 0; - int data_len = (t_rcvudata(0, &iud, &rcv_flags) > -1) - ? iud.udata.len : -1; -#else int data_len = read(0, readbuff, sizeof(readbuff)); -#endif + /* this read is a pipe or a socket read, + * depending on CALL_NWCONN_OVER_SOCKET + */ ncpresponse->connect_status = (uint8) 0; if (fl_get_int) { @@ -1574,9 +1556,12 @@ int main(int argc, char **argv) if (data_len > 0) { XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len)); if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) { + /* this is a response packet */ data_len -= sizeof(NCPRESPONSE); - if (saved_sequence > -1 && ((int)(ncprequest->sequence) == saved_sequence) + if (saved_sequence > -1 + && ((int)(ncprequest->sequence) == saved_sequence) && !ncprequest->function) { + /* comes from nwbind */ handle_after_bind(); } else { /* OK for direct sending */ @@ -1589,11 +1574,15 @@ int main(int argc, char **argv) (int)(ncprequest->function), data_len); } saved_sequence = -1; - } else { /* this calls I must handle */ + } else { /* this calls I must handle, it is a request */ int result; requestlen = data_len - sizeof(NCPREQUEST); if (0 != (result = handle_ncp_serv()) ) { - if (result == -2) { /* here the actual call must be saved */ + if (result == -2) { + /* here the actual call must be saved + * because we need it later, when the request to nwbind + * returns. + */ memcpy(saved_readbuff, readbuff, data_len); saved_sequence = (int)(ncprequest->sequence); } else saved_sequence = -1; diff --git a/nwcrypt.c b/nwcrypt.c index 507ce54..eadc0b7 100644 --- a/nwcrypt.c +++ b/nwcrypt.c @@ -211,3 +211,89 @@ nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til) } +/* =========== next is from Guntram Blohm ! =============== */ +char newshuffle[256+16] = { + 0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09, + 0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a, + 0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08, + 0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07, + + 0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00, + 0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07, + 0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09, + 0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e, + + 0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00, + 0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09, + 0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c, + 0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e, + + 0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07, + 0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f, + 0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e, + 0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c, + + 0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a, + 0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09, + 0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f, + 0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09, + + 0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00, + 0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08, + 0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04, + 0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06, + + 0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b, + 0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d, + 0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c, + 0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d, + + 0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01, + 0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a, + 0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00, + 0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02, + + 0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05, + 0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08, +}; + + +int nw_decrypt_newpass(char *oldpwd, char *newpwd, char *undecr) +{ + int i, j, n; + unsigned char ch, cl; + + char invshuffle[256+16]; + char copy[8]; + + for (i=0; i<256+16; i+=16) + for (j=0; j<16; j++) + invshuffle[i+newshuffle[i+j]]=j; + + for (i=0; i<16; i++) + { + memset(copy, '\0', 8); + for (j=0; j<16; j++) + { + n=newshuffle[j+0x100]; + + ch=(j&1 ? (newpwd[j/2]>>4)&0x0f : newpwd[j/2]&0x0f); + copy[n/2]|=(n&1) ? (ch<<4) : ch; + } + + ch=(oldpwd[0]<<4); + for (j=0; j<7; j++) + oldpwd[j]=(oldpwd[j+1]<<4)|((oldpwd[j]>>4)&0x0f); + oldpwd[7]=ch|((oldpwd[7]>>4)&0x0f); + + for (j=0; j<8; j++) + { + cl=invshuffle[((copy[j] )&0x0f)+j*32 ] ; + ch=invshuffle[((copy[j]>>4)&0x0f)+j*32+16]<<4; + copy[j]=(ch|cl)^oldpwd[j]; + } + memcpy(newpwd, copy, 8); + } + memcpy(undecr, copy, 8); +} + diff --git a/nwcrypt.h b/nwcrypt.h index 3876b0b..19cee4d 100644 --- a/nwcrypt.h +++ b/nwcrypt.h @@ -1,7 +1,11 @@ -/* nwcrypt.h */ +/* nwcrypt.h 19-Jun-96 */ extern void shuffle(unsigned char *lon, const unsigned char *buf, int buflen, unsigned char *target); extern void nw_encrypt(unsigned char *fra, unsigned char *buf,unsigned char *til); + + +extern int nw_decrypt_newpass(char *oldpwd, char *newpwd, char *undecr); + diff --git a/nwdbm.c b/nwdbm.c index 0428e65..0e1573e 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 13-May-96 data base for mars_nwe */ +/* nwdbm.c 20-Jun-96 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ */ /* - * This code is only called from the process 'ncpserv' + * This code is only called from the process 'nwbind' * So, there is no need for locking or something else. */ @@ -41,8 +41,8 @@ #define DBM_REMAINS_OPEN 1 -int tells_server_version=0; -int password_scheme=PW_SCHEME_CHANGE_PW; +int tells_server_version=0; +int password_scheme=PW_SCHEME_CHANGE_PW; static datum key; static datum data; @@ -174,7 +174,10 @@ int find_obj_id(NETOBJ *o, uint32 last_obj_id) return(result); } -static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id) +static int loc_delete_property(uint32 obj_id, + uint8 *prop_name, + uint8 prop_id, + int ever) /* ever means no access tests */ /* deletes Object property or properties */ /* wildcards allowed in property name */ { @@ -191,7 +194,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id) p = (NETPROP*)data.dptr; if (p != NULL && name_match(p->name, prop_name)){ XDPRINTF((2,0, "found prop: %s, id=%d for deleting", p->name, (int)p->id)); - if (!b_acc(obj_id, p->security, 0x13)) { + if (ever || !b_acc(obj_id, p->security, 0x13)) { if ((int)(p->id) > result) result = (int)(p->id); xset[p->id]++; } else if (result < 0) result = -0xf6; /* no delete priv. */ @@ -252,7 +255,7 @@ static int loc_delete_obj(uint32 objid, int security) { int result = b_acc(objid, 0x33, 0x03); /* only supervisor or intern */ if (result) return(result); /* no object delete priv */ - (void)loc_delete_property(objid, (uint8*)"*", 0); + (void)loc_delete_property(objid, (uint8*)"*", 0, 1); if (!dbminit(FNOBJ)){ key.dptr = (char*)&objid; key.dsize = NETOBJ_KEY_SIZE; @@ -633,7 +636,7 @@ int nw_delete_property(int object_type, obj.name, prop_name_x, object_type)); obj.type = (uint16) object_type; if ((result = find_obj_id(&obj, 0)) == 0){ - result = loc_delete_property(obj.id, prop_name_x, 0); + result = loc_delete_property(obj.id, prop_name_x, 0, 0); } return(result); } @@ -875,6 +878,7 @@ int nw_obj_has_prop(NETOBJ *obj) static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) { int result = b_acc(obj->id, obj->security, 0x12); + XDPRINTF((3, 0, "create property='%s' objid=0x%x", prop->name, obj->id)); if (result) return(result); if (!dbminit(FNPROP)){ uint8 founds[256]; @@ -997,7 +1001,7 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id) if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){ struct passwd *pw = getpwnam(buff); if (NULL != pw) { - if (obj_id != 1 && pw->pw_uid == 1) + if (obj_id != 1 && !pw->pw_uid) return(NULL); /* only supervisor -> root */ pwstat.pw_uid = pw->pw_uid; pwstat.pw_gid = pw->pw_gid; @@ -1064,26 +1068,42 @@ static int crypt_pw_ok(uint8 *password, char *passwd) return( (strcmp(p, passwd)) ? 0 : 1 ); } +static int loc_nw_test_passwd(uint8 *keybuff, uint8 *stored_passwd, + uint32 obj_id, uint8 *vgl_key, uint8 *akt_key) +{ + if (nw_get_prop_val_str(obj_id, "PASSWORD", stored_passwd) > 0) { + nw_encrypt(vgl_key, stored_passwd, keybuff); + return (memcmp(akt_key, keybuff, 8) ? -0xff : 0); + } else { /* now we build an empty password */ + uint8 buf[8]; + uint8 s_uid[4]; + U32_TO_BE32(obj_id, s_uid); + shuffle(s_uid, buf, 0, stored_passwd); + nw_encrypt(vgl_key, stored_passwd, keybuff); + return(1); + } +} + + int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key) /* returns 0, if password ok and -0xff if not ok */ { - char buf[200]; - if (nw_get_prop_val_str(obj_id, "PASSWORD", buf) > 0) { - uint8 keybuff[8]; - memcpy(keybuff, vgl_key, sizeof(keybuff)); - nw_encrypt(keybuff, buf, keybuff); - return (memcmp(akt_key, keybuff, sizeof(keybuff)) ? -0xff : 0); - } else { - if (obj_id == 1) return(-0xff); - if (password_scheme & PW_SCHEME_LOGIN) { - if (!(password_scheme & PW_SCHEME_ALLOW_EMPTY_PW)) { - MYPASSWD *pw = nw_getpwnam(obj_id); - if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd)) - return(-0xff); - } + uint8 keybuff[8]; + uint8 stored_passwd[200]; + int result=loc_nw_test_passwd(keybuff, stored_passwd, + obj_id, vgl_key, akt_key); + if (result < 1) return(result); + + if (obj_id == 1) return(-0xff); /* SUPERVISOR */ + + if (password_scheme & PW_SCHEME_LOGIN) { + if (!(password_scheme & PW_SCHEME_ALLOW_EMPTY_PW)) { + MYPASSWD *pw = nw_getpwnam(obj_id); + if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd)) + return(-0xff); } - return(0); /* no password */ } + return(0); /* no password */ } int nw_test_unenpasswd(uint32 obj_id, uint8 *password) @@ -1122,7 +1142,7 @@ static int nw_set_enpasswd(uint32 obj_id, uint8 *passwd, int dont_ch) prop_name, P_FL_STAT|P_FL_ITEM, 0x44, passwd, 16); } else if (!dont_ch) - (void)loc_delete_property(obj_id, prop_name, 0); + (void)loc_delete_property(obj_id, prop_name, 0, 1); return(0); } @@ -1133,7 +1153,7 @@ int nw_set_passwd(uint32 obj_id, char *password, int dont_ch) uint8 s_uid[4]; U32_TO_BE32(obj_id, s_uid); shuffle(s_uid, password, strlen(password), passwd); -#if 1 +#if 0 XDPRINTF((2,0, "password %s->0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", password, (int)passwd[0], @@ -1159,6 +1179,53 @@ int nw_set_passwd(uint32 obj_id, char *password, int dont_ch) } +/* main work from Guntram Blohm + * no chance for unix password support here - can't get real password + * from ncp request + */ +int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, + int cryptedlen, uint8 *newpass, uint32 act_id) +{ + uint8 storedpass[200]; + uint8 keybuff[8]; + char buf[100]; + int len; + int result = loc_nw_test_passwd(keybuff, storedpass, + obj_id, cryptkey, oldpass); + + XDPRINTF((5, 0, "Crypted change password: id=%lx, oldpresult=0x%x", + obj_id, result)); + + len=(cryptedlen ^ storedpass[0] ^ storedpass[1])&0x3f; + XDPRINTF((5, 0, "real len of new pass = %d", len)); + + XDPRINTF((5, 0, "stored: %s", hex_str(buf, storedpass, 16))); + XDPRINTF((5, 0, "crypted: %s", hex_str(buf, keybuff, 8))); + XDPRINTF((5, 0, "ncp old: %s", hex_str(buf, oldpass, 8))); + + if (result < 0) { /* wrong passwd */ + if (1 == act_id) { /* supervisor is changing passwd */ + uint8 buf[8]; + uint8 s_uid[4]; + U32_TO_BE32(obj_id, s_uid); + shuffle(s_uid, buf, 0, storedpass); + nw_encrypt(cryptkey, storedpass, keybuff); + len=(cryptedlen ^ storedpass[0] ^ storedpass[1])&0x3f; + XDPRINTF((5, 0, "N real len of new pass = %d", len)); + XDPRINTF((5, 0, "N stored: %s", hex_str(buf, storedpass, 16))); + XDPRINTF((5, 0, "N crypted: %s", hex_str(buf, keybuff, 8))); + if (memcmp(oldpass, keybuff, 8)) + return(-0xff); /* if not BLANK then error */ + } else return(-0xff); + } + XDPRINTF((5, 0, "ncp new: %s", hex_str(buf,newpass, 16))); + nw_decrypt_newpass(storedpass, newpass, newpass); + nw_decrypt_newpass(storedpass+8, newpass+8, newpass+8); + XDPRINTF((5, 0, "realnew: %s", hex_str(buf,newpass, 16))); + nw_set_enpasswd(obj_id, newpass, 0); + return(0); +} + int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) /* addiert member to set, if member not in set */ { @@ -1202,6 +1269,7 @@ static void create_nw_db(char *fn, int allways) chmod(fname, 0600); } + static void add_pr_queue(uint32 q_id, char *q_name, char *q_directory, char *q_command, @@ -1342,12 +1410,13 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int shorten, int nw_fill_standard(char *servername, ipxAddr_t *adr) -/* fills the Standardproperties */ +/* fills the standardproperties */ { char serverna[MAX_SERVER_NAME+2]; uint32 su_id = 0x00000001; uint32 ge_id = 0x01000001; uint32 serv_id = 0x03000001; + uint32 pserv_id = 0L; uint32 q1_id = 0x0E000001; #if 0 uint32 guest_id = 0x02000001; @@ -1370,7 +1439,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { if (1 == what && !*sysentry) { xstrcpy(sysentry, buff); - } else if (6 == what) { /* Server Version */ + } else if (6 == what) { /* server Version */ tells_server_version = atoi(buff); } else if (7 == what) { /* password_scheme */ int pwscheme = atoi(buff); @@ -1445,27 +1514,40 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) } /* while */ fclose(f); } + if (servername && adr) { strmaxcpy(serverna, servername, MAX_SERVER_NAME); upstr(serverna); - nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, + nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, (char*)adr, sizeof(ipxAddr_t)); + +#if _MAR_TESTS_ + nw_new_obj_prop(pserv_id, serverna, 0x47, O_FL_DYNA, 0x31, + "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, + (char*)adr, sizeof(ipxAddr_t)); +#endif } if (auto_ins_user) { + /* here Unix users will be inserted automaticly as mars_nwe users */ struct passwd *pw; upstr(auto_ins_passwd); while (NULL != (pw=getpwent())) { - if ( (pw->pw_passwd[0] != '*' && pw->pw_passwd[0] != 'x') - || pw->pw_passwd[1] != '\0') { - char nname[100]; - xstrcpy(nname, pw->pw_name); - upstr(nname); - add_user(0L, ge_id, nname, pw->pw_name, auto_ins_passwd, - (auto_ins_user == 99) ? 0 : 99); + if (pw->pw_uid) { + if ( (pw->pw_passwd[0] != '*' && pw->pw_passwd[0] != 'x') + || pw->pw_passwd[1] != '\0') { + char nname[100]; + xstrcpy(nname, pw->pw_name); + upstr(nname); + add_user(0L, ge_id, nname, pw->pw_name, auto_ins_passwd, + (auto_ins_user == 99) ? 0 : 99); + } else { + XDPRINTF((1,0, "Unix User:'%s' not added because passwd='%s'", + pw->pw_name, pw->pw_passwd)); + } } else { - XDPRINTF((1,0, "Unix User:'%s' not added because passwd='%s'", - pw->pw_name, pw->pw_passwd)); + XDPRINTF((1,0, "Unix User:'%s' not added because uid=0 (root)", + pw->pw_name)); } } endpwent(); @@ -1572,7 +1654,7 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) } } dbmclose(); - while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz]); /* now delete */ + while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz], 1); /* now delete */ anz = nw_fill_standard(servername, adr); sync_dbm(); return(anz); diff --git a/nwdbm.h b/nwdbm.h index ac5818c..2e99308 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -180,6 +180,11 @@ extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key); extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password); extern int nw_set_passwd(uint32 obj_id, char *password, int dont_ch); +extern int nw_keychange_passwd(uint32 obj_id, + uint8 *cryptkey, uint8 *oldpass, + int cryptedlen, uint8 *newpass, + uint32 act_id); + extern int nw_get_q_dirname(uint32 q_id, uint8 *buff); extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff); diff --git a/nwfile.c b/nwfile.c index ba1318d..0221395 100644 --- a/nwfile.c +++ b/nwfile.c @@ -36,7 +36,7 @@ static int new_file_handle(uint8 *unixname) FILE_HANDLE *fh=NULL; while (++rethandle < anz_fhandles) { FILE_HANDLE *fh=&(file_handles[rethandle]); - if (fh->fd == -1 && !(fh->flags & 4)) { /* empty slot */ + if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */ rethandle++; break; } else fh=NULL; @@ -52,7 +52,7 @@ static int new_file_handle(uint8 *unixname) fh->offd = 0L; fh->tmodi = 0L; strcpy((char*)fh->fname, (char*)unixname); - fh->flags = 0; + fh->fh_flags = 0; fh->f = NULL; XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s", rethandle, anz_fhandles, unixname)); @@ -65,12 +65,12 @@ static int free_file_handle(int fhandle) if (fhandle > 0 && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); if (fh->fd > -1) { - if (fh->flags & 2) { + if (fh->fh_flags & FH_IS_PIPE_COMMAND) { if (fh->f) ext_pclose(fh->f); fh->f = NULL; } else close(fh->fd); - if (fh->tmodi > 0L && !(fh->flags & 2) - && !(fh->flags & FILE_IS_READONLY)) { + if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags) + && !(FH_IS_READONLY & fh->fh_flags) ) { /* now set date and time */ struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; @@ -79,11 +79,11 @@ static int free_file_handle(int fhandle) } } fh->fd = -1; - if (fhandle == anz_fhandles && !(fh->flags & 4)) { + if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* was last */ anz_fhandles--; while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1 - && !(file_handles[anz_fhandles-1].flags & 4) ) + && !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) ) anz_fhandles--; } result=0; @@ -129,9 +129,10 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, fh->f = ext_popen(pipecommand, geteuid(), getegid()); fh->fd = (fh->f) ? fileno(fh->f->fildes[1]) : -1; if (fh->fd > -1) { - fh->flags |= 2; + fh->fh_flags |= FH_IS_PIPE; + fh->fh_flags |= FH_IS_PIPE_COMMAND; if (!dowrite) stbuff->st_size = 0x7fffffff; - if (creatmode & 4) fh->flags |= 4; + if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; return(fhandle); } } @@ -162,10 +163,14 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } else { int statr = stat(fh->fname, stbuff); int acm = (access & 2) ? (int) O_RDWR : (int)O_RDONLY; - if ( (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) + if ( (!statr && !S_ISDIR(stbuff->st_mode)) || (statr && (acm & O_CREAT))){ - XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); + if ((!statr) && S_ISFIFO(stbuff->st_mode)){ + acm |= O_NONBLOCK; + fh->fh_flags |= FH_IS_PIPE; + } fh->fd = open(fh->fname, acm, 0777); + XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); fh->offd = 0L; if (fh->fd > -1) { if (statr) stat(fh->fname, stbuff); @@ -173,7 +178,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, } } if (fh->fd > -1) { - if (creatmode & 4) fh->flags |= 4; + if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; return(fhandle); } } /* else (NOT DEVICE) */ @@ -188,7 +193,7 @@ int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) if (fhandle > 0 && (--fhandle < anz_fhandles) ) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (!(fh->flags & FILE_IS_READONLY)) { + if (!(fh->fh_flags & FH_IS_READONLY)) { fh->tmodi = nw_2_un_time(datum, zeit); return(0); } else return(-0x8c); @@ -203,11 +208,11 @@ int nw_close_datei(int fhandle, int reset_reuse) fhandle, anz_fhandles)); if (fhandle > 0 && (fhandle <= anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle-1]); - if (reset_reuse) fh->flags &= (~4); + if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE); if (fh->fd > -1) { int result = 0; int result2; - if (fh->flags & 2) { + if (fh->fh_flags & FH_IS_PIPE_COMMAND) { if (fh->f) { result=ext_pclose(fh->f); if (result > 0) result = 0; @@ -215,8 +220,8 @@ int nw_close_datei(int fhandle, int reset_reuse) fh->f = NULL; } else result=close(fh->fd); fh->fd = -1; - if (fh->tmodi > 0L && !(fh->flags&2) - && !(fh->flags & FILE_IS_READONLY)) { + if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE) + && !(fh->fh_flags & FH_IS_READONLY)) { struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; utime(fh->fname, &ut); @@ -248,8 +253,17 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (fh->flags & 2) { /* PIPE */ - size = fread(data, 1, size, fh->f->fildes[1]); + if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ + if (fh->fh_flags & FH_IS_PIPE_COMMAND) + size = fread(data, 1, size, fh->f->fildes[1]); + else { + size = read(fh->fd, data, size); + if (size < 0) { + int k=5; + while (size < 0 && --k /* && errno == EAGAIN */) + size = read(fh->fd, data, size); + } + } } else { if (fh->offd != (long)offset) { fh->offd=lseek(fh->fd, offset, SEEK_SET); @@ -265,6 +279,7 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset) } } else size = -1; } + if (size == -1) size=0; return(size); } } @@ -276,7 +291,7 @@ int nw_seek_datei(int fhandle, int modus) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (fh->flags & 2) { /* PIPE */ + if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ return(0x7fffffff); } else { int size=-0xfb; @@ -297,11 +312,13 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset) if (fhandle > 0 && (--fhandle < anz_fhandles)) { FILE_HANDLE *fh=&(file_handles[fhandle]); if (fh->fd > -1) { - if (fh->flags & FILE_IS_READONLY) return(-0x94); - if (fh->flags & 2) { /* PIPE */ - if (size) - return(fwrite(data, 1, size, fh->f->fildes[0])); - return(0); + if (fh->fh_flags & FH_IS_READONLY) return(-0x94); + if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */ + if (size) { + if (fh->fh_flags & FH_IS_PIPE_COMMAND) + return(fwrite(data, 1, size, fh->f->fildes[0])); + return(write(fh->fd, data, size)); + } return(0); } else { if (fh->offd != (long)offset) fh->offd = lseek(fh->fd, offset, SEEK_SET); @@ -345,7 +362,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset, if (fhq->fd > -1 && fhz->fd > -1) { char buff[2048]; int wsize; - if (fhz->flags & FILE_IS_READONLY) return(-0x94); + if (fhz->fh_flags & FH_IS_READONLY) return(-0x94); if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { retsize = 0; @@ -384,7 +401,7 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock) if (fh->fd > -1) { struct flock flockd; int result; - if (fh->flags & 2) return(0); + if (fh->fh_flags & FH_IS_PIPE) return(0); flockd.l_type = (do_lock) ? F_WRLCK : F_UNLCK; flockd.l_whence = SEEK_SET; flockd.l_start = offset; diff --git a/nwfile.h b/nwfile.h index e5074ec..bc5dcd9 100644 --- a/nwfile.h +++ b/nwfile.h @@ -5,15 +5,20 @@ typedef struct { int fd; /* filehandle from system open/creat */ - long offd; /* aktuell file offset */ + long offd; /* actual file offset */ time_t tmodi; /* modification TIME */ FILE_PIPE *f; /* for PIPE */ - int flags; /* 2 = PIPE */ + int fh_flags; /* 2 = PIPE */ /* 4 = don't reuse after close */ /* 0x20 = readonly */ char fname[256]; /* UNIX filename */ } FILE_HANDLE; -#define FILE_IS_READONLY 0x20 + +/* fh_flags */ +#define FH_IS_PIPE 0x01 +#define FH_IS_PIPE_COMMAND 0x02 +#define FH_DO_NOT_REUSE 0x04 +#define FH_IS_READONLY 0x20 extern void init_file_module(void); diff --git a/nwqueue.c b/nwqueue.c index 5519603..56d43b1 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -159,8 +159,6 @@ int ext_pclose(FILE_PIPE *fp) waitpid(fp->command_pid, &status, 0); } kill(fp->command_pid, SIGKILL); - - signal(SIGINT, intsave); signal(SIGQUIT, quitsave); signal(SIGHUP, hupsave); diff --git a/nwserv.c b/nwserv.c index 434a881..9f7eef5 100644 --- a/nwserv.c +++ b/nwserv.c @@ -40,6 +40,10 @@ int anz_net_devices=0; NW_NET_DEVICE *net_devices[MAX_NET_DEVICES]; uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */ +#ifdef PSERVER_SLOT + ,SOCK_PSERVER +#endif + #if INTERNAL_RIP_SAP ,SOCK_SAP #else diff --git a/tools.c b/tools.c index 06471df..41fd19e 100644 --- a/tools.c +++ b/tools.c @@ -426,3 +426,12 @@ uint8 *downstr(uint8 *ss) return(ss); } +char *hex_str(char *buf, uint8 *s, int len) +{ + char *pp=buf; + while (len--) { + int i = sprintf(pp, "%02x ", *s++); + pp += i; + } + return(buf); +} diff --git a/tools.h b/tools.h index bb88d01..9362ff7 100644 --- a/tools.h +++ b/tools.h @@ -59,6 +59,7 @@ extern uint8 up_char(uint8 ch); extern uint8 *downstr(uint8 *ss); extern uint8 *upstr(uint8 *ss); +extern char *hex_str(char *buf, uint8 *s, int len); extern int nw_debug; #if DO_DEBUG