From 32780f74036d0e3c32a8b297cb134419bcf5eb94 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Sun, 13 Nov 2011 00:38:56 +0100 Subject: [PATCH] mars_nwe-0.97.pl04 --- connect.c | 58 ++++-- doc/CHANGES | 11 ++ doc/HOWTO.ger | 373 +++++++++++++++++++++++++++++++++++++ doc/INSTALL | 183 ++++++++++++------ doc/PIPE-FS | 3 - doc/README | 109 ++++++----- doc/mars_nwe.lsm | 12 +- examples/config.h | 89 +++++---- examples/nw.ini | 465 ++++++++++++++++++++++++++++++++-------------- makefile.unx | 2 +- namspace.c | 179 +++++++++++------- namspace.h | 1 + net.h | 2 +- nwbind.c | 99 ++++++---- nwconn.c | 8 + nwdbm.c | 88 +++++---- nwdbm.h | 2 - nwfile.c | 25 ++- nwfile.h | 4 +- nwroute.c | 129 ++++++------- nwserv.c | 73 ++++++-- nwvolume.c | 18 +- nwvolume.h | 5 +- tools.c | 35 ++-- 24 files changed, 1407 insertions(+), 566 deletions(-) create mode 100644 doc/HOWTO.ger diff --git a/connect.c b/connect.c index c3f0896..c41301c 100644 --- a/connect.c +++ b/connect.c @@ -808,6 +808,8 @@ static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs) XDPRINTF((5,0,"DELETE FILE unname:%s:", unname)); if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_IS_PIPE) return(0); /* don't delete 'pipe commands' */ + else if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_READONLY) + return(-0x8a); /* don't delete 'readonly' */ if (!unlink(unname)) return(0); return(-0x8a); /* NO Delete Privileges */ } @@ -828,10 +830,13 @@ static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) { char unname[256]; NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf; + int voloption; strcpy(unname, build_unix_name(nwpath, 0)); XDPRINTF((5,0,"set_file_info unname:%s:", unname)); - if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_IS_PIPE) + if ((voloption = get_volume_options(nwpath->volume, 1)) & VOL_OPTION_IS_PIPE) return(0); /* don't change 'pipe commands' */ + else if (voloption & VOL_OPTION_READONLY) + return(-0x8c); /* no modify rights */ else { struct utimbuf ut; ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time); @@ -882,7 +887,6 @@ int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus) return(-0x9c); /* wrong path */ } - int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) { NW_PATH nwpath; @@ -891,26 +895,35 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) if (completition > -1) { char unname[256]; strcpy(unname, build_unix_name(&nwpath, 2)); -#if 0 - if (unname[0] && unname[1]) { - char *p=unname+strlen(unname)-1; - if (*p=='/') *p = '\0'; - } -#endif - + if (get_volume_options(nwpath.volume, 1) & VOL_OPTION_READONLY) + return(mode ? -0x84 : -0x8a); if (mode) { XDPRINTF((5,0,"MKDIR dirname:%s:", unname)); if (!mkdir(unname, 0777)) return(0); completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ } else { /* rmdir */ + int j = -1; + while (++j < (int)anz_dirhandles){ + DIR_HANDLE *fh=&(dir_handles[j]); + if (fh->inode == completition && fh->f != (DIR*) NULL) { + closedir(fh->f); + fh->f = (DIR*)NULL; + } + } XDPRINTF((5,0,"RMDIR dirname:%s:", unname)); + if (!rmdir(unname)) { NW_DIR *d=&(dirs[0]); - int j = 0; + j = 0; while (j++ < (int)used_dirs){ if (d->inode == completition) d->inode = 0; d++; } + j = -1; + while (++j < (int)anz_dirhandles){ + DIR_HANDLE *fh=&(dir_handles[j]); + if (fh->inode == completition) free_dir_handle(j+1); + } completition = 0; } else if (errno == EEXIST) completition = -0xa0; /* dir not empty */ @@ -926,14 +939,15 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, NW_PATH quellpath; NW_PATH zielpath; int completition=conn_get_kpl_path(&quellpath, qdirhandle, q, qlen, 0); - if (!completition > -1){ + if (!completition > -1) { completition=conn_get_kpl_path(&zielpath, zdirhandle, z, zlen, 0); if (completition > -1) { - if (get_volume_options(quellpath.volume, 1) & - VOL_OPTION_IS_PIPE || - get_volume_options(zielpath.volume, 1) & - VOL_OPTION_IS_PIPE) - completition = -0x9c; + int optq = get_volume_options(quellpath.volume, 1); + int optz = get_volume_options(zielpath.volume, 1); + if ((optq & VOL_OPTION_IS_PIPE) || + (optz & VOL_OPTION_IS_PIPE)) completition = -0x9c; + else if ((optq & VOL_OPTION_READONLY) || + (optz & VOL_OPTION_READONLY)) completition = -0x8b; } if (completition > -1){ char unquelle[256]; @@ -942,7 +956,7 @@ int mv_file(int qdirhandle, uint8 *q, int qlen, strcpy(unziel, build_unix_name(&zielpath,0)); if (!link(unquelle, unziel)){ if (unlink(unquelle)) { - completition=-0x9c; + completition=-0x8b; /* TODO: here completition must be no pernmissions */ unlink(unziel); } @@ -968,9 +982,12 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, memcpy(&zielpath, &quellpath, sizeof(NW_PATH)); strmaxcpy(zielpath.fn, z, zlen); if (completition > -1) { - if (get_volume_options(quellpath.volume, 1) & - VOL_OPTION_IS_PIPE) - completition = -0x9c; + int optq = get_volume_options(quellpath.volume, 1); + int optz = get_volume_options(zielpath.volume, 1); + if ((optq & VOL_OPTION_IS_PIPE) || + (optz & VOL_OPTION_IS_PIPE)) completition = -0x9c; + else if ((optq & VOL_OPTION_READONLY) || + (optz & VOL_OPTION_READONLY)) completition = -0x8b; } if (completition > -1){ int result; @@ -978,6 +995,7 @@ int mv_dir(int dir_handle, uint8 *q, int qlen, char unziel[256]; strcpy(unquelle, build_unix_name(&quellpath, 0)); strcpy(unziel, build_unix_name(&zielpath, 0)); + result = unx_mvdir((uint8 *)unquelle, (uint8 *)unziel); XDPRINTF((2,0, "rendir result=%d, '%s'->'%s'", result, unquelle, unziel)); diff --git a/doc/CHANGES b/doc/CHANGES index 95fbc3e..48f7dda 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -120,4 +120,15 @@ Erste 'oeffentliche' Version - Parameter -k fuer SIGTERM und -h fuer SIGHUP eingebaut. - eigene 'pipe' Routine fuer Druck Queue Aufruf eingebaut. - namespace services call rename file/dir eingebaut. +<----- ^^^^^^^^^^ pl3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- utmp/wtmp Ipx-Adresseintraege korrigiert. +- setgroups(0,NULL) in nwserv eingbaut. (security) +- falls internal net = 0 wird nun die IP Nummer als internal net verwendet. +- Zugriffsrechte Bindery erweitert und korrigiert. +- Volume option -r fuer readonly eingebaut. + + + + + diff --git a/doc/HOWTO.ger b/doc/HOWTO.ger new file mode 100644 index 0000000..87493e0 --- /dev/null +++ b/doc/HOWTO.ger @@ -0,0 +1,373 @@ +Dieses HowTo ist noch unfertig. + +Aktuelle Version erhaeltlich bei: +Hardy Buchholz + + +ALLGEMEINES +^^^^^^^^^^^ + +MARS_NWE ist ein frei erhaeltlicher Netware-Emulator fuer Linux. +(auch fuer Unixware) + + +IPX +^^^ + + +QUICKINST (fuer alle Ungeduldigen und Wiederholungstaeter ;-) +^^^^^^^^^ +1. "make" aufrufen. +2. "config.h" evtl. anpassen. +3. "make" aufrufen. +4. "nw.ini" zum Konfigurieren des Servers bearbeiten. +5. "make install" (und dann "make install_ini" wenn neue Konf-Datei). +6. "nwserv" starten, MsDOS | WIN | WfW | WIN95 | OS/2-Clients starten, + einloggen, Spass haben ;-) + + +Und wenns dann doch nicht funktioniert: + +INSTALLATION +^^^^^^^^^^^^ + +Kernel +^^^^^^ +Voraussetzung um MARS_NWE laufen zu lassen ist ein Kernel mit +IPX-Option. Grundsaetzlich sollte der MARS_NWE unter allen neueren +Kernelversionen nutzbar sein. Die Kernelpatches aus dem Verzeichniss +"mars_mwe/examples" sind keine Vorraussetzung, steigern die +Performance des Servers aber ganz erheblich (ca. 30-40%). Weiter wird +dringend empfohlen, die Option FULL_INTERNAL_NET in der +Kernel-Konfiguration auf NEIN zu setzen. Sind die genannten +Bedingungen erfuellt, steht der Installation vom MARS_NWE von der +Linux-Seite nichts mehr im Weg, andernfalls sollte zuerst ein neuer +Kernel erzeugt (IPX = Y, FULL_INTERNAL_NET = N, Patch eingespielt?) +und Linux neu gebootet werden. + + +Novell +^^^^^^ +Im Augenblick (Mai 96) werden noch einige Novell-Dateien benoetigt, um +sich z.b. auf dem Server anzumelden, Printqueues einzurichten etc. +Ausserdem muss ein Verzeichniss existieren, dass spaeter als Volume +"SYS" genutzt werden kann. Als minimale Dateien werden "LOGIN.EXE", +"CAPTURE.EXE", "MAP.EXE" und vielleicht noch "SYSCON.EXE" gebraucht. +In allernaechster Zukunft sollte es von Martin Stover auch die +"mars_dosutils" geben, so dass auf die Novell-Files verzichtet werden +kann. Damit ist dann ein vollwertiger Netware-kompatibler Server als +Freeware fuer Linux verfuegbar. Die Novell-Unterverzeichnisse "LOGIN", +"PUBLIC", "SYSTEM" und "MAIL" werden beim ersten Aufruf von "nwserv" +automatisch erzeugt (dafuer sollte der Eintrag 16 in der +"nw.ini/nwserv.conf" auf 1 bleiben). Man kann also mars_nwe, nachdem +in der nwserv.conf Datei der SYS Eintrag bearbeitet wurde, erstmal +einmal starten und dann per Client versuchen einen attach zu erhalten. +Der Client muss dann ein leeres LOGIN Verzeichnis bzw. Volume (bei +vlms) vorfinden. Dann sollte sich der Client mit einem extern +gestarteten LOGIN.EXE oder entsprechendem aus mars_dosutils auf dem +Server als Supervisor einloggen und die benoetigten Dateien ins LOGIN +Verzeichniss kopieren. Dieses hat den Vorteil, dass die Dateien in der +richtigen Schreibweise gross bzw. klein in das Verzeichnis kopiert +werden. Dateinamen die nicht in das Dos-Schema passen, oder +irrtuemlich in Gross- und Kleinschreibung gemischt wurden, sind +spaeter fuer den Client schlicht nicht sichtbar (waere z.b. bei LOGIN. +EXE nicht so schoen, wenns unsichtbar bliebe ;-). + + +Directories +^^^^^^^^^^^ +Wie bereits gesagt muss wenigstens ein Verzeichniss mit der +Novell-Directory-Struktur existieren, wofuer der "nwserv" aber mit +Eintrag 16=1 in der nwserv.conf selbst sorgt. Daneben wird ein oder +mehrere Verzeichnisse gebraucht, die als Uebergabeverzeichnisse fuer +die Printqueues und eventuell eingerichtete Pipe-Dateien dienen. +Letztere koennen aber jederzeit nachtraeglich angelegt und auch neu +konfiguriert werden, unverzichtbar ist nur das Verzeichniss mit den +Novell-Directories, dass spaeter als Volume SYS freigegeben wird. +Generell ist es bestimmt keine schlechte Idee, alle Verzeichnisse und +Files, die fuer die Clients sichtbar sein sollen, gross zu schreiben. + + +MARS_NWE +^^^^^^^^ +Die aktuelle Version vom MARS_NWE auspacken, was jetzt wohl schon +passiert ;-) ist. Wenn alles komplett ist, gibts jetzt die +Verzeichnisse "mars_nwe", "mars_nwe/examples" und "mars_nwe/doc". Im +doc-Verzeichniss sind ein paar Texte zum MARS_NWE und im +examples-Verzeichniss finden sich u.a. die bereits besprochenen +Patches. Hat bisher alles geklappt, kann jetzt der erste "make" +aufgerufen werden. Damit werden die Dateien "mk.li" und "config.h" +erzeugt. "mk. li" ist ein Scriptfile, mit dessen Hilfe der "make" fuer +Linux angepasst wird und braucht fuer Linux normalerweise nicht +veraendert werden, die "config.h" (die eigentliche Konfigurationsdatei +fuer "make" und den Compilerlauf) sollte aber wenigstens kontrolliert +werden. +Im Einzelnen kann man hier Folgendes einstellen: +Mit DO_DEBUG wird gesteuert, ob der Debugging-Code mit compiliert +werden soll. Generell ist besser mit debug-code, denn der Debug-Level +kann dann spaeter ueber die nwserv.conf eingestellt werden. +Abhaengig vom Eintrag DO_TESTING wird der MARS_NWE nur local (im +aktuellen Verzeichniss) oder endgueltig installiert. +Die meisten folgenden Eintraege sind selbsterklaerend (MAX_CONNECTIONS +...). Um MARS_NWE mit ncpfs oder WIN95 zu betreiben sollte +WITH_NAMESPACE_CALLS = 1 gesetzt werden. +INTERNAL_RIP_SAP ist standard auf 1, soll der MARS_NWE aber nur als +Server und nicht als Router eingesetzt werden, muss es auf Null +gesetzt werden, dann muss aber auch das Routing von Hand eingerichtet +werden und es wird ein externer RIP/SAP Daemon benoetigt. Wenn dieser +Define auf Null gesetzt ist, wird beim compilieren ein tool namens +"nwrouted" erzeugt. Dies ist der Routingund IPX-Konfigurationsteil aus +MARS_NWE. Er kann z.B. verwendet werden, wenn Linux normalerweise ohne +MARS_NWE lauft, IPX-Routing aber (z.B. fuer Linux als IPX-Client) +gebraucht wird, bzw. wenn MARS_NWE nur ab und zu, dass Routing aber +generell fuer Clients benoetigt wird. + +Grundsaetzlich kann MARS_NWE auf zwei Arten eingerichtet werden: + +1.Man kann alle Routen "von Hand" anlegen und MARS_NWE nur als Server +einsetzen. Hat natuerlich den Nachteil, dass man selbst fuer korrektes +IPX-Routing und richtige Einstellung der Internal-Net Nummern etc. +sorgen muss, bzw. dass zusaetzliche Programme wie ipx-configure, ipxd +usw. benoetigt werden. In mars_nwe/config.h muss folgende Zeile +vorhanden sein: +#define INTERNAL_RIP_SAP 0 +Wie schon gesagt, wird dabei ab Version 0.97-PL3 der "routed" erzeugt. + +2. +(Der Standard-Modus) MARS_NWE legt alle Routen selbst, man kann die +entsprechenden Devices in der Conf-Datei bestimmen und der MARS_NWE +arbeitet als RIP/SAP-Router (z.B. auch ueber ISDN...). Es werden keine +zusaetzlichen Tools wie IPX_Configure etc. benoetigt. + +Sind alle Defines gesetzt, kann der zweite make gestartet werden. +Damit werden die Binaries "nwserv", "ncpserv", "nwbind", "nwconn" und +"nwclient" erzeugt (wenn INTERNAL_RIP_SAP=0 war auch "nwrouted"). +Bevor der MARS_NWE endgueltig installiert wird, sollte jetzt die +"nw.ini" bearbeitet werden. Diese wird vom anschliessenden "make +install" ins "/etc/"-Verzeichniss unter dem Namen "nwserv.conf" +kopiert und ist die eigentliche Konfigurationsdatei fuer den MARS_NWE. +Sollte bereits eine "nwserv.conf" im "/etc"-Verzeichniss liegen, wird +diese nicht automatisch ueberschrieben. Will man, dass die +"nwserv.conf" mit der neuen "nw.ini" ueberschrieben wird (z.B. beim +Wechseln auf eine neue MARS_NWE-Version, so muss noch ein "make +install_ini" durchgefuehrt werden. +Die "nwserf.conf" kann jederzeit nachtraeglich bearbeitet werden, +viele Einstellungen koennen mit dem Aufruf "nwserv -h" in den +laufenden Server uebernommen werden. Die Eintraege sind nummeriert, +alles nach einem "#" ist Kommentar und wird ignoriert. Die Eintraege +und ihre Bedeutung sind kurz in der "nwserv.conf" selbst kommentiert. +Im Detail wird die "nwserv.conf" weiter unten besprochen. Fuer einen +ersten Testlauf sollten die Eintraege 1,3,4, und 12 unbedingt +kontrolliert oder geaendert werden. Nachdem das passiert ist, wird der +"make install" aufgerufen, um die Binaries und die "nwserf.conf" zu +installieren. +Ist alles fehlerfrei durchgelaufen (ein paar Warnings beim +Compilerlauf zaehlen nicht ;-), kann der "nwserv" zum testen +aufgerufen werden. Danach sollten mit "ps" drei Prozesse sichtbar sein +(etwa folgendermassen): + +<-------------------- schnipp ---------------------------------------> + 1132 psf 1 < 0:00 nwserv + 1133 psf 1 N 0:00 nwbind NWE_SERVER 22.22.22.22:0.0.0.0.0.1:4.51 4001 + 1134 psf 1 N 0:00 ncpserv NWE_SERVER 22.22.22.22:0.0.0.0.0.1:4.51 4001 + 1136 pP8 1 N 0:00 ps +<-------------------- schnipp ---------------------------------------> + +Passiert ist folgendes: +Der Hauptprozess "nwserv" ruft die beiden Prozesse "nwbind" und +"ncpserv" auf ("ncpserv" lauert auf eventuell startende IPX-Clients). +Die Parameter hinter den beiden Prozessen nwbind und ncpserv haben +folgende Bedeutung: + +NWE_SERVER: Der Name, der in den nw.ini (nwserv.conf) als + SERVER-Name angegeben wurde (Eintrag Nr.2), + oder falls nichts eingegeben wurde der Unix- + Hostname. + +22.22.22.22 Internal-Net Nummer des Servers. + +0.0.0.0.0.1 Node-Nummer des Servers. + +4.51 Socket-Nummer. + +4001 Socket, ueber den die Prozesse miteinander kom- + munizieren + +Es hat also keinen Sinn, "nwbind" oder "ncpserv" als eigenstaendige +Programme aufzurufen! + +Ein "cat /proc/net/ipx*" sollte jetzt in etwa folgendes zeigen: + +<-------------------- schnipp ---------------------------------------> +ipx: +Local_Address Remote_Address Tx_Queue Rx_Queue State Uid +22222222:4000 Not_Connected 00000000 00000000 07 000 +22222222:0452 Not_Connected 00000000 00000000 07 000 +22222222:0453 Not_Connected 00000000 00000000 07 000 +22222222:4001 Not_Connected 00000000 00000000 07 000 +22222222:0451 Not_Connected 00000000 00000000 07 000 +22222222:4002 Not_Connected 00000000 00000000 07 000 +22222222:4003 Not_Connected 00000000 00000000 07 000 +ipx_interface: +Network Node_Address Primary Device Frame_Type +22222222 000000000001 Yes Internal None +0000000A 0000E8037ECC No eth0 802.3 +0000AFFE FCFCAC100101 No isdn2 EtherII +ipx_route: +Network Router_Net Router_Node +0000AFFE Directly Connected +0000000A Directly Connected +22222222 Directly Connected +<-------------------- schnipp ---------------------------------------> + +Die "ipx_interfaces" sind in diesem Beispiel eine Ethernetkarte (eth0) +und ein ISDN-Interface (auch das geht!). Das erste "Interface" ist der +Server mit seiner Internal-Net Nummer. "ipx_route" zeigt die aktuellen +Netzwerk-Routen, die vom nwserv verwaltet werden, d.h. die beiden +Netzwerke 0000AFFE und 0000000A sind augenblicklich erreichbar. "ipx" +zeigt die Sockets auf denen der Server lauscht. Meldet sich nun ein +IPX-Client auf dem Netz (Start von NETX oder mit VLM), so wird fuer +jeden Client ein Prozess "nwconn" gestartet, der die Connection +verwaltet. Wenn der Client erkannt wurde und alles funktioniert hat, +dann zeigt ein "ps" unter anderem folgendes: + +<-------------------- schnipp ---------------------------------------> + 51 psf 5 < 0:00 /sbin/nwserv + 53 psf 5 N 0:00 nwbind NWE_SERVER 22.22.22.22:0.0.0.0.0.1:4.51 4001 + 54 psf 5 N 0:00 ncpserv NWE_SERVER 22.22.22.22:0.0.0.0.0.1:4.51 4001 + ... +342 psf 5 N 0:00 nwconn 54 0.0.0.a:0.20.cb.0.1a.e8:40.3 1 4001 +<-------------------- schnipp ---------------------------------------> + +Hier ist ein Client dazugekommen mit folgenden Daten: + +Netzwerk-Nummer (nicht Internal-Net): 0.0.0.A +Kartennummer (Physikalisch): 0.20.cb.0.1a.e8 +Socket-Nummer: 40.3 +Connection Nummer: 1 +Die letzte Nummer (4001) ist eine MARS_NWE interne Socketnummer. + +Auf der Client-Seite sollte jetzt der Server mit SLIST sichtbar sein: + +<-------------------- schnipp ---------------------------------------> +Known NetWare File Servers Network Node Address Status +-------------------------- ------- ------------ ------ +NWE_SERVER [22222222][ 1]Default + +Total of 1 file servers found +<-------------------- schnipp ---------------------------------------> + +Auch die Dateien im Verzeichniss SYS:\LOGIN des Servers sollten jetzt +sichtbar sein (wenn nicht, ist moeglicherweise die Option "k" gesetzt +und die File-Namen sind auf der Linux-Seite grossgeschrieben oder +umgekehrt?. Siehe auch Kapitel Novell, weiter oben). + + +NWSERV.CONF + +Die Datei "nw.ini" ist waerend der Installation als Vorlage fuer die +eigentliche Konfigurationsdatei "nwserv.conf" angelegt und bearbeitet +worden. Alle relevanten Einstellungen des MARS_NWE (ausser den +Compilereinstellungen in der "config.h") werden hier vorgenommen. +Einige davon koennen sogar waehrend der Laufzeit des Servers mittels +"nwserv -h" uebernommen werden. +In letzter Zeit hat Winfried Truemper die Kommentare ueberarbeitet und +erweitert, so dass viele Parameter jetzt in der Datei selber erklaert +werden. +Hier sollen nur ein paar Einstellungen diskutiert werden, die immer +wieder Fragen aufwerfen: +Mindesten ein Eintrag 1 (Volumes) muss vorhanden sein. Wie +schon im Kapitel Novell gesagt, gibt es auf Netware-Servern eine +minimale Directory-Struktur die aus den Verzeichnissen "LOGIN", +PUBLIC, "SYSTEM" und "MAIL" besteht, und in der standardmaessig +bestimmte Dateien (Login-Scripte, Map-, Capture- und Login-Commands +etc.) abgelegt sind. Damit der Client auf den Server Zugreifen kann +muessen diese also vorhanden sein. Mit Eintrag 16=1 werden diese beim +ersten Start von "nwserv" angelegt. Der Volume-Name ist ueblicherweise +"SYS". +Beim Anlegen und Eintragen der Optionen fuer das Volume SYS unbedingt +auf Gross- und Kleinschreibung achten, sonst sind diese Dateien +nachher fuer den Client nicht Sichtbar. Alle weiteren Volumes sind +Optional und koennen beliebige Verzeichnisse (ausser /) freigeben. +Auf Verzeichniss "/" hat nur der root=Supervisor Zugriff. Volumes +koennen mit NFS gemountete Verzeichnisse, CD-Roms, Floppys und +beliebige unter Linux mountbare Filesystems sein. Die einzige +Einschraenkung besteht in der Beschraenkung auf entweder alles gross +oder klein geschrieben und der Dos-Namensgebung fuer die Files +(xxxxxxxx.xxx). +Eine Besonderheit sind beim MARS_NWE die sogenannten PIPE-Volumes. +Hier koennen spaeter Shell-Scripte abgelegt werden, auf die vom +Dos-Client aus lesend und schreibend zugegriffen werden kann (siehe +PIPE-Volumes, weiter unten). +Eintrag 3 ist fuer die Internal-Net Nummer. Diese ist nur fuer den +Server und muss einmalig im gesamten Netzwerk sein. Mit einer Null als +Eintrag, wird die IP-Nummer des Linux-Hosts genommen, die ja +ueblicherweise einmalig im Netz ist. Die Node-Nummer ist bei +Netware-Servern 1, sollte also auch hier nicht anders eingestellt +werden. Die Internal-Net Nummer einzurichten ist zwingend notwendig +wenn der Server auch als Router arbeiten soll (mehr als ein +Net-device), oder mehr als ein Server im Netz aktiv ist, sollte aber +generell geschehen. +Bei Netware gibt es zwei Typen von Netzwerknummern, die interne und +externe Netzwerknummer. Die hier eingestellte interne wird verwendet, +damit nur solche Pakete vom Server empfangen werden, die auch direkt +fuer ihn bestimmt sind. Wenn mehrere Net-devices im Server +konfiguriert sind, dann uebernimmt der Server automatisch +Routing-Aufgaben. In diesem Fall sollen Pakete, die nicht fuer den +Server bestimmt, sind ja nur weitergeleitet werden. Die in der +Netzwerkkarte enthaltene physikalische Netzwerknummer ist daher +natuerlich ungeeignet. +Die Server unterscheiden sich aus Sicht der Arbeitsstationen nur durch +ihre interne Netznummer, Pakete werden von den Clients nur an diese +geschickt, der Server adressiert seine Paeckchen an den Client mit +Absender = interne Netznummer und Empfaenger = externe Netznummer. Die +externe Netzwerkadresse (in Eintrag 4) muss nun mit der Netzwerknummer +des LAN's uebereinstimmen, das an das hier konfigurierte Device +angeschlossen ist. Der Frame-Typ muss natuerlich auch mit dem +uebereinstimmen, der auf diesem LAN gueltig ist (Standard bei +Netware-Netzen ist meist 802.3, 802.2 ist bei einigen neueren (Netware +3.12 ..) zu finden. +Neuerdings kann in der "nwserv.conf" auch ein Autodetect der +Net-Devices eingestellt werden. Dies kann natuerlich nur +funktionieren, wenn an diesem Device mindestens ein anderer +Netware-Server haengt, der korrekt eingerichtet ist, damit vom +MARS_NWE die externe Netzwerknummer und der Frame-Typ vom laufenden +Datenverkehr abgeleitet werden kann. +Eintraege 7 - 13 legen die Securety- und Login-Details fest. Als +Besonderheit bei Eintrag 7 gilt: auch wenn die 8 (allow empty passwds) +eingetragen ist, muss der Supervisor ein Passwort haben (zumindest, +wenn der Root auf dem Linux-Rechner eines hat). Die Optionen fuer +Eintrag 7 (Passwd-Handling) sind hirarchisch gestaffelt, wobei die +Null nur verschluesseltes Passworthandling zulaesst, und damit die +sicherste Variante darstellt. Die unter 12 und 13 einzutragenden +Usernamen und Passworte werden beim ersten Start von "nwserv" in die +Bindery-Dateien (*.pag und *.dir-Files in /etc/) eingetragen. Danach +koennen (und sollten in der Praxis auch) diese Eintraege wieder aus +der "nwserv.conf" entfernt werden. + + + +FILE-SERVICES +^^^^^^^^^^^^^ + +PINT-QUEUES +^^^^^^^^^^^ + +PIPE-VOLUMES +^^^^^^^^^^^^ + +CLIENTS INSTALLIEREN +^^^^^^^^^^^^^^^^^^^^ + +FAQ's +^^^^^ + + +TIPS UND LESESTOFF +^^^^^^^^^^^^^^^^^^ + +EMAIL-ADRESSEN +^^^^^^^^^^^^^^ + + + diff --git a/doc/INSTALL b/doc/INSTALL index 68f5048..02b6168 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -1,70 +1,133 @@ -=========> !! important NOTE !! -You can configure mars_nwe in two ways. -1. You want mars_nwe to handle routing/sap and configuring - ipx-interfaces. This is the default mode. - You do not need any other ipx-tool or routers/daemons. - In this modus the correct coexisting working - of mars_nwe, dosemu, ncpfs or Caldera's nwclient was tested. --> you must use kernel < 1.3.60 or use kernel >= 1.3.60 and compile - your kernel with IPX-option CONFIG_IPX_INTERN=N - This do NOT mean 'no internal net' but 'no *full* internal net'. - In mars_nwe/config.h there must exist the following line: - #define INTERNAL_RIP_SAP 1 - If you have other IPX/NCP servers in your net you can let - your external nets configured automaticly. - To do this you must use internal net: entry '3' must be filled - with a *UNIQUE* NetNumber and you must place minimal one - entry '4' with '0' as networknumber, device = '*' and frame=auto. - example for conf/ini file: (see also examples/nw.ini): - 3 0x77777 # UNIQUE network number for internal net. - 4 0x0 * AUTO # autocreat Interfaces +This is the file "INSTALL", a step-by-step guide on how to install +the mars_nwe-package. + +(1) Get a 'good' ipx-kernel-version and compile + it with IPX-support, but no full internal net. You can do + this by answering the following questions when running + "make config": + + The IPX protocol (CONFIG_IPX) [N/m/y/?] y + Full internal IPX network (CONFIG_IPX_INTERN) [N/y/?] n + + For general questions about how to compile a kernel, + please see the Linux Kernel-HOWTO. + Best kernels for mars_nwe are 1.3.57 + (with little patch from example directory) + or kernels >= 1.3.60. + Older kernels will sometimes not work because of + bugs in the ipx-code. See examples directory for + some patches. + +(2) Decide, if mars_nwe should initialize your IPX-subsystem, + make routing and handle sap/rip or if you want to do this + with 3rd party products by hand. + Before mailing problems with mars_nwe please try the first. + +(2a) Configuration of the IPX-subsystem by "mars_nwe" + + You do not need any other ipx-tool or routers/daemons + in this case. + It was tested that "mars_nwe", "dosemu", "ncpfs" or + Caldera's "nwclient" do coexist friendly in this case. - If there is no other IPX/NCP Server on your net then - network number in entry '4' can be any number. - 4 0x10 eth0 ethernet_ii # eth0 device with network number '0x10' - # and frame ETHERNET_II. - 4 0x20 eth0 802.3 # eth0 device with network number '0x20' - # und frame ETHERNET_802.3. + Set INTERNAL_RIP_SAP to "1" in `mars_nwe/config.h': -2. You want to run mars_nwe only as a fileserver and use - special tools to configure ipx and rip/sap routers. --> In this mode you must use tools like ipx-configure and - ripd to configure ipx-interfaces, routes and handle rip/sap. - In mars_nwe/config.h there must exist the following line: - #define INTERNAL_RIP_SAP 0 + #define INTERNAL_RIP_SAP 1 -=========> create programs -1. call make. -2. perhaps you must modify mk.li and config.h -3. call make -=========> configure -modify nw.ini ! -IMPORTANT !! -Please read examples/nw.ini if you use a new version -of mars_nwe and make the needed changes to your -'ini' or 'conf' file. -=========> install -"make install" -"make install_ini" to overwrite your old _installed_ ini. + If you have other IPX/NCP servers on your local net you + can let "mars_nwe" choose TRV ("the right values"(tm)) + for you. + You request this with the following entries in `nwserv.conf': -=========> start programs -call nwserv ( as root !! ) -tested with Linux Version 1.2.13 and 1.3.32 and higher -the linux-kernel must be configured with IPX=Y. -ipx-interface and ipx-routes are setup by the program if the -entry 4 (devices) in the nw.ini file is filled. + 3 0x0 # use your IP number for internal net. + 4 0x0 * AUTO # autocreat Interfaces + + Make sure that no other server is using your internal net number + as it's networknumber. + + If there is no other IPX/NCP Server on your net then the network- + number from section '4' can be any number. + + 4 0x10 eth0 ethernet_ii # eth0 device with network number '0x10' + # and frame ETHERNET_II. + 4 0x20 eth0 802.3 # eth0 device with network number '0x20' + # und frame ETHERNET_802.3. + + +(2b) Manual configuration of the IPX-subsystem + + In this mode you must use tools like ipx-configure and + ipxd to configure ipx-interfaces, routes and handle rip/sap. + + Set INTERNAL_RIP_SAP to "0" in `mars_nwe/config.h': + + #define INTERNAL_RIP_SAP 0 + + +(3) Compile the programs from the mars_nwe-package + + Unpack the source of "mars_nwe" and change to the directory + `mars_nwe' (you already did that, otherwise you won't read this). + Enter the command: + + make + + This will create the file `config.h' and 'mk.li'. + Edit them to suit your needs. 'mk.li" only needs to be altered under + very rare conditions or if you have problems with compiling/linking + this package. + + Now run "make" again: + + make + + +(4) Edit the configuration-file `nw.ini'. + + Make sure you have all required sections included in your old + configuration-file, if you upgrade to a new version of "mars_nwe". + + +(5) Install everything + + Just say + + make install + and perhaps + make install_ini + + The later is only if you want to _overwrite_ the already installed + versions of the configuration-file "nwserv.conf" by the "nw.ini" file. + + +(6) Create the directories visible to DOS-clients + + At least the volume "SYS" must be defined in the configuration-file + "nwserv.conf". Create the associated directory if it does not + already exists and place the programs "login.exe" and "slist.exe" + into the "LOGIN" directory. You also can use the free mars_dosutils + with a poor version of these programms. + +(7) Fire it up + + As root, execute the command + + nwserv + + +(8) Stop programs (server down) + + If nwserv isn't daemonized, then the server can be stopped + with ^C, otherwise the server must be shut down with a + kill of nwserv or with starting 'nwserv -k' or with the + right dos client programm (fconsole server down) as supervisor. + Entry 210 in the nw.ini file gives the time in seconds, before + the server really shuts down. -=========> stop programs (server down) -If nwserv isn't daemonized, then the server can be stopped -with ^C, otherwise the server must be shut down with a -kill of nwserv or with the right dos client programm -(fconsole server down) as supervisor. Entry 210 in the -nw.ini file gives the time in seconds, before the server -really shuts down. good luck :-) -Martin -(mstover@freeway.de) +Martin Stover + diff --git a/doc/PIPE-FS b/doc/PIPE-FS index e65674e..107d711 100644 --- a/doc/PIPE-FS +++ b/doc/PIPE-FS @@ -65,6 +65,3 @@ I would appreciate hearing about further documented applications of the PIPE filesystem or suggestions for other ways of using it. Martin - -(translated by Michael Beddow) - diff --git a/doc/README b/doc/README index 5f825a7..9d69009 100644 --- a/doc/README +++ b/doc/README @@ -1,70 +1,79 @@ -(C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany -to compile and install, please read INSTALL ! +mars_nwe - Martin Stovers netware emulation +Copyright (C) 1993,1996 Martin Stover, Marburg, Germany -This is a little try to emulate some functions from -a NOVELL-SERVER under UNIX (LINUX). -The first version I have written 1993 on a USL1.1 -with TLI-Code. -1994 I have ported it to LINUX. This was easy, because -I only have to write a small TLI->SOCKET emu. -Unfortunately I had no full description of the NCP-calls, -so many of the calls based on trying. :-( +Help on how to compile and install can be found in `INSTALL'. -WARNING: this code has still many BUG's !! -BINDERY: this are the *.pag and *.dir files. - These files are generated by the first starting - of mars_nwe and are filled with the minimal - needed Objects and Properties. - The User SUPERVISOR must be described in the - nw.ini file, entry 12 +"mars_nwe" is an attempt to emulate the basic functionality +of a netware-server under UNIX (Linux). +The first version was written 1993 on a USL1.1 with TLI-Code. +1994 I ported it to LINUX, which was easy because I only had +to write a small TLI->SOCKET emulation (see the modul +"emutli"). -NETWORK: If there is a real Novell-Server on the - same net-line, then the NETWORK Number of - the network device in nw.ini should match - the NETWORK Number of the Novell-Server. +Unfortunately I had no complete description of the NCP-calls, +so that the handling of many calls is based on experiments. :-( -LINUX -KERNEL: the only linux-kernel depending files - are emutli.[hc]. +WARNING: this code still has many BUG's! -short description of the processes. -1) nwserv : the main program.Initiates all and starts 'ncpserv'. - sends broadcasts, wdogs, sap and rip packets. - If nwserv is started with a parameter, then the simple - test client 'nwclient', only for debugging, is started. +BINDERY: + These are the *.pag and *.dir files. + They are generated by the first starting + of mars_nwe and are filled with the minimal + needed Objects and Properties. + The User SUPERVISOR must be described in the + nw.ini file, entry 12 -2) ncpserv: opens NCP-Socket and handles NCP-Requests. - When there comes NCP-Request 0x1111 (Get Connection Nr) - then there will be started a new process 'nwconn'. - Every client-ncp-request reaches nwconn over - ncpserv. +NETWORK: + If there is a real Novell-Server on the + same net-line, then the NETWORK Number of + the network device in nw.ini should match + the NETWORK Number of the Novell-Server. -3) nwconn: will be started for every connection. Is connected - to ncpserv with a pipe. +LINUX KERNEL: + the only linux-kernel depending files + are emutli.[hc]. -Problems and TODO: -Many:-( -Here is a short list. -o - password changings from clients -o - make routing better. -o - making printing better. -o - clean the code !!! -o - make bindery code more complete. -o - and much more ... +Short description of the programs from this package: +---------------------------------------------------- + +nwserv: + the main program. Initiates all subsystems and + starts 'ncpserv'. + Sends broadcasts, wdogs, sap and rip packets. + If nwserv is started with the parameter 'y', then the simple + test client 'nwclient', only for debugging, is started. + Parameter '-k' is for stopping the actual running nwserv + and parameter '-h' for sending a HUP signal to the + running nwserv. + +ncpserv: + opens NCP-Socket and handles NCP-Requests. + For every incoming NCP-Request 0x1111 (Get Connection Nr) + a new instance of 'nwconn' ist started. + Every client-ncp-request reaches nwconn over ncpserv. + +nwconn: + started for every single connection. Communicates with + ncpserv over an ipx-socket. + +nwbind: + the bindery program. Communicates with + ncpserv and nwconn over an ipx-socket. + Have luck with trying. :) - Martin -(mstover@freeway.de) +Martin Stover + +BTW: The kick to make mars_nwe public was the publication of +linware ( lwared ), the NetWare-Emulator from +Ales Dryak -BTW: The kick to make mars_nwe public was the -publication of linware ( lwared ), the Novell-Server-Emulator -from Ales Dryak (A.Dryak@sh.cvut.cz). I hope both products can make profit from each other. -----> SuperNOS ala Linux ;-) Novell don't want to make it anymore. :-( diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index f78010f..5d260a1 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,15 +1,15 @@ Begin3 Title: mars_nwe -Version: 0.97.pl3 -Entered-date: 07-May-96 -Description: full novell-server-emulator (src),beta - supports file-services, bindery-services, - printing-services, routing-services +Version: 0.97.pl4 +Entered-date: 11-May-96 +Description: Full netware-emulator (src), beta. + Supports file-services, bindery-services, + printing-services, routing-services. 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.pl3.tgz + 140kB mars_nwe-0.97.pl4.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/examples/config.h b/examples/config.h index 513cb82..8001ee0 100644 --- a/examples/config.h +++ b/examples/config.h @@ -1,57 +1,64 @@ -/* config.h: 03-May-96 */ -/* some of this config is needed by make, others by cc */ -#define DO_DEBUG 1 /* Compile in debug code */ +/* config.h: 13-May-96 */ +/* some of this config is needed by make, others by cc */ + +#define DO_DEBUG 1 /* compile in debug code */ + +#define DO_TESTING 0 /* set this to "1" to test only */ -#define DO_TESTING 0 /* only for the next choose */ #if DO_TESTING -# define FILENAME_NW_INI "./nw.ini" /* full name of ini (conf) file */ -# define PATHNAME_PROGS "." /* path location of progs */ -# define PATHNAME_BINDERY "." /* path location of bindery */ +# define FILENAME_NW_INI "./nw.ini" /* full name of ini (conf) file */ +# define PATHNAME_PROGS "." /* where to find the executables */ +# define PATHNAME_BINDERY "." /* directory for bindery-files */ # define FUNC_17_02_IS_DEBUG 1 #else -# define FILENAME_NW_INI "/etc/nwserv.conf" /* full name of ini (conf) file */ -# define PATHNAME_PROGS "/sbin" /* path location of progs */ -# define PATHNAME_BINDERY "/etc" /* path location of bindery */ +# define FILENAME_NW_INI "/etc/nwserv.conf" + /* full name of ini (conf) file */ +# define PATHNAME_PROGS "/sbin" /* where to find the executables */ +# define PATHNAME_BINDERY "/etc" /* directory for bindery-files */ # define FUNC_17_02_IS_DEBUG 0 #endif -#define PATHNAME_PIDFILES "/var/run" /* path location of 'pidfiles' */ -/* next for utmp/wtmp updates */ -#define FILENAME_UTMP UTMP_FILE -/* can be set NULL if you don't want utmp/wtmp updates */ -#define FILENAME_WTMP WTMP_FILE -/* can be set NULL if you don't want wtmp updates */ +#define PATHNAME_PIDFILES "/var/run" /* directory for 'pidfiles' */ -#define NETWORK_SERIAL_NMBR 0x44444444L /* Serial Number 4 Byte */ -#define NETWORK_APPL_NMBR 0x2222 /* Applikation Number 2 Byte */ +/* ----- logging the logins via "mars_nwe" in utmp/wtmp ------------------ */ +#define FILENAME_UTMP UTMP_FILE /* use "NULL" instead of UTMP_FILE */ + /* to disable logging via utmp */ +#define FILENAME_WTMP WTMP_FILE /* use "NULL" instead of WTMP_FILE */ + /* to disable logging via wtmp */ -#define MAX_CONNECTIONS 5 /* max. Number of Connections */ - /* must be < 256 !!! */ +#define NETWORK_SERIAL_NMBR 0x44444444L + /* serial number (4 byte) */ +#define NETWORK_APPL_NMBR 0x2222 /* application number (2 byte) */ -#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ +#define MAX_CONNECTIONS 5 /* max. number of simultaneous */ + /* connections handled by mars_nwe */ -/* <-----------------------------------------------------------> */ -#define MAX_NW_VOLS 10 /* max. Volumes */ -#define MAX_FILE_HANDLES_CONN 80 /* max. open files /connection */ +#define IPX_DATA_GR_546 1 /* allow ipx packets > 546+30 Byte */ -/* <--------------- new namespace services call --------------> */ -#define WITH_NAME_SPACE_CALLS 1 /* Namespace Calls are only minimal */ - /* supported till now. */ - /* to enable testing of them this */ - /* entry must be changed to '1' and */ - /* entry '6' in ini file must be set */ - /* to > '0', too. */ -#define MAX_DIR_BASE_ENTRIES 50 /* max. cached base entries/connection */ -/* <-----------------------------------------------------------> */ -#define MAX_NW_SERVERS 40 /* max. count of servers */ +/* <--------------------------------------------------------------------> */ +#define MAX_NW_VOLS 10 /* max. number of mars_nwe-volumes */ +#define MAX_FILE_HANDLES_CONN 80 /* max. number of open files per */ + /* connection */ +/* <--------------- new namespace services call -----------------------> */ +#define MAX_DIR_BASE_ENTRIES 50 /* max. cached base entries per */ + /* connection */ +#define WITH_NAME_SPACE_CALLS 0 /* Namespace Calls are only minimal */ + /* supported so far. */ + /* To enable testing of them this */ + /* entry must be changed to '1' and */ + /* entry '6' in ini file should be set*/ + /* to > '0', too. */ +/* <--------------------------------------------------------------------> */ +#define MAX_NW_SERVERS 40 /* max. number of nw-servers on your */ + /* network */ -/* <--------------- next is for linux only -------------------> */ -#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ +/* <--------------- next is for linux only ----------------------------> */ +#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ /* -------------------- */ -#define MAX_NET_DEVICES 5 /* max. Netdevices, frames */ -#define MAX_NW_ROUTES 50 /* max. networks (internal + external) */ -#define MAX_RIP_ENTRIES 50 /* max. rip responses */ +#define MAX_NET_DEVICES 5 /* max. Netdevices, frames */ +#define MAX_NW_ROUTES 50 /* max. nw-networks on your network */ + /* (internal + external) */ +#define MAX_RIP_ENTRIES 50 /* max. rip responses */ /* -------------------- */ -#define SHADOW_PWD 0 /* change to '1' for shadow passwds */ - +#define SHADOW_PWD 0 /* change to '1' for shadow passwds */ diff --git a/examples/nw.ini b/examples/nw.ini index 1bfb9bb..e7b7168 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -1,133 +1,310 @@ -# (C)opyright 1993, 1996, Martin Stover, Softwareentwicklung, Marburg -# last change: 28-Apr-96 -# MAR.S NW-Server Emulator -# Einfache Konfiguration, alles ab # ist Kommentar. -# Jeder Eintrag beginnt mit einer Zahl und dann folgt der Inhalt. -# simple configuration, all after # is ignored. -# every entry begins with a number and then the meet follows. -#################################### -# entry 1 VOLUMES (max. volumes depend on your config.h) -# Volumename Volumepath Options (k=lowercase,p=pipe,m=removable) -1 SYS /u3/SYS/ # SYS 1 -# SYS, der Name darf auch anders lauten, muss -# eingerichtet sein mit den folgenden Verzeichnissen: -# LOGIN, PUBLIC, SYSTEM, MAIL. -# SYS, may be named diffent but must be setup and must -# contains the following Directories: LOGIN, PUBLIC, SYSTEM, MAIL -#################################### -# Die folgenden Volumes sind optional. -# the following volumes are optional. -#1 HOME ~ k # Users HOME directory -#.............^^^ -# such a 'path' (~) stands for users home dir -# this is an automatic changed volume. -#1 SYS1 /u3/SYS1/ # SYS 2 upshift -#1 TMP /tmp/ k # TMP downshift -#1 CD /cdrom km # CDROM downshift/removable -#1 PIPES /u3/pipes kp # pipecommands -# Falls lowercase nicht gesetzt ist, werden GROSSBUCHSTABEN erwartet. -# If lowercase is not set then all filenames are upshift. -# all flags for volumes: -# 'k' all is downshift -# 'm' volume is moveable (cdrom) -# 'o' volume has only one filesystem/device/namespace -# this is for filesystems with high inode > 0xFFFFFFF. -# because for namespace services mars_nwe normally use the -# first 4 bit of 32 bit inode for distinguish -# between several devices/namespaces for one volume. -# 'p' 'PIPE' filesystem. All files are pipe commands. -# see 'doc/PIPE-FS' -###################################### -# Eintrag 2 fuer den Servername. -# falls nicht gesetzt, wird hostname (in GROSSBUCHSTABEN) verwendet. -# entry 2 for the servername. If not set, then the hostname (upshift) -# will be taken. -#2 MAR1 # Servername -###################################### -# next entry for configure mars_nwe to use the internal net +# +# This is the configuration-file for "mars_nwe", the free netware-emulator +# for Linux. +# +# last change: 13-May-96 +# +# Syntax of this config-file: +# - everything after the "#" is ignored, so it is used to +# make comment-lines +# - entries _must_ begin with a number, indicating the section +# they belong to +# - hexadecimal values are prepended with "0x" +# +# All examples are verbatim. + + +# Section 1: volumes (required) +# +# In this section you list all directories accessible via "mars_nwe". +# To be more specific: a mapping from Linux-directories to mars_nwe-volumes +# is done. (Volumes are the beasts you can map to drive letters under DOS +# using "map.exe"). +# +# Linux-directory mars_nwe-volume map.exe DOS-Drive +# /var/local/nwe/SYS -------> SYS -------------> W: +# +# More than one entry is possible in this section. +# The maximum number of volumes is a compile-time option that must be +# specified in `config.h' before compiling mars_nwe. +# +# Please note that at least the volume "SYS" must be defined and it must +# contain the following sub-directories: LOGIN, PUBLIC, SYSTEM, MAIL. +# See the installation-instructions in the doc-directory for more infos. +# +# Syntax: +# 1 VOLUMENAME DIRECTORY OPTIONS +# +# VOLUMENAME: the name of the mars_nwe-volume (max. 8 characters) +# DIRECTORY: the directory on your Linux-system associated with that +# volume; use the special name "~" to refer to the users +# individual home-directory +# +# OPTIONS: none or some of the following characters (without a seperator) +# k allow lowercase-filenames (if you don't set this, all +# files _must_ be upper-case) +# m removable volume (e.g. cd-roms) +# o volume has only one filesystem/device/namespace +# this is for filesystems with high inode > 0xFFFFFFF. +# because for namespace services mars_nwe normally use the +# first 4 bit of 32 bit inode to distinguish +# between several devices/namespaces for one volume. +# p "PIPE"-filesystem. All files are pipe commands. +# See `doc/PIPE-FS'. +# r readonly volume. Free disk space will also return 0. +# +# examples: +1 SYS /u3/SYS/ # SYS upper-case filenames +1 CDROM /cdrom km # lowercase filenames, removable +1 HOME ~ k # users HOME directory, lowercase + + +# Section 2: servername (optional) +# +# The servername is the name under which this server will show up when +# using tools like "slist" (server-list). +# +# If you don't supply an entry for this section, the hostname of your +# Linux-machine will be converted to all-uppercase and used as the servername. +# +# Syntax: +# 2 SERVERNAME +# +# SERVERNAME: a name for this nw-server +# +# Example: +# 2 MARS + + +# Section 3: Number of the internal network # If you have mars_nwe V > 0.96pl5 and a kernel >= 1.3.60 # or the small ipx-kpatch from the examples dir you should use # internal net and routing. -# NOTE: the internal NET Number must be UNIQUE -# in your IPX-environment. ! -# INTERNAL NET [NODE] (default 1) -3 0xABCDEF99 1 # Net Number must be unique. -###################################### -# entry 4: # for DEVICE(S) +# +# NOTE: the internal net number must be _unique_ in your IPX-environment! +# +# Syntax: +# 3 INTERNAL_NET [NODE] +# +# INTERNAL_NET: AUTO or 0 for using the ip number as INTERNAL_NET +# +# NODE: 1 (optional) +# +# Examples: +# 3 0xABCDEF99 # use a unique number +3 AUTO # use ip number as INTERNAL_NET + + +# Section 4: IPX-devices (optional) +# # NOTE for people with other IPX/NCP servers on the net: # Your network numbers, frames must be the same as at your # other servers on the same net. -# You also may choose a network number = '0', device = '*' -# and frame = 'auto' for autosetup of devices. # -# NETWORK NUMBER, DEVICE, Frame-Typ TICKS (default 1) -4 0x10 eth0 802.3 1 -4 0x0 * AUTO 1 # autosetup all devices -# ^^^^...........^^^....^^^^^^^ -# NOTE: autosetup can only be choosen if you have other -# IXP/NCP servers on the same net which are setup correctly. -###### -#4 0x22 eth0 ethernet_ii 1 -#4 0x33 eth0 802.2 1 -#4 0x55 isdn2 ethernet_ii 7 -#4 0x66 tr0 token 1 -# Frames=ethernet_ii, 802.2, 802.3, snap, token, auto, (default 802.3), -5 0 # don't = 0, do = 1, save ipx-routes after server is down. -###################################### -# some clients are running better, if the server tells -# that it is a 3.11 Server, although many calls -# (namespace services) of a real 3.11 Server are missing yet. -# simple namespace services are implemented for testing -# since V 0.96pl8. To test them, this entry must be set to > 0. -# and config.h must be altered to compile in namespace calls. -6 0 # tells server version: 0=2.15, 1=3.11, 2=3.12 -###################################### -# Password handling -7 0 # 0 = use only encrypted passwords stuff (default) - # 1 = allow the unencrypted change password routine. - # 7 = allow all unencrypted stuff, no empty nwe passwords. - # 8 = allow all unencrypted stuff, allow empty nwe passwords. - # 9 = use all unencryted calls + get crypt key will allways fail - # so the login program will use the old unencryted calls. - # this will *not* work with all clients !! (OS2/client) -###################################### -# GID and UID for _minimal_ rights -# will be used for not logins or not assigned mars_nwe users. -10 200 # GID -11 201 # UID -###################################### -# the following passwords should be removed after the first -# start, because these entries will be inserted (crypted) into -# the bindery. If you specify a password here, then this password -# will be put into bindery after every start of mars_nwe. -# one entry 12 for SUPERVISOR -## NW-Name UNIX-Name [PASSWORD] -12 SUPERVISOR root MYPW # Supervisor -############################# -# more entries 13 for other user(s) -## NW-Name UNIX-Name [PASSWORD] -#13 MAR mar # others -#13 ALF mar # others -##### -# Read UnixUsers automaticly from passwd into bindery -# switch password -15 0 secure11 -# ^^^ 0=off (default), 1=on, 99=overwrite existing mars_nwe users. +# Syntax: +# 4 NET_NUMBER DEVICE FRAME TICKS +# +# NET_NUMBER: +# DEVICE: the network-interface associated with the NET_NUMBER +# FRAME: +# ethernet_ii +# 802.2 +# 802.3 (default) +# snap +# token +# auto +# TICKS: ethernet: 1, isdn: 7 +# +# Examples: +4 0x10 eth0 802.3 1 +# Automatic setup: +4 0x0 * AUTO 1 +# +# NOTE: autosetup only works if there are other IXP/NCP servers on +# the same net which are setup correctly, that means: tells us the required +# information about netnumber and frame. + + +# Section 5: Saving of ipx-routes (optional) +# +# This entry controls if the information regarding the ipx-routes should be +# saved beyond the livetime of the server. +# You can achieve a small speedup when starting mars_nwe by using this entry. +# +# Syntax: +# 5 SAVE_FLAG +# +# SAVE_FLAG: +# 0 don't save routes (default) +# 1 do save routes +# Example: +5 0 + + +# Section 6: version-spoofing +# +# Some clients work better if the server tells that it is a 3.11 Server, +# although many calls (namespace services) of a real 3.11 Server are +# missing yet. +# To test the namespace calls, this entry must be set to > 0 and `config.h' +# must be altered before compiling "mars_nwe". +# +# Syntax: +# 6 SERVER_VERSION +# +# SERVER_VERSION: +# 0 Version 2.15 +# 1 Version 3.11 +# 2 Version 3.12 (not implemented yet) +6 0 + + +# Section 7: password handling (required) +# When changing your "mars_nwe"-password from a DOS-client, this client +# (think of "LOGIN.EXE", "SYSCON.EXE" or "SETPASS.EXE") can encrypt your +# password before sending it to the "mars_nwe"-server (this improves +# security a little bit). +# In this section you can enforce encryption of user-passwords or allow +# not-encrypted sending of passwords over the net. +# On the Linux-side, passwords will only be stored in encrypted format. +# +# Syntax: +# 7 FLAG +# +# FLAG: +# 0 use only encrypted passwords stuff. +# the encrypted change password call is not +# implemented till now, so if you choose this option +# you will not be able to change passwords from +# client size. +# 1 allow the unencrypted change password routine (default). +# You can use mars_dosutils or an old 2.15 setpass program. +# +# 7 allow all unencrypted stuff, no empty nwe passwords. +# 8 allow all unencrypted stuff, allow empty nwe passwords. +# 9 use all unencryted calls + get crypt key will allways fail +# so the login program will use the old unencryted calls. +# this will *not* work with all clients !! (OS2/client) +7 1 + + +# Section 10 + 11 : UID and GID with minimal rights +# +# When loading the netware-drivers in the "autoexec.bat" of your +# DOS-client, you automatically "attach" to a netware-server. +# As a result, a new drive-letter is accessible under DOS, usally +# containing the programs "login.exe" and "slist.exe". +# Because you haven't logged in, nothing else of the netware-server +# will be visible to you. All actions requested from the DOS-client +# will be done with the following UID and GID on the Linux-side in this +# case. +# To achieve some level of security, the user/group asscociated with +# the UID and GID should only have _read_ rights on the files visible, +# _nothing_ else. +# +# On most Linux-systems, there is a user and group "nobody" defined in +# `/etc/passwd' and `/etc/group'. Use the number of that user/group +# for the following entries. +# +# Syntax: +# 10 GID +# 11 UID +# Example: +# 10 65534 +# 11 65534 +# +# GID numeric number of the group +# UID numeric number of the user +10 65534 +11 65534 + + +# Section 12: supervisor-login (required) +# +# The "supervisor" of a nw-server is much like "root" on the Linux-side. +# +# Syntax: +# 12 NW_LOGIN LINUX_LOGIN [PASSWORD] +# +# NW_LOGIN: the login-name for the "mars_nwe"-server (traditionally, +# this is "SUPERVISOR") +# LINUX_LOGIN: the account on the Linux-side associated with the NW_LOGIN +# (to improve security, don't use "root" here) +# PASSWORD: the password for the NW_LOGIN. It must be clear-text but +# will be encrypted and permanent stored in the +# bindery-files, so it can be deleted after the first start +# of "nwserv". +# +# Example: +12 SUPERVISOR root top-secret + + +# Section 13: user-logins (optional) +# +# See section 12 for the syntax. +# +# Examples: +13 MAR mar mypw +13 ALF mar - # no password + + +# Section 15: read unix users automaticly from passwd into bindery +# +# Syntax: +# 15 FLAG DEFAULT_PASSWORD +# +# FLAG: +# 0 off +# 1 on +# 99 overwrite existing users. +# +# DEFAULT_PASSWORD: password for every new inserted user. +# +15 0 top-secret +# # !!! IMPORTANT !!! # If you enable this feature you should chose a secure # password for the users, because all not existent # mars_nwe users will be inserted into bindery with this password. -############### + + +# Section 16: Tests on startup +# 16 1 # enable some bindery and sys dir tests/creats after starting. -############################# -# entry 21 for simple print queues -# the queue Directory must exist before printing !!! -# QUEUE NAME, Q_DIRECTORY, UNIX-print-command (pipe) -21 Q1 SYS:/PRINT/Q1 lpr -#21 Q2 SYS:/PRINT/Q2 lpr -C printer2 -############################# -# >= 100 debug flags, -# 0=nodebug, 1=mindebug(errors+notes), 99=maxdebug +# default = 1 + + +# Section 21: print queues (optional) +# +# Make the printers connected to your Linux-box accessible from the +# DOS-clients. +# Multiple entries are allowed. +# +# Syntax: +# 21 QUEUE_NAME QUEUE_DIR PRINT_COMMAND +# +# QUEUE_NAME: the name of the print queue +# QUEUE_DIR: spooling directory for the print-jobs; this directory must +# exist before printing +# PRINT_COMMAND: command used for serving the print-jobs under Linux +# (see "man lpr" and "man magicfilter" for details) +# +# Examples: +# 21 LASER SYS:/PRINT/L lpr -Plaser +# 21 OCTOPUSS SYS:/PRINT/O lpr -Php_deskjet + + +# -------------------------------------------------------- +# You usally don't want to change anything below this line +# -------------------------------------------------------- + +# Sections 100-106: amount of debug-information +# +# FLAG: +# 0 no debug messages +# 1 errors and notes are reported +# .. +# 99 maximum debug level 100 0 # debug IPX KERNEL (0 | 1) 101 1 # debug NWSERV 102 0 # debug NCPSERV @@ -135,28 +312,46 @@ 104 0 # debug (start) NWCLIENT 105 0 # debug NWBIND 106 1 # debug NWROUTED -############################# + + +# Sections 200-202: logging of "nwserv" +# 200 1 # 0 = no logfile and dont daemonize nwserv/nwrouted # # 1 = daemonize nwserv/nwrouted and use logfile -201 /tmp/nw.log # logfilename -202 1 # 1=creat new logfile, 0=append to logfile -############################# -210 10 # 1 .. 600 (default 10) seconds after server really goes down -# # after a down command +201 /tmp/nw.log # filename of logfile +202 1 # 1=creat new logfile, 0=append to logfile + + +# Sections 210,211: timing +# +210 10 # 1 .. 600 (default 10) seconds after server +# # really goes down after a down command 211 60 # 10 .. 600 (default 60) broadcasts every x seconds -############################# -300 1 # > 0 print routing info to file every x broadcasts. ( normally minutes ) -301 /tmp/nw.routes # filename. -302 1 # creat new routing info file=1, append to this file=0 -############################# + + +# Sections 300-302: loging of routing-information +# +300 1 # > 0 print routing info to file every x broadcasts. +# # ( normally minutes ) +301 /tmp/nw.routes # filename of logfile +302 1 # 1 = creat new routing info file +# # 0 = append to this file + + +# Section 310: watchdogs +# 310 7 # send wdog's only to device net < x ticks. - # 0 = allways send wdogs. < 0 = never send wdogs -############################## +# 0 = allways send wdogs. < 0 = never send wdogs +# +# Section 400: # station file for special handling of stations. +# 400 /etc/nwserv.stations # for syntax see file in the examples directory. + + +# Section 401: nearest server +# # for special handling of the 'get nearest server request'. 401 0 # 0 = ignore entry 400, get nearest response ever enabled. - # 1 = 400 are excludes, get nearest response normally enabled. - # 2 = 400 are includes, get nearest response normally disabled. -### - +# 1 = 400 are excludes, get nearest response normally enabled. +# 2 = 400 are includes, get nearest response normally disabled. diff --git a/makefile.unx b/makefile.unx index d3b5eae..19f512d 100644 --- a/makefile.unx +++ b/makefile.unx @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=97 -P_L=3 +P_L=4 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/namspace.c b/namspace.c index fbe1a31..8513420 100644 --- a/namspace.c +++ b/namspace.c @@ -1,4 +1,4 @@ -/* namspace.c 06-May-96 : NameSpace Services, mars_nwe */ +/* namspace.c 13-May-96 : NameSpace Services, mars_nwe */ /* !!!!!!!!!!!! NOTE !!!!!!!!!! */ /* Its very dirty till now. */ @@ -225,12 +225,6 @@ static DIR_BASE_ENTRY *allocate_dbe_p(int namespace) return(*pdbe); } -static int allocate_dbe(int namespace) -{ - DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); - return((NULL != dbe) ? dbe->slot : -1); -} - static void xx_free_dbe_p(DIR_BASE_ENTRY **dbe) { if (NULL != dbe && NULL != *dbe) { @@ -293,6 +287,7 @@ char *debug_nwpath_name(N_NW_PATH *p) } static int get_comp_pathes_size(NW_HPATH *nwp, uint8 *pp_pathes) +/* returns size of path components in bytes */ { int k = -1; int size = 0; @@ -386,7 +381,8 @@ static int nwp_stat(N_NW_PATH *nwpath, char *debstr) } static uint32 build_base_handle(N_NW_PATH *nwpath, int namespace) -/* returns basehandle of path, or 0 if not exist !! */ +/* returns basehandle of path, or 0 if not exist !! */ +/* nwpath must be filled, namespace must be specified */ { uint32 basehandle=0L; if (!nwp_stat(nwpath, "build_base_handle")) { @@ -417,9 +413,13 @@ static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, { N_NW_PATH *nwpath = &(dbe->nwpath); uint32 basehandle = build_base_handle(nwpath, namespace); + if (!basehandle && creatmode) { /* now creat the entry (file or dir) */ int result = 0; char *unname = nwpath_2_unix(nwpath, 2); + if (get_volume_options(nwpath->volume, 1) & + VOL_OPTION_READONLY) return(-0x8a); + if (creatmode & FILE_ATTR_DIR) { /* creat dir */ if (mkdir(unname, 0777)) result=-0x84; @@ -450,19 +450,19 @@ static int insert_get_base_entry(DIR_BASE_ENTRY *dbe, dbe->basehandle = basehandle; return(touch_handle_entry_p(dbe)); } - return(-0xff); /* no files matching */ + return(-0xff); /* invalid path = -0x9c, -0xff no matching files */ } -static int build_dos_base(NW_HPATH *nwp, - uint8 *pathes, - int dbase, - int mode, uint8 *rets) +static int build_dos_base(NW_HPATH *nwp, + uint8 *pathes, + DIR_BASE_ENTRY *dbe, + int mode, + uint8 *rets) /* routine returns the actual dbe entry offset or */ /* < 0 if error */ /* if mode == 1, then last_path will be ignored and will be put */ /* into the rets variable */ { - DIR_BASE_ENTRY *dbe=dir_base[dbase]; N_NW_PATH *nwpath=&(dbe->nwpath); int result=0; if (!nwp->flag) { /* short handle */ @@ -478,10 +478,10 @@ static int build_dos_base(NW_HPATH *nwp, } else result = -0x9b; } else if (nwp->flag == 1) { /* basehandle */ uint32 basehandle = GET_32(nwp->base); - int k=-1; - result = -0x9b; + int k = -1; + result = -0x9b; /* here wrong dir_handle should mean wrong basehandle */ while (++k < anz_dbe) { - if (k != dbase) { + if (k != dbe->slot) { DIR_BASE_ENTRY *e=dir_base[k]; if ( (DIR_BASE_ENTRY*)NULL != e && e->nwpath.volume == nwp->volume @@ -507,7 +507,7 @@ static int build_dos_base(NW_HPATH *nwp, *(nwpath->path) = '\0'; } } - if (pp) nwpath->fn=(uint8*)pp+1; + nwpath->fn = (pp) ? (uint8*)pp+1 : nwpath->path; result = insert_get_base_entry(dbe, NAME_DOS, 0); } } @@ -521,21 +521,19 @@ int nw_generate_dir_path(int namespace, /* returns Volume Number >=0 or errcode < 0 if error */ { - int dbase = allocate_dbe(namespace); + DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); int result = -0xfb; - if (dbase > -1) { - if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { - DIR_BASE_ENTRY *dbe=dir_base[result]; + if (NULL != dbe) { + if ((result = build_dos_base(nwp, nwp->pathes, dbe, 0, NULL)) > -1) { U32_TO_32(dbe->basehandle, ns_dir_base); /* LOW - HIGH */ U32_TO_32(dbe->basehandle, dos_dir_base); XDPRINTF((3, 0, "nw_generate_dir_path path=%s, result=%d, basehandle=0x%x", debug_nwpath_name(&(dbe->nwpath)), result, dbe->basehandle)); result= dbe->nwpath.volume; - } else free_dbe(dbase); + } else free_dbe_p(dbe); } if (result < 0) { - XDPRINTF((3, 0, "nw_generate_dir_path NOT OK dbase=%d, result=%d", - dbase, result)); + XDPRINTF((3, 0, "nw_generate_dir_path NOT OK result=-0x%x", -result)); } return(result); } @@ -640,18 +638,16 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, * But the _valid_ info is. */ { - int dbase = allocate_dbe(namespace); + DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace); int result = -0xfb; - if (dbase > -1) { - if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { - DIR_BASE_ENTRY *dbe=dir_base[result]; + if (NULL != dbe) { + if ((result = build_dos_base(nwp, nwp->pathes, dbe, 0, NULL)) > -1) { nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); result = build_dir_info(dbe, infomask, responsedata); - } else free_dbe(dbase); + } else free_dbe_p(dbe); } if (result < 0) { - XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK dbase=%d, result=-0x%x", - dbase, -result)); + XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", -result)); } return(result); } @@ -663,8 +659,7 @@ static int nw_init_search(int namespace, DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); int result = -0xfb; if (NULL != dbe) { - if ((result = build_dos_base(nwp, nwp->pathes, dbe->slot, 0, NULL)) > -1) { - dbe=dir_base[result]; + if ((result = build_dos_base(nwp, nwp->pathes, dbe, 0, NULL)) > -1) { result = base_open_seek_dir(dbe, 0L); if (result > -1) { *responsedata++ = dbe->nwpath.volume; @@ -789,22 +784,21 @@ static int nw_open_creat_file_or_dir(int namespace, NW_HPATH *nwp, uint8 *pathes, uint8 *responsedata) { - int dbase = allocate_dbe(namespace); + DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); int result = -0xfb; - if (dbase > -1) { + if (NULL != dbe) { int exist=-1; uint8 last_part[258]; *last_part='\0'; - if ((result = build_dos_base(nwp, pathes, dbase, 0, NULL)) > -1) { + if ((result = build_dos_base(nwp, pathes, dbe, 0, NULL)) > -1) { exist = result; } else if (opencreatmode & OPC_MODE_CREAT) { - result = build_dos_base(nwp, pathes, dbase, 1, last_part); + result = build_dos_base(nwp, pathes, dbe, 1, last_part); if (result > -1) - result = get_add_new_entry(dir_base[result], last_part, + result = get_add_new_entry(dbe, last_part, (creatattrib & FILE_ATTR_DIR) ? FILE_ATTR_DIR : 1); } if (result > -1) { - DIR_BASE_ENTRY *dbe=dir_base[result]; uint32 fhandle=0L; int actionresult=0; if (exist < 0) actionresult |= OPC_ACTION_CREAT; @@ -837,7 +831,7 @@ static int nw_open_creat_file_or_dir(int namespace, responsedata++ ; result = 5 + build_dir_info(dbe,infomask, responsedata); } - } + } else free_dbe_p(dbe); } XDPRINTF((3, 0, "nw_open_creat mode=0x%x, creatattr=0x%x, access=0x%x, attr=0x%x, result=%d", opencreatmode, creatattrib, access_rights, attrib, result)); @@ -847,24 +841,30 @@ static int nw_open_creat_file_or_dir(int namespace, static int nw_delete_file_dir(int namespace, int searchattrib, NW_HPATH *nwp) { - int dbase = allocate_dbe(namespace); - int result = -0xfb; - if (dbase > -1) { - if ((result = build_dos_base(nwp, nwp->pathes, dbase, 0, NULL)) > -1) { - DIR_BASE_ENTRY *dbe=dir_base[dbase=result]; + DIR_BASE_ENTRY *dbe = allocate_dbe_p(namespace); + int result = -0xfb; + if (dbe != NULL) { + if ((result = build_dos_base(nwp, nwp->pathes, dbe, 0, NULL)) > -1) { uint8 *unname=(uint8*)nwpath_2_unix(&(dbe->nwpath), 2); - if (S_ISDIR(dbe->nwpath.statb.st_mode)) result = rmdir(unname); - else result = unlink(unname); - if (result < 0) { - switch (errno) { - case EEXIST: result=-0xa0; /* dir not empty */ - default: result=-0x8a; /* No privilegs */ + if (get_volume_options(dbe->nwpath.volume, 1) & + VOL_OPTION_READONLY) result = -0x8a; + else { + if (S_ISDIR(dbe->nwpath.statb.st_mode)) { + free_dbe_p(dbe); + result = rmdir(unname); + } else { + if (-1 < (result = unlink(unname))) + free_dbe_p(dbe); } - } else { - result = 0; - free_dbe(dbase) ; + if (result < 0) { + switch (errno) { + case EEXIST: result=-0xa0; /* dir not empty */ + default: result=-0x8a; /* No privilegs */ + } + } else + result = 0; } - } else free_dbe(dbase); + } else free_dbe_p(dbe); } return(result); } @@ -875,8 +875,7 @@ static int nw_alloc_short_dir_handle(int namespace, int hmode, DIR_BASE_ENTRY *dbe=allocate_dbe_p(namespace); int result = -0xfb; if (NULL != dbe) { - if ((result = build_dos_base(nwp, nwp->pathes, dbe->slot, 0, NULL)) > -1) { - dbe=dir_base[result]; + if ((result = build_dos_base(nwp, nwp->pathes, dbe, 0, NULL)) > -1) { if (S_ISDIR(dbe->nwpath.statb.st_mode)) { result=xinsert_new_dir(dbe->nwpath.volume, dbe->nwpath.path, dbe->nwpath.statb.st_ino, 300, hmode, task); @@ -897,21 +896,26 @@ static int nw_rename_file_dir(int namespace, DIR_BASE_ENTRY *dbe_d = (NULL != dbe_s) ? allocate_dbe_p(namespace) : NULL; int result = -0xfb; if (dbe_d && - (result = build_dos_base(nwps, pathes_s, dbe_s->slot, 0, NULL)) > -1) { + (result = build_dos_base(nwps, pathes_s, dbe_s, 0, NULL)) > -1) { uint8 last_part[258]; uint8 *unname_s= - (uint8*)nwpath_2_unix1(&((dbe_s=dir_base[result])->nwpath), - 2, 1); - if ((result = build_dos_base(nwpd, pathes_d, dbe_d->slot, + (uint8*)nwpath_2_unix1(&(dbe_s->nwpath), 2, 1); + if ((result = build_dos_base(nwpd, pathes_d, dbe_d, 1, last_part)) > -1) { uint8 *unname_d = - (uint8*)nwpath_2_unix2(&((dbe_d=dir_base[result])->nwpath), - 0, 1, last_part); + (uint8*)nwpath_2_unix2(&(dbe_d->nwpath), 0, 1, last_part); - if (S_ISDIR(dbe_s->nwpath.statb.st_mode)) - result = unx_mvdir(unname_s, unname_d); - else - result = unx_mvfile(unname_s, unname_d); + if (get_volume_options(dbe_s->nwpath.volume, 1) & + VOL_OPTION_READONLY) result= EROFS; + else if (get_volume_options(dbe_d->nwpath.volume, 1) & + VOL_OPTION_READONLY) result= EROFS; + + else { + if (S_ISDIR(dbe_s->nwpath.statb.st_mode)) + result = unx_mvdir(unname_s, unname_d); + else + result = unx_mvfile(unname_s, unname_d); + } XDPRINTF((5, 0, "Rename:%d '%s' -> '%s'", result, unname_s, unname_d)); @@ -920,8 +924,8 @@ static int nw_rename_file_dir(int namespace, case 0 : break; case EEXIST : result = -0x92; break; - - default : result = -0xff; + case EROFS : result = -0x8b; break; + default : result = -0x8b; } if (!result) { free_dbe_p(dbe_s); @@ -969,7 +973,7 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) case 0x03 : /* Search for File or DIR */ { /* NW PATH STRUC */ - int datastream = *(p+1); + int datastream = (int) *(p+1); int searchattrib = (int) GET_16(p+2); /* LOW-HI */ uint32 infomask = GET_32(p+4); /* LOW-HI */ int volume = *(p+8); @@ -1123,4 +1127,37 @@ int handle_func_0x57(uint8 *p, uint8 *responsedata, int task) return(result); } + +int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) +/* extended attribute calls */ +{ + int result = -0xfb; /* unknown request */ + int ufunc = (int) *p++; /* now p locates at 4 byte boundary */ + XDPRINTF((3, 0, "0x56 call ufunc=0x%x", ufunc)); + switch (ufunc) { +#if 0 + case 0x03 : /* read extended attribute */ + { + int flags = GET_BE16(p); + /* next 2 entries only if flags bits 0-1 = 00 */ + int volume = (int)GET_32(p+2); + uint32 basehandle = (int)GET_32(p+6); + struct OUTPUT { + uint8 errorcode[4]; /* ???? */ + uint8 ttl_v_length[4]; /* ???? */ + uint8 ea_handle[4]; /* ???? */ + uint8 access[4]; /* ???? */ + uint8 value_length[2]; /* ???? */ + uint8 value[2]; + } *xdata= (struct OUTPUT*)responsedata; + memset(xdata, 0, sizeof(struct OUTPUT)); + /* U32_TO_BE32(1, xdata->errorcode); */ + result = sizeof(struct OUTPUT); + } + break; +#endif + default : result = -0xfb; /* unknown request */ + } /* switch */ + return(result); +} #endif diff --git a/namspace.h b/namspace.h index f8e0f0c..7c09784 100644 --- a/namspace.h +++ b/namspace.h @@ -68,5 +68,6 @@ typedef struct { extern int handle_func_0x57(uint8 *p, uint8 *responsedata, int task); +extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task); #endif diff --git a/net.h b/net.h index 870116c..a49524d 100644 --- a/net.h +++ b/net.h @@ -181,7 +181,7 @@ extern int errno; #endif #ifndef WITH_NAME_SPACE_CALLS -# define WITH_NAME_SPACE_CALLS 1 +# define WITH_NAME_SPACE_CALLS 0 #endif #ifndef MAX_DIR_BASE_ENTRIES diff --git a/nwbind.c b/nwbind.c index c31769c..ad24e20 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "05-May-96" +#define REVISION_DATE "08-May-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -144,9 +144,14 @@ int b_acc(uint32 obj_id, int security, int forwrite) * 3 = only supervisor has access * 4 = only internal access. */ + char *acc_what=NULL; + char *acc_typ=NULL; + int errcode =0; + XDPRINTF((5,0, "b_acc for id=0x%lx, security=0x%x, forwrite=0x%x", + obj_id, security, forwrite)); if (internal_act || !act_c) return(0); /* allways full access to internal routines */ - if (forwrite) security >>= 4; /* writesecurity */ - security &= 0x4; + if (forwrite & 0xf) security >>= 4; /* writesecurity */ + security &= 0xf; if (!security) return(0); /* rights for all */ else if (security == 1) { if (act_c->object_id > 0) return(0); /* rights for all logged */ @@ -155,10 +160,39 @@ int b_acc(uint32 obj_id, int security, int forwrite) || act_c->object_id == 1 ) return(0); /* rights for the user */ } else if (security == 3 && act_c->object_id == 1) return(0); - XDPRINTF((1, 0, "b_acc no rights for 0x%x to %s property", - act_c->object_id, forwrite ? "read" : "write" )); + switch (forwrite&0xf) { + case 0 : acc_what = "read"; break; + case 1 : acc_what = "write"; break; + case 2 : acc_what = "creat"; break; + case 3 : acc_what = "delete"; break; + case 4 : acc_what = "rename"; break; + case 5 : acc_what = "change security"; break; + default : acc_what = "?" ; break; + } - return(forwrite ? -0xf8 : -0xfb); + switch ( (forwrite >> 4) & 0xf) { + case 0 : acc_typ = "obj" ; break; + case 1 : acc_typ = "prop"; break; + default : acc_typ = "?"; break; + } + + switch (forwrite) { + case 0x00 : errcode = -0xf2; break; + case 0x01 : errcode = -0xf8; break; /* should be changed */ + case 0x02 : errcode = -0xf5; break; + case 0x03 : errcode = -0xf4; break; + case 0x04 : errcode = -0xf3; break; + + case 0x10 : errcode = -0xf9; break; + case 0x11 : errcode = -0xf8; break; + case 0x12 : errcode = -0xf7; break; + case 0x13 : errcode = -0xf6; break; + + default : errcode = -0xff; break; + } + XDPRINTF((1, 0, "b_acc no rights for 0x%x to %s %s", + act_c->object_id, acc_what, acc_typ)); + return(errcode); } static void sent_down_message(void) @@ -421,10 +455,11 @@ static void handle_fxx(int gelen, int func) XDPRINTF((1, 0, "Supervisor tried unencrypted LOGIN")); } else #endif - + { internal_act = 1; result=nw_test_unenpasswd(obj.id, password); internal_act = 0; + } } else { XDPRINTF((1, 0, "unencryted logins are not enabled")); result=-0xff; @@ -438,7 +473,7 @@ static void handle_fxx(int gelen, int func) result = get_home_dir(responsedata + 2*sizeof(int)+1, obj.id); *(responsedata+ 2 * sizeof(int)) = (uint8) result; data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); - write_utmp(1, act_connection, act_c->pid_nwconn, &from_addr, pw_name); + write_utmp(1, act_connection, act_c->pid_nwconn, &(act_c->client_adr), pw_name); } else completition = (uint8) -result; } break; @@ -540,7 +575,7 @@ static void handle_fxx(int gelen, int func) *(responsedata+ 2 * sizeof(int)) = (uint8) result; data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); write_utmp(1, act_connection, act_c->pid_nwconn, - &from_addr, pw_name); + &(act_c->client_adr), pw_name); } else { #if 0 /* this is not ok */ @@ -551,7 +586,7 @@ static void handle_fxx(int gelen, int func) #endif completition = (uint8) -result; } - /* completition = 0xde menas login time has expired */ + /* completition = 0xde means login time has expired */ /* completition = 0xdf means good login, but */ /* login time has expired */ /* perhaps I will integrate it later */ @@ -932,31 +967,23 @@ static void handle_fxx(int gelen, int func) struct XDATA { uint8 acces_level; uint8 object_id[4]; - } *xdata = (struct XDATA*) responsedata; -#else - uint8 *xdata = responsedata; -#endif - - NETOBJ obj; - obj.id = act_c->object_id; - if (0 != obj.id) { - int result = nw_get_obj(&obj); - if (!result) { - *xdata = obj.security; - U32_TO_BE32(obj.id, (xdata+1)); - XDPRINTF((2,0, "ACCESS LEVEL:=0x%x, obj=0x%lx", - (int) obj.security, obj.id)); - data_len = 5; - } else completition = (uint8)-result; - } else { - *xdata = 0; - memset(xdata+1, 0xff, 4); - data_len = 5; } +#endif + uint8 *xdata = responsedata; + if (!act_c->object_id) { + *xdata = (uint8) 0; + memset(xdata+1, 0xff, 4); + } else { + *xdata = (act_c->object_id == 1) ? (uint8) 0x33 + : (uint8) 0x22; + U32_TO_BE32(act_c->object_id, (xdata+1)); + } + data_len = 5; + XDPRINTF((2,0, "ACCESS LEVEL:=0x%x, obj=0x%lx", + (int) *xdata, act_c->object_id)); } break; - case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */ /* TODO !!! */ completition = (uint8)0xff; @@ -979,12 +1006,10 @@ static void handle_fxx(int gelen, int func) break; case 0x49 : { /* IS CALLING STATION A MANAGER */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - /* TODO !! */ - completition = 0; /* here allways Manager */ + completition = (act_c->object_id == 1) ? 0 : 0xff; + /* here only SU = Manager */ /* not manager, then completition = 0xff */ - } + } break; case 0x4a : { /* keyed verify password */ @@ -1216,7 +1241,7 @@ static void handle_fxx(int gelen, int func) default : completition = 0xfb; /* not known here */ } /* switch */ } else if (func == 0x19) { /* logout */ - write_utmp(0, act_connection, act_c->pid_nwconn, &from_addr, NULL); + write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL); act_c->object_id = 0; /* not LOGIN */ } else completition = 0xfb; diff --git a/nwconn.c b/nwconn.c index 0244bdf..9c67ef3 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1279,6 +1279,14 @@ static int handle_ncp_serv(void) break; #if WITH_NAME_SPACE_CALLS + case 0x56 : /* some extended atrribute calls */ + { + int result = handle_func_0x56(requestdata, responsedata, ncprequest->task); + if (result > -1) data_len = result; + else completition=(uint8)-result; + } + break; + case 0x57 : /* some new namespace calls */ { int result = handle_func_0x57(requestdata, responsedata, ncprequest->task); diff --git a/nwdbm.c b/nwdbm.c index 1c2bc8e..0428e65 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 30-Apr-96 data base for mars_nwe */ +/* nwdbm.c 13-May-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 @@ -42,7 +42,7 @@ #define DBM_REMAINS_OPEN 1 int tells_server_version=0; -int password_scheme=0; +int password_scheme=PW_SCHEME_CHANGE_PW; static datum key; static datum data; @@ -62,7 +62,7 @@ static int x_dbminit(char *s) { char buff[256]; sprintf(buff, "%s/%s", PATHNAME_BINDERY, s); - my_dbm = dbm_open(buff, O_RDWR|O_CREAT, 0666); + my_dbm = dbm_open(buff, O_RDWR|O_CREAT, 0600); return( (my_dbm == NULL) ? -1 : 0); } @@ -189,10 +189,12 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id) if (p->obj_id == obj_id) { data = fetch(key); p = (NETPROP*)data.dptr; - if (p != NULL && name_match(p->name, prop_name)){ + 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 ((int)(p->id) > result) result = (int)(p->id); - xset[p->id]++; + if (!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. */ } } } /* for */ @@ -246,9 +248,10 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id) return(result); } -static int loc_delete_obj(uint32 objid) +static int loc_delete_obj(uint32 objid, int security) { - int result=0; + 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); if (!dbminit(FNOBJ)){ key.dptr = (char*)&objid; @@ -263,7 +266,7 @@ int nw_delete_obj(NETOBJ *obj) { int result = find_obj_id(obj, 0); XDPRINTF((2,0, "nw_delete_obj obj_id=%d, obj_name=%s", obj->id, obj->name)); - if (!result) result=loc_delete_obj(obj->id); + if (!result) result=loc_delete_obj(obj->id, obj->security); return(result); } @@ -272,7 +275,9 @@ int nw_rename_obj(NETOBJ *o, uint8 *newname) { int result = find_obj_id(o, 0); if (!result) { - result = -0xff; + result = b_acc(0, 0x33, 0x04); /* only supervisor */ + if (result) return(result); /* no obj rename priv */ + else result=-0xff; if (!dbminit(FNOBJ)){ key.dsize = NETOBJ_KEY_SIZE; key.dptr = (char*)o; @@ -285,6 +290,7 @@ int nw_rename_obj(NETOBJ *o, uint8 *newname) } } dbmclose(); + } return(result); } @@ -294,7 +300,9 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity) { int result = find_obj_id(o, 0); if (!result) { - result = -0xff; + result = b_acc(o->id, o->security, 0x05); + if (result) return(result); + else result=-0xff; if (!dbminit(FNOBJ)){ key.dsize = NETOBJ_KEY_SIZE; key.dptr = (char*)o; @@ -321,9 +329,9 @@ int nw_get_obj(NETOBJ *o) data = fetch(key); if (data.dptr != NULL){ NETOBJ *obj=(NETOBJ*)data.dptr; + result = b_acc(o->id, obj->security, 0x0); XDPRINTF((2,0, "got OBJ name=%s, id = 0x%x", obj->name, (int)obj->id)); - memcpy(o, data.dptr, sizeof(NETOBJ)); - result = 0; + if (!result) memcpy(o, data.dptr, sizeof(NETOBJ)); } } else result = -0xff; dbmclose(); @@ -375,7 +383,7 @@ static int loc_change_prop_security(NETPROP *p, uint32 obj_id) if (data.dptr != NULL && name_match(prop->name, p->name) ) { uint8 security = p->security; XDPRINTF((2,0, "found PROP %s, id=0x%x", prop->name, (int) prop->id)); - result = b_acc(obj_id, prop->security, 1); + result = b_acc(obj_id, prop->security, 0x15); if (!result) { memcpy(p, prop, sizeof(NETPROP)); p->security = security; @@ -534,7 +542,7 @@ L1: static int ins_prop_val(uint32 obj_id, NETPROP *prop, int segment, uint8 *property_value, int erase_segments) { - int result = b_acc(obj_id, prop->security, 1); + int result = b_acc(obj_id, prop->security, 0x11); if (result) return(result); if (!dbminit(FNVAL)){ NETVAL val; @@ -814,8 +822,9 @@ int nw_create_obj(NETOBJ *obj, uint32 wanted_id) * wanted_id should be taken as obj_id. */ { - int result = 0; /* OK */ + int result = b_acc(0, 0x33, 0x02); XDPRINTF((2,0, "creat OBJ=%s,type=0x%x", obj->name, (int)obj->type)); + if (result) return(result); /* no object creat rights */ if (!dbminit(FNOBJ)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { data = fetch(key); @@ -863,10 +872,10 @@ int nw_obj_has_prop(NETOBJ *obj) return(result); } - -int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) +static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) { - int result=0; + int result = b_acc(obj->id, obj->security, 0x12); + if (result) return(result); if (!dbminit(FNPROP)){ uint8 founds[256]; memset((char*)founds, 0, sizeof(founds) ); @@ -918,7 +927,7 @@ int nw_create_prop(int object_type, if ((result = find_obj_id(&obj, 0)) == 0){ prop.flags = (uint8)prop_flags; prop.security = (uint8)prop_security; - result = nw_create_obj_prop(&obj, &prop); + result = nw_create_obj_prop(&obj, &prop); } return(result); } @@ -956,7 +965,8 @@ uint32 nw_new_obj_prop(uint32 wanted_id, if (objname && *objname) nw_new_obj(&wanted_id, objname, objtype, objflags, objsecurity); - obj.id = wanted_id; + obj.id = wanted_id; + obj.security = objsecurity; if (propname && *propname) { strmaxcpy(prop.name, propname, sizeof(prop.name)); prop.flags = (uint8)propflags; @@ -1064,13 +1074,13 @@ int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key) 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); } - if (obj_id == 1) return(-0xff); } return(0); /* no password */ } @@ -1180,14 +1190,16 @@ static void create_nw_db(char *fn, int allways) struct stat stbuff; sprintf(fname, "%s/%s.dir", PATHNAME_BINDERY, fn); if (allways || stat(fname, &stbuff)){ - int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0666); + int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); } + chmod(fname, 0600); sprintf(fname, "%s/%s.pag", PATHNAME_BINDERY, fn); if (allways || stat(fname, &stbuff)){ - int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0666); + int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); } + chmod(fname, 0600); } static void add_pr_queue(uint32 q_id, @@ -1246,7 +1258,7 @@ static void add_user(uint32 u_id, uint32 g_id, char *password, int dont_ch) { /* Typ Flags Security */ - if (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x33) + if (nw_new_obj(&u_id, name, 0x1 , 0x0, (u_id == 1) ? 0x33 : 0x31) && dont_ch) return; XDPRINTF((1, 0, "Add/Change User='%s', UnixUser='%s'", name, unname)); @@ -1346,7 +1358,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) FILE *f = open_nw_ini(); int auto_ins_user = 0; char auto_ins_passwd[100]; - int make_tests = 0; + int make_tests = 1; char sysentry[256]; sysentry[0] = '\0'; ge_id = nw_new_obj_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31, @@ -1444,11 +1456,17 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) struct passwd *pw; upstr(auto_ins_passwd); while (NULL != (pw=getpwent())) { - 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_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)); + } } endpwent(); } @@ -1527,12 +1545,18 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) /* dynamic or without name */ objs[anz++] = obj->id; if (anz == 10000) break; + } else if (obj->type == 1 && obj->id != 1 && obj->security != 0x31) { + /* this is for correcting wrong obj security */ + obj->security=0x31; + (void)store(key, data); + XDPRINTF((1,0, "Correcting access obj_id=0x%lx(%s)", + obj->id, obj->name)); } } } } dbmclose(); - while (anz--) loc_delete_obj(objs[anz]); /* Now delete */ + while (anz--) loc_delete_obj(objs[anz], 0x44); /* Now delete */ anz = 0; if (!dbminit(FNPROP)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { diff --git a/nwdbm.h b/nwdbm.h index fbcabb5..ac5818c 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -162,8 +162,6 @@ extern int nw_create_obj(NETOBJ *obj, uint32 wanted_id); extern int nw_obj_has_prop(NETOBJ *obj); -extern int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop); - extern int nw_create_prop(int object_type, uint8 *object_name, int object_namlen, uint8 *prop_name, int prop_namlen, diff --git a/nwfile.c b/nwfile.c index ad77443..8a05046 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 01-May-96 */ +/* nwfile.c 11-May-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -69,7 +69,8 @@ static int free_file_handle(int fhandle) if (fh->f) ext_pclose(fh->f); fh->f = NULL; } else close(fh->fd); - if (fh->tmodi > 0L && !(fh->flags & 2)) { + if (fh->tmodi > 0L && !(fh->flags & 2) + && !(fh->flags & FILE_IS_READONLY)) { /* now set date and time */ struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; @@ -112,11 +113,14 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, if (fhandle > 0){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); int completition = -0xff; /* no File Found */ - if (get_volume_options(volume, 1) & VOL_OPTION_IS_PIPE) { + int dowrite = (access & 2) || creatmode ; + int voloptions = get_volume_options(volume, 1); + if (dowrite && (voloptions & VOL_OPTION_READONLY)) { + completition = (creatmode) ? -0x84 : -0x94; + } else if (voloptions & VOL_OPTION_IS_PIPE) { /* this is a PIPE Volume */ int statr = stat(fh->fname, stbuff); if (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) { - int dowrite= (access & 2) || creatmode ; char pipecommand[300]; char *topipe = "READ"; if (creatmode) topipe = "CREAT"; @@ -165,7 +169,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, fh->offd = 0L; if (fh->fd > -1) { if (statr) stat(fh->fname, stbuff); - } else completition = -0x9a; + } else completition = dowrite ? -0x94 : -0x93; } } if (fh->fd > -1) { @@ -184,8 +188,10 @@ 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) { - fh->tmodi = nw_2_un_time(datum, zeit); - return(0); + if (!(fh->flags & FILE_IS_READONLY)) { + fh->tmodi = nw_2_un_time(datum, zeit); + return(0); + } else return(-0x8c); } } return(-0x88); /* wrong filehandle */ @@ -208,7 +214,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)) { + if (fh->tmodi > 0L && !(fh->flags&2) + && !(fh->flags & FILE_IS_READONLY)) { struct utimbuf ut; ut.actime = ut.modtime = fh->tmodi; utime(fh->fname, &ut); @@ -289,6 +296,7 @@ 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])); @@ -336,6 +344,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 (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { retsize = 0; diff --git a/nwfile.h b/nwfile.h index 846a59a..e5074ec 100644 --- a/nwfile.h +++ b/nwfile.h @@ -1,4 +1,4 @@ -/* nwfile.h 23-Jan-96 */ +/* nwfile.h 11-May-96 */ #ifndef _NWFILE_H_ #define _NWFILE_H_ #include "nwqueue.h" @@ -10,8 +10,10 @@ typedef struct { FILE_PIPE *f; /* for PIPE */ int flags; /* 2 = PIPE */ /* 4 = don't reuse after close */ + /* 0x20 = readonly */ char fname[256]; /* UNIX filename */ } FILE_HANDLE; +#define FILE_IS_READONLY 0x20 extern void init_file_module(void); diff --git a/nwroute.c b/nwroute.c index 2215044..91c8b89 100644 --- a/nwroute.c +++ b/nwroute.c @@ -1,4 +1,4 @@ -/* nwroute.c 24-Apr-96 */ +/* nwroute.c 12-May-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -55,7 +55,7 @@ static void insert_delete_net(uint32 destnet, NW_NET_DEVICE *nd_dev = NULL; int ndticks = 99; - XDPRINTF((3,0,"%s net:0x%X, over 0x%X, 0x%02x:%02x:%02x:%02x:%02x:%02x", + XDPRINTF((3,0,"Beg: %s net:0x%X, over 0x%X, 0x%02x:%02x:%02x:%02x:%02x:%02x", (do_delete) ? "DEL" : "INS", destnet, rnet, (int)rnode[0], (int)rnode[1], (int)rnode[2], (int)rnode[3], (int)rnode[4], (int)rnode[5])); @@ -388,7 +388,7 @@ void handle_rip(int fd, int ipx_pack_typ, int data_len, IPX_DATA *ipxdata, ipxAddr_t *from_addr) -/* All received rip packeta reach this function */ +/* All received rip packets reach this function */ /* It can be a RIP Request or a RIP Respons */ { int operation = GET_BE16(ipxdata->rip.operation); @@ -429,46 +429,84 @@ void handle_rip(int fd, int ipx_pack_typ, } /* <========================= SAP ============================> */ +static void send_sap_to_addr(int entry, int hops, int ticks, + int respond_typ, ipxAddr_t *to_addr) +{ + if (entry > -1) { + IPX_DATA ipx_data; + NW_SERVERS *nw=nw_servers[entry]; + memset(&ipx_data, 0, sizeof(ipx_data.sip)); + strcpy((char*)ipx_data.sip.server_name, nw->name); + memcpy(&ipx_data.sip.server_adr, &nw->addr, sizeof(ipxAddr_t)); + XDPRINTF((4, 0, "%s SERVER=%s, typ=0x%x, ticks=%d, hops=%d", + (respond_typ==4) ? "NEAREST" : "GENERAL", nw->name, + nw->typ, ticks, hops)); + U16_TO_BE16(respond_typ, ipx_data.sip.response_type); + U16_TO_BE16(nw->typ, ipx_data.sip.server_type); + U16_TO_BE16(hops, ipx_data.sip.intermediate_networks); + send_ipx_data(sockfd[SAP_SLOT], + 4, /* this is the official packet typ for SAP's */ + sizeof(ipx_data.sip), + (char *)&(ipx_data.sip), + to_addr, "Sap Server Response"); + } +} + void send_server_response(int respond_typ, - int styp, ipxAddr_t *to_addr) + int styp, ipxAddr_t *to_addr) /* respond_typ 2 = general, 4 = nearest service respond */ { - IPX_DATA ipx_data; int j=-1; - int tics=99; + int ticks=99; int hops=15; int entry = -1; - memset(&ipx_data, 0, sizeof(ipx_data.sip)); + int to_internal = (!no_internal) + && (GET_BE32(to_addr->net) == internal_net) + && (GET_BE16(to_addr->sock) != SOCK_SAP); while (++j < anz_servers) { NW_SERVERS *nw=nw_servers[j]; if (nw->typ == styp && nw->name && *(nw->name)) { - int xtics=999; + int xticks=999; if (nw->net != internal_net) { NW_NET_DEVICE *nd=find_netdevice(nw->net); - if (nd) xtics = nd->ticks; - } else xtics =0; - if (xtics < tics || (xtics == tics && nw->hops <= hops)) { - tics = xtics; + if (nd) xticks = nd->ticks; + if (to_internal) + send_sap_to_addr(j, nw->hops+1, xticks, respond_typ, to_addr); + } else xticks = 0; + if (xticks < ticks || (xticks == ticks && nw->hops <= hops)) { + ticks = xticks; hops = nw->hops; entry = j; } } } - if (entry > -1) { - NW_SERVERS *nw=nw_servers[entry]; - strcpy((char*)ipx_data.sip.server_name, nw->name); - memcpy(&ipx_data.sip.server_adr, &nw->addr, sizeof(ipxAddr_t)); - hops++; - XDPRINTF((4, 0, "NEAREST SERVER=%s, typ=0x%x, ticks=%d, hops=%d", - nw->name, styp, tics, hops)); - U16_TO_BE16(respond_typ, ipx_data.sip.response_type); - U16_TO_BE16(styp, ipx_data.sip.server_type); - U16_TO_BE16(hops, ipx_data.sip.intermediate_networks); - send_ipx_data(sockfd[SAP_SLOT], - 4, /* this is the official packet typ for SAP's */ - sizeof(ipx_data.sip), - (char *)&(ipx_data.sip), - to_addr, "Nearest Server Response"); + if (!to_internal) + send_sap_to_addr(entry, hops+1, ticks, respond_typ, to_addr); +} + + +static void send_sip_to_net(uint32 nd_net, int nd_ticks, int mode) +{ + ipxAddr_t wild; + int j=-1; + memset(&wild, 0, sizeof(ipxAddr_t)); + U32_TO_BE32(nd_net, wild.net); + memset(wild.node, 0xFF, IPX_NODE_SIZE); + U16_TO_BE16(SOCK_SAP, wild.sock); + while (++j < anz_servers) { + NW_SERVERS *nw=nw_servers[j]; + if ( !nw->typ /* server has no typ */ + || ( nw->net == nd_net && nw->hops) /* server has same net but */ + /* hops */ + || ( mode == 2 && nw->hops) ) { /* no SAP to this NET */ + XDPRINTF((3, 0, "No SAP mode=%d, to net=0x%lx for server '%s'", + mode, nd_net, nw->name)); + continue; + } + send_sap_to_addr(j, (mode == 2) ? 16 : nw->hops+1, + nd_ticks, + 2, /* General */ + &wild); } } @@ -482,42 +520,7 @@ static void send_sap_broadcast(int mode) NW_NET_DEVICE *nd=net_devices[k]; if (nd->is_up && (nd->ticks < 7 || mode)) { /* isdn devices should not get SAP broadcasts everytime */ - IPX_DATA ipx_data; - ipxAddr_t wild; - int j=-1; - memset(&wild, 0, sizeof(ipxAddr_t)); - U32_TO_BE32(nd->net, wild.net); - memset(wild.node, 0xFF, IPX_NODE_SIZE); - U16_TO_BE16(SOCK_SAP, wild.sock); - while (++j < anz_servers) { - NW_SERVERS *nw=nw_servers[j]; - if ( !nw->typ /* server has no typ */ - || ( nw->net == nd->net && nw->hops) /* server has same net but */ - /* hops */ - || ( mode == 2 && nw->hops) ) { /* no SAP to this NET */ - XDPRINTF((3, 0, "No SAP mode=%d, to net=0x%lx for server '%s'", - mode, nd->net, nw->name)); - continue; - } - memset(&ipx_data, 0, sizeof(ipx_data.sip)); - strcpy(ipx_data.sip.server_name, nw->name); - memcpy(&ipx_data.sip.server_adr, &(nw->addr), sizeof(ipxAddr_t)); - U16_TO_BE16(2, ipx_data.sip.response_type); /* General */ - U16_TO_BE16(nw->typ, ipx_data.sip.server_type); /* Fileserver */ - if (mode == 2) { - U16_TO_BE16(16, ipx_data.sip.intermediate_networks); - } else { - U16_TO_BE16(nw->hops+1, ipx_data.sip.intermediate_networks); - /* I hope hops are ok here */ - XDPRINTF((3, 0, "SEND SIP %s,0x%04x, hops=%d", - nw->name, nw->typ, nw->hops+1)); - } - send_ipx_data(sockfd[SAP_SLOT], - 4, /* this is the official packet typ for SAP's */ - sizeof(ipx_data.sip), - (char *)&(ipx_data.sip), - &wild, "SIP Broadcast"); - } + send_sip_to_net(nd->net, nd->ticks, mode); } } } diff --git a/nwserv.c b/nwserv.c index 03d589a..434a881 100644 --- a/nwserv.c +++ b/nwserv.c @@ -21,8 +21,12 @@ #include "net.h" #include "nwserv.h" +#ifdef LINUX +# include +#endif + uint32 internal_net = 0x0L; /* NETWORKNUMMER INTERN (SERVER) */ -int no_internal = 0; /* no use of internal net */ +int no_internal = 0; /* no use of internal net */ int auto_creat_interfaces=0; ipxAddr_t my_server_adr; /* Address of this server */ @@ -438,7 +442,7 @@ static void modify_wdog_conn(int conn, int mode) case 2 : c->counter = max(2, MAX_WDOG_TRIES); /* slow test (activate)*/ break; - default : c->counter = 0; /* reset */ + default : c->counter = 0; /* reset */ break; } /* switch */ } else if (mode == 99) { /* remove */ @@ -514,17 +518,17 @@ static int name_match(uint8 *s, uint8 *p) while ( (pc = *p++) != 0){ switch (pc) { case '?' : if (!*s++) return(0); /* simple char */ - break; + break; case '*' : if (!*p) return(1); /* last star */ - while (*s) { - if (name_match(s, p) == 1) return(1); - ++s; - } - return(0); + while (*s) { + if (name_match(s, p) == 1) return(1); + ++s; + } + return(0); default : if (pc != *s++) return(0); /* normal char */ - break; + break; } /* switch */ } /* while */ return ( (*s) ? 0 : 1); @@ -837,18 +841,37 @@ static void get_ini(int full) } break; +#if INTERNAL_RIP_SAP case 3 : if (full) { - if (sscanf(inhalt, "%ld%c", &internal_net, &dummy) != 1) - sscanf(inhalt, "%lx", &internal_net); + upstr(inhalt); + if (!strcmp(inhalt, "AUTO")) internal_net = 0; + else { + if (sscanf(inhalt, "%ld%c", &internal_net, &dummy) != 1) + sscanf(inhalt, "%lx", &internal_net); + } if (anz > 1) { if (sscanf(inhalt2, "%ld%c", &node, &dummy) != 1) sscanf(inhalt2, "%lx", &node); } + if (0 == internal_net) { /* now we try ip number */ + char locname[50]; + struct hostent *hent; + gethostname(locname, 48); + hent=gethostbyname(locname); + if (NULL != hent && hent->h_length == 4) { + internal_net = GET_BE32(*(hent->h_addr_list)); + } else { + XDPRINTF((0, 0, "Cannot gethostbyname from '%s'", + locname)); + if (hent) { + XDPRINTF((0, 0, "hent->h_length=%d", hent->h_length)); + } + } + } } break; -#if INTERNAL_RIP_SAP case 4 : if (full) { if (anz_net_devices < MAX_NET_DEVICES && @@ -978,11 +1001,12 @@ static void get_ini(int full) } # endif #endif + if (!get_ipx_addr(&my_server_adr)) { internal_net = GET_BE32(my_server_adr.net); } else exit(1); -#if LINUX && INTERNAL_RIP_SAP +#if INTERNAL_RIP_SAP if (no_internal) { errorp(10, "WARNING:No use of internal net", NULL); } else if (!anz_net_devices) { @@ -1111,6 +1135,21 @@ static void set_sigs(void) static int server_is_down=0; +static int usage(char *prog) +{ +#if !IN_NWROUTED + fprintf(stderr, "usage:\t%s [-h|-k|y]\n", prog); +#else + fprintf(stderr, "usage:\t%s [-h]|-k]\n", prog); +#endif + fprintf(stderr, "\t-h: send HUP to main process\n"); + fprintf(stderr, "\t-k: stop main process\n"); +#if !IN_NWROUTED + fprintf(stderr, "\t y: start testclient code.\n"); +#endif + return(1); +} + int main(int argc, char **argv) { int j = 0; @@ -1123,12 +1162,16 @@ int main(int argc, char **argv) switch (*a) { case 'h' : init_mode = 1; break; case 'k' : init_mode = 2; break; - default : break; + default : return(usage(argv[0])); } } - } else if (*a == 'y') client_mode=1; + } else if (*a == 'y') + client_mode=1; /* in client mode the testprog 'nwclient' will be startet. */ + else + return(usage(argv[0])); } + setgroups(0, NULL); init_tools(IN_PROG, init_mode); get_ini(1); j=-1; diff --git a/nwvolume.c b/nwvolume.c index 434f6dc..09f03a5 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 22-Apr-96 */ +/* nwvolume.c 11-May-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -94,6 +94,10 @@ void nw_init_volumes(FILE *f) |= VOL_OPTION_IS_PIPE; break; + case 'r' : vol->options + |= VOL_OPTION_READONLY; + break; + default : break; } } @@ -273,7 +277,17 @@ int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu) /* returns 0 if OK, else errocode < 0 */ { int volnr = nw_get_volume_number(volname, strlen((char*)volname)); - return((volnr>-1 && !get_fs_usage((char*)nw_volumes[volnr].unixname, fsu)) ? 0 : -1); + if (volnr > -1) { + NW_VOL *v=&(nw_volumes[volnr]); + if (0 == (volnr=get_fs_usage((char*)v->unixname, fsu))) { + if (v->options & VOL_OPTION_READONLY) { + fsu->fsu_bfree = 0; + fsu->fsu_bavail = 0; + fsu->fsu_ffree = 0; + } + } + } + return(volnr); } int get_volume_options(int volnr, int mode) diff --git a/nwvolume.h b/nwvolume.h index 0745082..f6b0971 100644 --- a/nwvolume.h +++ b/nwvolume.h @@ -1,4 +1,4 @@ -/* nwvolume.h 29-Mar-96 */ +/* nwvolume.h 11-May-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -39,7 +39,7 @@ typedef struct { int max_maps_count; /* may be less than MAX_DEV_NAMESPACE_MAPS */ int maps_count; /* count of dev_namespace_maps */ uint32 high_inode; /* hight inode to can handle correct */ - int options; /* *_1_* all is lowercase */ + int options; /* see defines below */ } NW_VOL; #define VOL_OPTION_DOWNSHIFT 0x01 /* All downshift */ @@ -47,6 +47,7 @@ typedef struct { #define VOL_OPTION_REMOUNT 0x04 /* Volume can be remounted (cdroms) */ #define VOL_OPTION_IS_HOME 0x08 /* Volume is USERS HOME */ #define VOL_OPTION_ONE_DEV 0x10 /* Volume has only one filesys */ +#define VOL_OPTION_READONLY 0x20 /* Volume is readonly */ /* stolen from GNU-fileutils */ /* Space usage statistics for a filesystem. Blocks are 512-byte. */ diff --git a/tools.c b/tools.c index c65f49c..9491f15 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 06-May-96 */ +/* tools.c 13-May-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -266,7 +266,7 @@ static char *get_pidfilefn(char *buf) { char lbuf[100]; strcpy(lbuf, get_modstr()); - return(get_div_pathes(buf, downstr((uint8*)lbuf), 2, ".pid")); + return(get_div_pathes(buf, (char*)downstr((uint8*)lbuf), 2, ".pid")); } void creat_pidfile(void) @@ -293,30 +293,33 @@ void init_tools(int module, int options) in_module = module; connection = (NWCONN == module) ? options : 0; if (NWSERV == module || NWROUTED == module) { - char *pidfn=get_pidfilefn(buf); + int kill_pid=-1; + char *pidfn=get_pidfilefn((char*)buf); if (fn_exist(pidfn)) { + FILE *pf=fopen(pidfn, "r"); + if ( NULL != pf) { + if (1 != fscanf(pf, "%d", &kill_pid) || kill_pid < 1 + || kill(kill_pid, 0) < 0) + kill_pid=-1; + fclose(pf); + } + if (kill_pid < 0) unlink((char*)buf); + } + if (kill_pid > -1) { int sig; - FILE *pf; if (options == 1) { /* kill -HUP prog */ sig = SIGHUP; } else if (options == 2) { /* kill prog */ sig = SIGTERM; } else { - errorp(11, "INIT", "Program allways running or pidfn=%s exists" , - pidfn); + errorp(11, "INIT", "Program pid=%d already running and pidfn=%s exists" , + kill_pid, pidfn); exit(1); } - if ( NULL != (pf=fopen(pidfn, "r"))) { - int kill_pid=0; - if (1 == fscanf(pf, "%d", &kill_pid) && kill_pid > 1) - kill(kill_pid, sig); - fclose(pf); - exit(0); - } - exit(1); + if (kill_pid > 1) kill(kill_pid, sig); + exit(0); } else if (options == 1 || options == 2) { - errorp(11, "INIT", "Program not running or pidfn=%s not exists" , - pidfn); + errorp(11, "INIT", "Program not running yet" ); exit(1); } }