mars_nwe-0.99.pl19

This commit is contained in:
Mario Fetka 2011-11-13 00:38:59 +01:00
parent 5c18363271
commit c1c64c1591
75 changed files with 11044 additions and 4466 deletions

1687
connect.c

File diff suppressed because it is too large Load Diff

121
connect.h
View File

@ -1,29 +1,7 @@
/* connect.h 01-Feb-98 */ /* connect.h 04-Apr-00 */
#ifndef _CONNECT_H_ #ifndef _CONNECT_H_
#define _CONNECT_H_ #define _CONNECT_H_
/* some TRUSTEE defines */
#define TRUSTEE_R 0x01 /* Read Rights */
#define TRUSTEE_W 0x02 /* Write Rights */
#define TRUSTEE_O 0x04 /* Open, not used ?? by Novell */
#define TRUSTEE_C 0x08 /* Creat */
#define TRUSTEE_E 0x10 /* Erase */
#define TRUSTEE_A 0x20 /* Access Control */
#define TRUSTEE_F 0x40 /* File Scan */
#define TRUSTEE_M 0x80 /* Modify */
/* ........................................ */
#define TRUSTEE_S 0x100 /* Supervisor */
/* <-------------- File Attributes -------------> */
#define FILE_ATTR_NORMAL 0x00000000
#define FILE_ATTR_R 0x00000001
#define FILE_ATTR_H 0x00000002
#define FILE_ATTR_S 0x00000004
#define FILE_ATTR_DIR 0x00000010
#define FILE_ATTR_A 0x00000020
#define FILE_ATTR_SHARE 0x00000080
typedef struct { typedef struct {
uint8 path[256]; /* directory */ uint8 path[256]; /* directory */
uint8 fn[256]; /* file */ uint8 fn[256]; /* file */
@ -33,8 +11,7 @@ typedef struct {
typedef struct { typedef struct {
uint8 name[14]; /* filename in DOS format */ uint8 name[14]; /* filename in DOS format */
uint8 attrib; /* Attribute */ uint8 attrib[2]; /* LO-HI attrib, ext_attrib */
uint8 ext_attrib; /* File Execute Type */
uint8 size[4]; /* size of file */ uint8 size[4]; /* size of file */
uint8 create_date[2]; uint8 create_date[2];
uint8 acces_date[2]; uint8 acces_date[2];
@ -44,8 +21,7 @@ typedef struct {
typedef struct { typedef struct {
uint8 name[14]; /* dirname */ uint8 name[14]; /* dirname */
uint8 attrib; uint8 attrib[2]; /* LO-HI attrib, ext_attrib */
uint8 ext_attrib;
uint8 create_date[2]; uint8 create_date[2];
uint8 create_time[2]; uint8 create_time[2];
uint8 owner_id[4]; uint8 owner_id[4];
@ -63,7 +39,7 @@ typedef struct {
typedef struct { typedef struct {
uint8 subdir[4]; uint8 subdir[4];
uint8 attributes[4]; /* 0x20,0,0,0 File */ uint8 attributes[4]; /* 0x20,0,0,0 LO-HI */
uint8 uniqueid; /* 0 */ uint8 uniqueid; /* 0 */
uint8 flags; /* 0x18 */ uint8 flags; /* 0x18 */
uint8 namespace; /* 0 */ uint8 namespace; /* 0 */
@ -81,7 +57,7 @@ typedef struct {
typedef struct { typedef struct {
uint8 subdir[4]; uint8 subdir[4];
uint8 attributes[4]; /* 0x10,0,0,0 DIR */ uint8 attributes[4]; /* 0x10,0,0,0 LO-HI */
uint8 uniqueid; /* 0 */ uint8 uniqueid; /* 0 */
uint8 flags; /* 0x14 or 0x1c */ uint8 flags; /* 0x14 or 0x1c */
uint8 namespace; /* 0 */ uint8 namespace; /* 0 */
@ -106,11 +82,22 @@ typedef struct {
} u; } u;
} NW_SCAN_DIR_INFO; } NW_SCAN_DIR_INFO;
typedef struct {
uint8 searchsequence[4]; /* same as NW_SCAN_DIR_INFO */
uint8 change_bits[4]; /* LO-HI, 2=Attributes */
union {
NW_DOS_DIR_INFO d;
NW_DOS_FILE_INFO f;
} u;
} NW_SET_DIR_INFO;
extern int use_mmap; extern int use_mmap;
extern int tells_server_version; extern int tells_server_version;
extern int server_version_flags; extern int server_version_flags;
extern int max_burst_send_size; extern int max_burst_send_size;
extern int max_burst_recv_size; extern int max_burst_recv_size;
extern int default_uid;
extern int default_gid;
extern int nw_init_connect(void); extern int nw_init_connect(void);
extern void nw_exit_connect(void); extern void nw_exit_connect(void);
@ -120,20 +107,25 @@ extern int nw_free_handles(int task);
extern int nw_creat_open_file(int dir_handle, uint8 *data, int len, extern int nw_creat_open_file(int dir_handle, uint8 *data, int len,
NW_FILE_INFO *info, int attrib, int access, int mode, int task); NW_FILE_INFO *info, int attrib, int access, int mode, int task);
extern int nw_delete_datei(int dir_handle, uint8 *data, int len); extern int nw_delete_files(int dir_handle, int searchattrib, uint8 *data, int len);
extern int nw_set_file_information(int dir_handle, uint8 *data, int len, extern int nw_set_file_information(int dir_handle, uint8 *data, int len,
int searchattrib, NW_FILE_INFO *f); int searchattrib, NW_FILE_INFO *f);
extern int nw_set_file_attributes(int dir_handle, uint8 *data, int len, extern int nw_set_file_attributes(int dir_handle, uint8 *data, int len,
int attrib, int newattrib); int attrib, int newattrib);
extern int mv_file(int qdirhandle, uint8 *q, int qlen, extern int nw_mv_files(int searchattrib,
int zdirhandle, uint8 *z, int zlen); int sourcedirhandle, uint8 *sourcedata, int qlen,
int zdirhandle, uint8 *destdata, int destdatalen);
extern int mv_dir(int dir_handle, uint8 *q, int qlen, extern int mv_dir(int dir_handle, uint8 *sourcedata, int qlen,
uint8 *z, int zlen); uint8 *destdata, int destdatalen);
extern int nw_creat_node(int volnr, uint8 *unname, int mode); extern int nw_unlink_node(int volume, uint8 *unname, struct stat *stb);
extern int nw_creat_node(int volume, uint8 *unname, int mode);
extern int nw_utime_node(int volume, uint8 *unname, struct stat *stb,
time_t t);
extern int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode); extern int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode);
@ -163,7 +155,8 @@ extern int nw_alloc_dir_handle(
int driveletter, /* A .. Z normal */ int driveletter, /* A .. Z normal */
int is_temphandle, /* temp Handle 1 */ int is_temphandle, /* temp Handle 1 */
/* spez. temp Handle 2 */ /* spez. temp Handle 2 */
int task); /* Prozess Task */ int task, /* Prozess Task */
int *eff_rights);
extern int nw_open_dir_handle( int dir_handle, extern int nw_open_dir_handle( int dir_handle,
@ -182,7 +175,7 @@ extern int alter_dir_handle(int targetdir, int volume, uint8 *path,
extern int nw_set_dir_handle(int targetdir, int dir_handle, extern int nw_set_dir_handle(int targetdir, int dir_handle,
uint8 *data, int len, int task); uint8 *data, int len, int task);
extern int nw_get_directory_path(int dir_handle, uint8 *name); extern int nw_get_directory_path(int dir_handle, uint8 *name, int size_name);
extern int nw_get_vol_number(int dir_handle); extern int nw_get_vol_number(int dir_handle);
@ -199,24 +192,29 @@ extern int nw_scan_dir_info(int dir_handle, uint8 *data, int len,
extern void get_dos_file_attrib(NW_DOS_FILE_INFO *f, extern void get_dos_file_attrib(NW_DOS_FILE_INFO *f,
struct stat *stb, struct stat *stb,
int volume, int volume,
uint8 *path); uint8 *path,
char *unixname);
void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
struct stat *stb, struct stat *stb,
int volume, int volume,
uint8 *path); uint8 *path,
char *unixname);
#define MAX_NW_DIRS 255 #define MAX_NW_DIRS 255
extern int act_uid; extern int act_uid;
extern int act_gid; extern int act_gid;
extern int act_obj_id; /* not login == 0 */ extern int act_obj_id; /* not login == 0 */
extern int act_id_flags; /* &1 == supervisor equivalence !!! */
extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */ extern int entry8_flags; /* special flags, see examples nw.ini, entry 8 */
extern int entry31_flags; /* special flags, see examples nw.ini, entry 31 */
extern int conn_get_full_path(int dirhandle, uint8 *data, int len, extern int conn_get_full_path(int dirhandle, uint8 *data, int len,
uint8 *fullpath); uint8 *fullpath, int size_fullpath);
extern int conn_get_kpl_unxname(char *unixname, extern int conn_get_kpl_unxname(char *unixname,
int size_unixname,
int dirhandle, int dirhandle,
uint8 *data, int len); uint8 *data, int len);
@ -225,14 +223,15 @@ extern void set_guid(int gid, int uid);
extern void reset_guid(void); extern void reset_guid(void);
extern void reseteuid(void); extern void reseteuid(void);
extern int in_act_groups(gid_t gid); extern int in_act_groups(gid_t gid);
extern int get_unix_eff_rights(struct stat *stb);
extern void set_nw_user(int gid, int uid, extern void set_nw_user(int gid, int uid,
int id_flags,
uint32 obj_id, uint8 *objname, uint32 obj_id, uint8 *objname,
int homepathlen, uint8 *homepath); int unxloginlen, uint8 *unxloginname,
int grpcount, uint32 *grps);
extern int get_real_access(struct stat *stb);
extern uint32 get_file_owner(struct stat *stb); extern uint32 get_file_owner(struct stat *stb);
extern int nw_scan_a_directory(uint8 *rdata, extern int nw_scan_a_directory(uint8 *rdata,
int dirhandle, int dirhandle,
uint8 *data, uint8 *data,
@ -243,18 +242,18 @@ extern int nw_scan_a_directory(uint8 *rdata,
extern int nw_scan_a_root_dir(uint8 *rdata, extern int nw_scan_a_root_dir(uint8 *rdata,
int dirhandle); int dirhandle);
extern int nw_set_a_directory_entry(int dirhandle,
uint8 *data,
int len,
int searchattrib,
uint32 searchbeg,
NW_SET_DIR_INFO *f);
extern int fn_dos_match(uint8 *s, uint8 *p, int options); extern int fn_dos_match(uint8 *s, uint8 *p, int options);
extern void un_date_2_nw(time_t time, uint8 *d, int high_low); extern void un_date_2_nw(time_t time, uint8 *d, int high_low);
extern time_t nw_2_un_time(uint8 *d, uint8 *t); extern time_t nw_2_un_time(uint8 *d, uint8 *t);
#if !NEW_ATTRIB_HANDLING
extern int un_nw_attrib(struct stat *stb, int attrib, int mode);
#endif
extern int un_nw_rights(struct stat *stb);
extern void un_time_2_nw(time_t time, uint8 *d, int high_low); extern void un_time_2_nw(time_t time, uint8 *d, int high_low);
extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp); extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp);
@ -262,5 +261,29 @@ extern void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp);
extern int nw_add_trustee(int dir_handle, uint8 *data, int len, extern int nw_add_trustee(int dir_handle, uint8 *data, int len,
uint32 id, int trustee, int extended); uint32 id, int trustee, int extended);
extern int nw_del_trustee(int dir_handle, uint8 *data, int len,
uint32 id, int extended);
extern int nw_set_dir_info(int dir_handle, uint8 *data, int len,
uint32 owner_id, int max_rights,
uint8 *creationdate, uint8 *creationtime);
extern int nw_scan_user_trustee(int volume, int *sequence, uint32 id,
int *access_mask, uint8 *path);
extern int nw_scan_for_trustee( int dir_handle,
int sequence,
uint8 *path,
int len,
int max_entries,
uint32 *ids,
int *trustees,
int extended);
extern int nw_log_file(int lock_flag,
int timeout,
int dir_handle,
int len,
char *data);
#endif #endif

View File

@ -1,4 +1,4 @@
/* dbmtool.c 08-Sep-96 data base tool program for mars_nwe */ /* dbmtool.c 10-Nov-99 data base tool program for mars_nwe */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -32,18 +32,23 @@ static int usage(char *s)
fprintf(stderr, "\te = export\n"); fprintf(stderr, "\te = export\n");
fprintf(stderr, "\ti = import\n"); fprintf(stderr, "\ti = import\n");
fprintf(stderr, "\tr = repair\n"); fprintf(stderr, "\tr = repair\n");
fprintf(stderr, "\tE = Export To DIR\n");
return(1); return(1);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
init_tools(0, 0); init_tools(0, 0);
nw_debug=5;
if (argc < 2) return(usage(argv[0])); if (argc < 2) return(usage(argv[0]));
if (*argv[1] == 'e') return(do_export_dbm(argv[2])); if (*argv[1] == 'e') return(do_export_dbm(argv[2]));
else if (*argv[1] == 'i') return(do_import_dbm(argv[2])); else if (*argv[1] == 'i') return(do_import_dbm(argv[2]));
else if (*argv[1] == 'r') if (!do_export_dbm(argv[2])) else if (*argv[1] == 'r') {
if (!do_export_dbm(argv[2]))
return(do_import_dbm(argv[2])); return(do_import_dbm(argv[2]));
else return(1); else return(1);
}
if (*argv[1] == 'E') return(do_export_dbm_to_dir());
else usage(argv[0]); else usage(argv[0]);
return(0); return(0);
} }

View File

@ -15,6 +15,8 @@
#define D_FN_NAMES 8 #define D_FN_NAMES 8
#define D_FN_SEARCH 0x10 /* file search */ #define D_FN_SEARCH 0x10 /* file search */
#define D_ACCESS 0x20 /* access rights */
#define D_TRUSTEES 0x40 /* trustees */
/* NWBIND */ /* NWBIND */
#define D_BIND_REQ 0x8000 /* all Requests */ #define D_BIND_REQ 0x8000 /* all Requests */

43
doc/BUGS.nl Normal file
View File

@ -0,0 +1,43 @@
Als je problemen heb:
-----------------
- Kijk of je in de kernel wel IPX heb geinstalleerd
CONFIG_IPX=y ( of m en het ipx module is geladen (insmod ipx))
- Kijk of je geen intern IPX netwerk hebt geinstalleerd 'full
internal net'. (kernel optie)
CONFIG_IPX_ITERN=n
- Lees altijd de documentatie: doc/INSTALL[.ger/.nl],
doc/README[.ger/.nl], doc/FAQS en examples/nw.ini
Zeer belangrijke secties in nwserv.conf(nw.ini) zijn:
Sectie 1: Volumes
Sectie 3: Number of the internal network
Sectie 4: IPX-devices
Sectie 5: device flags
Sectie 6: version-"spoofing"
Sectie 12: supervisor-login
Als je niet kunt inloggen, probeer het dan eens met de meegeleverde
configuratie bestanden, zonder deze te veranderen.
- Belangrijk nieuws staat in doc/NEWS.
- zet de debug switches in sectie 101 .. 10x op '1',
probeer het opnieuw met het herstarten van nwserv en kijk in het
log bestand in /tmp/nw.log
Misschien begrijp je het probleem dan. :)
Sommige kleine aantekeningen voor probleem- of bug-'reporters'.
---------------------------------------------------------------
- Geef je systeem waarop je draait door en de volledige mars_nwe
versie, bijvoorbeeld:
mars_nwe versie: 0.99.pl14
linux-kernel: 2.2.0p9
het type client: (NCPFS, DOS (NETX/VLM), OS2, WIN, Novell client
32 WIN ..)
de veranderingen in nwserv.conf(nw.ini) en de config.h
- als je nwserv.conf opstuurd, haal het commentaar eruit.
doe dit door in te tikken 'make showconf' in de mars_nwe source dir
of doe 'grep "^[ \t*[0-9]" /etc/nwserv.conf'
- vermeld of je client wel loopt met een 'echte Novell-server'
(als je er een hebt. ;) )
Bekende problemen / oplossingen:
--------------------------------
- kijk is doc/FAQS

View File

@ -1,6 +1,8 @@
Sorry, this is in German only. Sorry, beginning is in German only.
User important notes are in the NEWS file. User important notes are in the NEWS file.
Aenderungen in mars_nwe bis zum : 03-Nov-97 Aenderungen in mars_nwe bis zum:
Changes in mars_nwe till:
=> 30-May-00 <=
-------------------------------- --------------------------------
Erste 'oeffentliche' Version Erste 'oeffentliche' Version
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -408,6 +410,131 @@ Erste 'oeffentliche' Version
- archive bit ist bei Dateien nun default gesetzt. - archive bit ist bei Dateien nun default gesetzt.
- archive bit wird nun bei Client Schreiboperationen gesetzt. - archive bit wird nun bei Client Schreiboperationen gesetzt.
<----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- in examples/config.h. NEW_ATTRIB_HANDLING removed.
- connect.c: nw_dir_search() corrected for new get_dir_attrib.
- changed some includes and defines for (g)libc6 / RH5.
- added some fixes from Andrew Sapozhnikov <sapa@hq.icb.chel.su>
fixed prop_find_member bug, !!!!!!!! VERY important !!!!!!
fixed add and delete property_val,
fixed dos search routine.
- new startup bindery check/compress routine.
- prop_delete_member changed to avoid holes (id==0) in a set section.
- bindery function creat_new_db() now saves old files to xyz/nwdbm.sav/.
<----- ^^^^^^^^^^ pl7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- queue code changed. WinNT did not print every job.
should also solve some strange problems under W95 and dos clients.
- old dos search routine is now reused again for namespace calls, because
new dos search routine from Andrew did not work with this calls.
( xcopy32 *.* did not work for for non OS/2 namespace volumes )
<----- ^^^^^^^^^^ pl8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- nwqconn.c:open_creat_queue_file(): insert missing nw_free_dir_handle()
- nwdbm.c: enhanced section 22, now normal user/client may act as print-
qserver.
- nwfile.c: removed bug in file read routine when reading a pipe.
- nwqueue.c: nw_service_queue_job()
queue files of length 0 are now deleted automaticly 1 minute
after creation, if they are serviced by a queue server.
- nwqueue.c: new: nw_close_connection_jobs()
- nwqconn.c: new: free_connection_task_jobs()
- added first simple trustee routines. ( new volume switch 't' )
see doc/TRUSTEES
- added supervisor security equals handling.
- changed device configurator a little bit so that running
ipx programs like ncpmount will not be killed by a
starting or stopping nwserv.
- changed default attrib/trustee location from /var/lib/nwserv -> /var/nwserv
- some cleanings to make UnixWare happy.
- close_file() only closes file if task correspond with file opened task.
Do not know whether this is ok, but it seems so.
Programs like Visual C linker (Borland,MS) now work correct.
<----- ^^^^^^^^^^ pl9 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- changed call 0x17, 0x0f, to let it handle only files not directories.
(mask 0x10 attrib flag )
- new dos search routine (from pl7) changed to handle '*' correct, for
example the call 0x17, 0x0f is called by syscons change file trustees
with '*' as searchstring. Also changed to handle '*xyz.xyz' in a
more restrictive way. I hope this is correct now.
<----- ^^^^^^^^^^ pl10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ncp call 0x7a (read queue job entry (new)) is now availible.
<----- ^^^^^^^^^^ pl11 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- changed default bindery directory location:
/etc -> /var/nwserv/db ( section 45 )
- possibility to unset the print banner flag.
( some strange W95 printer drivers always set banner flag to TRUE )
- port to FreeBSD by Boris Popov <bp@butya.kz>
<----- ^^^^^^^^^^ pl12 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- small FreeBSD patch from Boris Popov. (nwroute1.c)
- added diagnostic-answers routine from Valeri Bourak. (nwserv.c)
- small pipe-filesystem patches.
- changed example programs (unxcomm/comm) for pipe-filesystem access.
- BUG in unx_xrmdir(),unxfile.c removed, opendir() was called twice.
- added namespace calls (0x57) add,delete trustee routines.
- new function 'Get Queue Job List' (0x17,0x81) added.
- new function 'Set Queue Status' (0x17,0x67/0x7e) added.
- debug/log file now with date/time
- nw_close_file() now closes files again which were opened
with different task. ( was inserted in pl9 )
- open_creat_queue_file() routine only sets the file noreuse flag
if file is opened for writing.
- fn_dos_match routine corrected, was broken in pl7. ( ndir.exe works again )
<----- ^^^^^^^^^^ pl13 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- now section 1 permissions works for '~' ('HOME') entries too
- get_fs_usage now also sets fsu_bavail to limit.
- new flag 'T' for volumes which has trustees & ignore the rights granted
in UN*X filesystem, added by Norbert Nemec <nobbi@cheerful.com>
- added 'inherited_rights_mask handling' to some routines.
- nwfile.c. Filehandle can now be used for more than one open.
Don't know whether this is correct. Under W95 client the dos
programm 'blinker' needs it.
- nw_rmdir() in connect.c now returns correct error code if directory
cannot be removed because it is not empty.
<----- ^^^^^^^^^^ pl14 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- doc/PIPE-FS.ger with new examples from Sascha Herrmann
- added '#define _SVID_SOURCE' and '#define _XOPEN_SOURCE'
in net.h to let mars_nwe work with glibc.
- connect.c, free_dir_stuff(), correcting error when recursively deleting a
largish directory tree, hint from Boris Popov, 21-Feb-99.
- Get Queue Job List (new) now returns info in right byte order.
Error appeared under Win9x with Novell Client32 when printing.
( segmentation error in spool32 ) bug corrected by georg@globaltrading.net.
<----- ^^^^^^^^^^ pl15 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- docs from Mendel Mobach (xxx.nl)
- some fixes to let mars_nwe compile under 2.2.x kernels.
- some BSD fixes from Boris Popov
- fix from Paolo Prandini for the wrong return code when an user without
supervisory rights tries to shutdown the server
- nw_open_creat_file_or_dir() now does not creat file if called with
opencreatmode==8 and file already exist. ( important for Win98 )
- dos 'rename files' now works with wildcards on both side (source and dest)
- nw_close_file() normally do not close files which were opened
with different task ( same as in pl9 ). But files are allways closed if
they are created with task 0 or if current task = 0.
- Routine which opened same file for more than one time deactivated,
because share conditions were wrong. Function was added in pl14.
Perhaps this routine will not be needed anymore.
- new signal SIGUSR2 for nwconn process to give info about open files.
the loginfo is placed into /tmp/nwconnxxxx.log
<----- ^^^^^^^^^^ pl16 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- rename file corrected. Error inserted in 0.99.pl16
- small patch in tools.c ( initialisation of logfile )
<----- ^^^^^^^^^^ pl17 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- prevent some possible buffer overflows.
security hint from Przemyslaw Frasunek <venglin@FREEBSD.LUBLIN.PL>
- better file share/lockings, with code from
Ingmar Thiemann <ingmar@gefas.com> and Przemyslaw Czerpak
- function Log Logical Record (NCP 0x9) aktivated
and lock flag 0x2 ( sharable ro lock ) added.
- function Log File (NCP 0x3) aktivated
and lock flag 0x2 ( sharable ro lock ) added.
- Clear File / Release File added.
- passwords with '-' at beginning should now be allowed in nwserv.conf.
- better trustee handling.
<----- ^^^^^^^^^^ pl18 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- security fixes. ( unlink() before fopen() )
- fixed routine 0x57/0x18, Get Name Spaces Loaded
- Login Restriction Routines from Paolo Prandini
- removed bug from pl18 for empty passwords and
passwords beginning with '-'. ( tnx Przemyslaw Czerpak )
- trustee fix
<----- ^^^^^^^^^^ pl19 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -16,6 +16,9 @@ Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de> Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
many testings+notes many testings+notes
Valeri Bourak <bvn@kali.belpak.minsk.by>
added some code
Arne de Bruijn <arne@knoware.nl> Arne de Bruijn <arne@knoware.nl>
testings, exploring ncp mysterius (netx), notes testings, exploring ncp mysterius (netx), notes
@ -26,17 +29,26 @@ Csoma Csaba <csoma@usa.net>
testings+bugfixes testings+bugfixes
Przemyslaw Czerpak <przemyslaw.czerpak@students.mimuw.edu.pl> Przemyslaw Czerpak <przemyslaw.czerpak@students.mimuw.edu.pl>
testings+bugfixes testings+bugfixes+more bugfixes (pcz:)
Ales Dryak <A.Dryak@sh.cvut.cz> Ales Dryak <A.Dryak@sh.cvut.cz>
his linware gave the kick his linware gave the kick
Fritz Elfert <fritz@wuemaus.franken.de> Fritz Elfert <fritz@wuemaus.franken.de>
gives bugreport and patches give bugreport and patches
Przemyslaw Frasunek <venglin@FreeBSD.lublin.pl>
hints for possible security bugs
Peter Gerhard <pgerhard@jpn.tuv.com> Peter Gerhard <pgerhard@jpn.tuv.com>
testings, bugreport, patches. testings, bugreport, patches.
Georg <georg@globaltrading.net>
fixed bug with print queue handling.
Sascha Herrmann <sascha@system.rhein-main.de>
docs, scripts
Victor Khimenko <khim@mccme.ru> Victor Khimenko <khim@mccme.ru>
cyrillic filename patches cyrillic filename patches
@ -61,9 +73,21 @@ James B. MacLean <macleajb@ednet.ns.ca>
Louis Zammit Mangion <lzamm@phys.um.edu.mt> Louis Zammit Mangion <lzamm@phys.um.edu.mt>
testings+bugfixes testings+bugfixes
Mendel Mobach <mendel@mobach.nl>
some doku
Norbert Nemec <nobbi@cheerful.com>
some patches
Matt Paley <mtpa@mail.nerc-bas.ac.uk> Matt Paley <mtpa@mail.nerc-bas.ac.uk>
adding QUOTA support, login time restrictions adding QUOTA support, login time restrictions
Boris Popov <bp@butya.kz>
ported mars_nwe to FreeBSD
Paolo Prandini <prandini@spe.it>
added login control routines
Jiri A. Randus <Jiri.Randus@vslib.cz> Jiri A. Randus <Jiri.Randus@vslib.cz>
testing bindery code testing bindery code
@ -76,8 +100,13 @@ Mr. Charlie Root (alexey) <root@cs.imi.udmurtia.su>
Andrew Sapozhnikov <sapa@hq.icb.chel.su> Andrew Sapozhnikov <sapa@hq.icb.chel.su>
fixed findfirst/findnext bug, fixed findfirst/findnext bug,
fixed directory access bug, fixed directory access bug,
added extend "Volume is home" feature. added extend "Volume is home" feature,
fixed "rename wildcard" bug. fixed "rename wildcard" bug,
fixed prop_find_member bug,
fixed x_str_match (DOS match) routine.
Christoph Scheeder <christoph.scheeder@scheeder.de>
added TRUSTEE_T flag
Hayo Schmidt <100305.1424@compuserve.com> Hayo Schmidt <100305.1424@compuserve.com>
added patch to let ATARI client work. added patch to let ATARI client work.
@ -85,13 +114,20 @@ Hayo Schmidt <100305.1424@compuserve.com>
Gregory Steuck <greg@nsu.ru> Gregory Steuck <greg@nsu.ru>
testings and errorreports testings and errorreports
Neal Stephenson <neal@nstephenson.gw.yorku.ca>
patch for glibc6
Morio Taneda <eb04@rz.uni-karlsruhe.de> Morio Taneda <eb04@rz.uni-karlsruhe.de>
testings, bugfixes testings, bugfixes
Erik Thiele <erik@escape.mos.unterland.de> Erik Thiele <erik@escape.mos.unterland.de>
testings and doc testings and doc
Winfried Truemper <winni@xpilot.org>: Ingmar Thiemann <ingmar@gefas.com>
added patches for better file locking/sharing
Winfried Truemper <winni@xpilot.org>
re-wrote `INSTALL' and added explanations to `nw.ini' re-wrote `INSTALL' and added explanations to `nw.ini'
Jukka Ukkonen <jau@iki.fi>
small patches

View File

@ -1,4 +1,4 @@
last updated: 14-Jul-97 last updated: 21-Feb-99
Q: Which DOS programs from the real Netware do I need? Q: Which DOS programs from the real Netware do I need?
A: For a minimal configuration you only need LOGIN.EXE. A: For a minimal configuration you only need LOGIN.EXE.
@ -10,6 +10,10 @@ A: For a minimal configuration you only need LOGIN.EXE.
There is also a DOS client program in development, which will allow There is also a DOS client program in development, which will allow
the use of mars_nwe without the original Novell DOS tools. the use of mars_nwe without the original Novell DOS tools.
Q: Do I need a device called '/dev/ipx', because I found references in mars_nwe
A: When you use Linux, no. These references are only used under OS-es with
TLI interfaces like UnixWare (tm)
Q: I don't exactly understand the meaning of some points in nw.ini: Q: I don't exactly understand the meaning of some points in nw.ini:
12,13 12,13
What will happen if I do not put PASSWORD here? Will it take it from What will happen if I do not put PASSWORD here? Will it take it from

85
doc/FILESHARING Normal file
View File

@ -0,0 +1,85 @@
Filesharing, tested with function 0x4c on a real Novell Server.
(+) = Openfile OK
(-) = Openfile fail
FILE OPEN (NCP 0x4C) with SHARE Flag set. Tested with NW312
-------------------------------------------------------------------------------------------------------------
11 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(+) |0a(+) |0b(+) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
12 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(+) |06(+) |07(+) |0d(-) |0e(-) |0f(-) |
13 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
01 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(+) |0a(+) |0b(+) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
02 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(+) |06(+) |07(+) |0d(-) |0e(-) |0f(-) |
03 |11(+) |12(+) |13(+) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
09 |11(+) |12(-) |13(-) |01(+) |02(-) |03(-) |09(+) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0a |11(+) |12(-) |13(-) |01(+) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(+) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0b |11(+) |12(-) |13(-) |01(+) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
05 |11(-) |12(+) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(+) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
06 |11(-) |12(+) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(+) |07(-) |0d(-) |0e(-) |0f(-) |
07 |11(-) |12(+) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
0d |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0e |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0f |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
=============================================================================================================
FILE OPEN (NCP 0x4C) without SHARE Flag set. Tested with NW312
-------------------------------------------------------------------------------------------------------------
11 |11(+) |12(-) |13(-) |01(+) |02(-) |03(-) |09(+) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
12 |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
13 |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
01 |11(+) |12(-) |13(-) |01(+) |02(+) |03(+) |09(+) |0a(+) |0b(+) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
02 |11(-) |12(-) |13(-) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(+) |06(+) |07(+) |0d(-) |0e(-) |0f(-) |
03 |11(-) |12(-) |13(-) |01(+) |02(+) |03(+) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
09 |11(+) |12(-) |13(-) |01(+) |02(-) |03(-) |09(+) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0a |11(-) |12(-) |13(-) |01(+) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(+) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0b |11(-) |12(-) |13(-) |01(+) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
05 |11(-) |12(-) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(+) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
06 |11(-) |12(-) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(+) |07(-) |0d(-) |0e(-) |0f(-) |
07 |11(-) |12(-) |13(-) |01(-) |02(+) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
0d |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0e |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
0f |11(-) |12(-) |13(-) |01(-) |02(-) |03(-) |09(-) |0a(-) |0b(-) |05(-) |06(-) |07(-) |0d(-) |0e(-) |0f(-) |
--
----------------
Access Modi
-----------------------------
Access | R W DR DW |
-----------------------------
0x01 | X |
0x02 | X |
0x03 | X X |
0x09 | X X |
0x0a | X X |
0x0b | X X X |
0x05 | X X |
0x06 | X X |
0x07 | X X X |
0x0d | X X X |
0x0e | X X X |
0x0f | X X X X |
-----------------------------
----------------
Handling Compatibility Access Modus.
shared | not shared
---------------------------------------------
Access | R W DR DW | R W DR DW
---------------------------------------------
0x11 | X | X X
0x12 | X | X X X
0x13 | X X | X X X X
---------------------------------------------

View File

@ -330,9 +330,7 @@ ersten Start von "nwserv" angelegt. Der Volume-Name ist ueblicherweise
"SYS". "SYS".
Beim Anlegen und Eintragen der Optionen fuer das Volume SYS unbedingt Beim Anlegen und Eintragen der Optionen fuer das Volume SYS unbedingt
auf Gross- und Kleinschreibung achten, sonst sind diese Dateien auf Gross- und Kleinschreibung achten, sonst sind diese Dateien
nachher fuer den Client nicht Sichtbar. Alle weiteren Volumes sind nachher fuer den Client nicht sichtbar. Volumes
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 koennen mit NFS gemountete Verzeichnisse, CD-Roms, Floppys und
beliebige unter Linux mountbare Filesystems sein. Die einzige beliebige unter Linux mountbare Filesystems sein. Die einzige
Einschraenkung besteht in der Beschraenkung auf entweder alles gross Einschraenkung besteht in der Beschraenkung auf entweder alles gross

View File

@ -132,5 +132,5 @@ the mars_nwe-package.
good luck :-) good luck :-)
Martin Stover <mstover@stover.f.eunet.de> Martin Stover <mstover@compu-art.de>

133
doc/INSTALL.nl Normal file
View File

@ -0,0 +1,133 @@
INSTALLATIE: ( Mendel Mobach <mendel@mobach.nl>)
Dit is het bestand "INSTALL.nl", een stap-voor-stap handboek voor het
installeren van het mars_nwe-pakket.
(1) Pak een goede ipx-kernel-versie ne compileer die met IPX Support,
Maar zonder 'Full internal network'. je kun dit doen door op de
volgende manier te antwoorden op de volgende vragen tijdens het
draaien van "make config":
The IPX protocol (CONFIG_IPX) [N/m/y/?] y
Full internal IPX network (CONFIG_IPX_INTERN) [N/y/?] n
Voor algemen vragen over het compileren van een kernel, kijk in de
Linux-Kernel-HOWTO.
De beste kernels voor Mars_nwe zijn 2.0.x.
Oudere kernels werken soms niet, omdat er bugs in de ipx-code
zitten. Kijk in de directorie 'examples' voor patches.
(2) Maak hier een keuze, of de mars_nwe je ipx-subsysteem moet initialiseren
en routing beheren, of dat je dit doet met de hand met andere producten.
Voordat je een probleem mailt naar de mailinglist over problemen met
mars_nwe, probeer dit eerst.
(2a) Configureer het IPX-subsysteem met "mars_nwe"
Je hebt geen andere ipx-tool of routers/daemons nodig
in dir geval.
Dit is gestest zodat "mars_nwe", "dosemu", "ncpfs" of
Caldera's "nwclient" hiermee goed samenwerken.
zet INTERNAL_RIP_SAP op "1" in `mars_nwe/config.h':
#define INTERNAL_RIP_SAP 1
Als je andere IPX/NCP server in je lokale netwerk hebt kun je
de "mars_nwe" automatisch de goede waarde laten invullen voor je
ipx-subsysteem.
Dit houd in dat je de volgende secties in 'nwserv.conf' zo invult:
3 0x0 # Gebruik je Ipx nummer voor het interne netwerk.
4 0x0 * AUTO # autodetect je interafces.
5 0x2 # laat de kernel automatisch interfaces voor
# creeeren.
Zorg dat er geen enkele andere server is die je interne netwerk-
nummer gebruikt als zijn netwerk nummer.
Als er geen andere IPX/NCP server is op je netwerk, dan kan het netwerk
nummer in sectie '4' elk nummer zijn.
4 0x10 eth0 ethernet_ii # eth0 device met het netwerk nummer '0x10'
# en frametype: ETHERNET_II.
4 0x20 eth0 802.3 # eth0 device met het netwerk nummer '0x20'
# en frametype: ETHERNET_802.3.
(2b) Handmatige configuratie van het IPX-subsysteem
In deze mode moet je tools zoals "ipx-configure" en
"ipxd" gebruiken voor het configureren van ipx-interfaces,
ipx-routes en om rip/sap aanvragen af te handelen.
zet INTERNAL_RIP_SAP op "0" in `mars_nwe/config.h':
#define INTERNAL_RIP_SAP 0
(3) Compileer de programma's van het Mars_nwe pakker
pak de source van "mars_nwe" uit en ga naar de directorie waarin
die is uitgepakt ('mars_nwe').
Type hget volgende comando in:
make
Dit command maakt de volgende bestanden: 'config.h' en 'mk.li'.
Edit de zoals jij ze nodig hebt. 'mk.li' moet alleen veranderdt
worden onder hele rare omstandigheden, of als je problemen hebt
met het compileren en/of het linken van dit pakket.
draai nu "make" opnieuw:
make
(4) Bewerk ("edit") het configuratie bestand 'nw.ini'.
Zorg dat je zeker weet dat alle benodigde secties in je oude configuratie
bestand staan, als je upgrade naar een nieuwere versie van de "mars_nwe".
(5) Installeer alles
Zeg alleen:
make install
en soms:
make install_ini
Deze laatste is alleen nodig als je je het _bestaande_ configuratie
bestand (nwserv.conf) wilt overschrijven met nw.ini
(6) Creer de directories die te zien moete zijn voor DOS-clients
Op z'n minst moet het volume "SYS" zijn gedefineerd in het configuratie
bestand nwserv.conf. Creer de geassocieerde directory als die al niet
bestaat en zet de programma's "login.exe" en "slist.exe" in de
"LOGIN" / "login" directorie.
Je kunt ook de vrij verkrijgbare mars_dosutils gebruiken.
NIEUW !
in nieuwere versies va de MARS_NWE worden deze directories automatisch
gecreetd bij de eerste keer dat de mars_nwe server opstart.
(7) Start de server
Start het volgende programma als root op:
nwserv
(8) Stop de programma's (server plat)
Als de mars_nwe server op de voorgrond loopt kun je de server stoppen
met een ^C (CTRL-C), anders kill de PID van nwserv,tik in 'nwserv -k'
Of gebruik het dos programma fconsole en kies "server down" als je als
supervisor (of gelijke) bent aangelogd.
Sectie 210 in het "nw.ini" / "nwserv.conf" bestand geeft de tijd in
seconden voordat de server echt stop.
Veel geluk :-)
Martin Stover <mstover@compu-art.de>

View File

@ -1,3 +1,16 @@
------23-Jul-98--- 0.99.pl12 ---------
- changed default bindery directory location:
/etc -> /var/nwserv/db ( section 45 )
------10-May-98--- 0.99.pl9 ---------
- changed default attrib directory location:
/var/lib/nwserv/attrib -> /var/nwserv/attrib. ( section 46 )
- changed default rights to 751 640. (section 9 and section 1 )
- first trustee handling added. See new volume flag 't' and 'doc/TRUSTEES'.
------03-Mar-98--- 0.99.pl7 ---------
- very important BUG fixed by Andrew Sapozhnikov. <sapa@hq.icb.chel.su>
The properties find member functions could find max. 32 entries. (1 segment)
Please enable 'ckeck/compress bindery on startup' (section 16, nwserv.conf)
to let mars_nwe do some checks/compressings on old bindery entries.
------08-Feb-98--- 0.99.pl6 --------- ------08-Feb-98--- 0.99.pl6 ---------
- archive bit handling changed. (default set if file, unset if directory) - archive bit handling changed. (default set if file, unset if directory)
- section 5: deleting of ipx devices/routes changed. - section 5: deleting of ipx devices/routes changed.

View File

@ -41,13 +41,14 @@ A simple print operation can be achieved with the following script:
This allows you to print under dos/windows without capturing. This allows you to print under dos/windows without capturing.
In the examples dir exist the two programpairs comm<->unxcomm In the examples directory there are two pairs of programs,
and sendm<->unxsendm as additional examples for using 'PIPE-filesystem'. comm<->unxcomm und sendm<->unxsendm, that provide further examples
With comm/unxcomm it is very easy to start simple Linux programs of how to use the PIPE-filesystem.
by your client. Using comm/unxcomm it is very easy to invoke simple Linux programs
for examples: ps, lpq, lprm ... from the client, e.g. ps, lpq, lprm ..
I would appreciate hearing about further documented applications of If anyone has other documented applications of the PIPE-filesystem,
the PIPE filesystem or suggestions for other ways of using it. or any suggestions about other ways it might be used, I'd be very glad
to hear from them.
Martin Martin

View File

@ -1,4 +1,7 @@
/* PIPE- Filesystem */ /* PIPE- Filesystem */
1. Was sind PIPEs?
das 'PIPE Filesystem' entstand urspruenglich aus der Frage heraus: das 'PIPE Filesystem' entstand urspruenglich aus der Frage heraus:
Wie kann ich ein Linux System oder Teile davon ueber/auf einen Wie kann ich ein Linux System oder Teile davon ueber/auf einen
DOS-Rechner oder Novell Fileserver sichern. DOS-Rechner oder Novell Fileserver sichern.
@ -15,6 +18,10 @@ je nach Modus des ersten Zugriffes (Read oder Write).
Das 'PIPE-Filesystem' bietet damit eine direkte Schnittstelle Das 'PIPE-Filesystem' bietet damit eine direkte Schnittstelle
zwischen Client Anwendungen und Linux Programmen. zwischen Client Anwendungen und Linux Programmen.
2. Beispiele
2.1 Dos->Linux, Linux->Dos Backup
Die Loesung des obigen Problems ergab sich dann mit folgendem einfachen Die Loesung des obigen Problems ergab sich dann mit folgendem einfachen
Shell Script, welches im PIPE-Filesystem hinterlegt wurde. Shell Script, welches im PIPE-Filesystem hinterlegt wurde.
@ -37,6 +44,8 @@ lokale Datei 'kopiert' werden ( -> Sichern ) bzw. es
kann die lokale Datei auf diese 'Pipe Datei' kopiert werden. kann die lokale Datei auf diese 'Pipe Datei' kopiert werden.
( -> Ruecksichern ) ( -> Ruecksichern )
2.2 Drucken ueber Pipes
Ein einfaches Drucken kann z.B. mit folgendem Mini Script realisiert werden. Ein einfaches Drucken kann z.B. mit folgendem Mini Script realisiert werden.
Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf
/usr/bin/lpr. /usr/bin/lpr.
@ -46,6 +55,93 @@ Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf
Dadurch kann ein capture unter DOS/Windows entfallen. Dadurch kann ein capture unter DOS/Windows entfallen.
2.3 Private Windowsinstallation fuer jeden Netzbenutzer
(Beispiel von Sascha Herrmann <sascha@system.rhein-main.de>)
Die Idee fuer diesen Script, war auf einem Netz mit Diskless PCs, die ueber
mars-nwe ihr Dos/Windows System bekommen, fuer jeden einzelnen Benutzer eine
eigene Windowsconfiguration zu bekommen.
Hierfuer habe ich einen kleinen Shellscript geschrieben, der diese Aufgabe
bisher recht gut erledigt, ohne viel Speicherplatz zu verschwenden.
Fuer den Skript muss zunaechst einmal Windows in mehrere Teile aufgesplittet
werden, einen gemeinsamen Teil, auf den kein Schreibzugriff noetig ist
(*.exe, *.dll etc.) und einen Teil auf den Schreibzugriff noetig ist (*.ini
etc.). Windows bringt mit der Serverinstallation schon eine moeglichkeit die
Installation in zwei Teile aufzuspalten. setup /a erzeugt ein Verzeichnis,
das von allen Benutzern gemeinsam benutzt werden kann und setup /n erzeugt
dann eine Benutzerinstallation, die nur noch ca. 500kb gross ist. Das so
erzeugte Verzeichnis wird nun auf den Server kopiert und dort nochmal in
zwei Teile aufgeteilt (nach dem oben beschriebenen Schema).
Der Skript kopiert und linkt nun einfach die Dateien aus dem mit setup /n
installierten Dateien in ~/windows/windows. Wenn man nun auf den Dosclient
das Volume \\SERVER\HOMEDIR\WINDOWS auf Laufwerk d: und das mit setup /a
erzeugte Verzeichnis auf ein anderes Laufwerk einbindet hat man eine
funktionierende Windowsinstallation, die pro Benutzer grade einmal 80kb
Plattenplatz wegnimmt.
Der Skript wird nach jedem login von dem Dosclient durch einen type auf die
Datei ausgefuehrt und kopiert alle Dateien mit cp -au (u steht fuer Update,
daher nur neuere Dateien werden kopiert) aus $TEMPLATE/dynamic nach
~/windows/windows und legt fuer jede Datei aus $TEMPLATE/static einen
symbolischen link in ~/windows/windows an. Damit kann man die mit setup -n
erstellten Dateien noch einmal in einen Teil mit und einem ohne
Schreibzugriff unterteilen.
Leider setzt mars-nwe (zumindest in 0.99.pl4) in Pipescripts die
umgebungsvariable $HOME immer auf /root, daher lese ich das Heimatverzeichnis
mit dem gethomedir.pl script aus /etc/passwd aus.
--------------------------------------------------------------------
#!/bin/sh
# mkwin Pipeskript
#
# !!!!ACHTUNG!!!!
# Wenn in $home/ eine Datei windows oder windows/windows exestiert,
# wird diese ohne nachfrage geloescht
PATH="/bin:/usr/bin"
TEMPLATE="/var/spool/nwserv/windows/template"
home=`/var/spool/nwserv/pipe/gethomedir.pl $UID`
case "$1" in
'READ')
if ! test -d $home/windows ; then
rm -rf $home/windows
fi
if ! test -d $home/windows/windows ; then
rm -rf $home/windows/windows > /dev/null
mkdir -pm 0700 $home/windows/windows
fi
for i in $TEMPLATE/static/* ; do
ln -s $i $home/windows/windows
done
cp -au $TEMPLATE/dynamic/* $home/windows/windows
;;
esac
-----------------------------------------------------------------
#!/usr/bin/perl
#
# File: gethomedir.pl
#
print "$1\n";
open(PW, "/etc/passwd");
while ($line=<PW>) {
chop($line);
($uid, $home) = ($line=~
/[^\:]*\:[^\:]*\:([\d]*)\:[^\:]*\:[^\:]*\:([^\:]*)\:/
);
if ($uid == $ARGV[0]) {
print "$home";
}
}
close(PW);
------------------------------------------------------------------
2.4 andere Beispiele
In dem Verzeichnis examples gibt es als zusaetzliches Beispiel In dem Verzeichnis examples gibt es als zusaetzliches Beispiel
die Programmpaare unxcomm<->comm und sendm<->unxsendm. die Programmpaare unxcomm<->comm und sendm<->unxsendm.
Mittels unxcomm/comm ist es sehr einfach moeglich einige Mittels unxcomm/comm ist es sehr einfach moeglich einige
@ -56,3 +152,4 @@ Ueber weitere dokumentierte Anwendungen bzw. Anregungen zu dem
PIPE-Filesystem wuerde ich mich freuen. PIPE-Filesystem wuerde ich mich freuen.
Martin Martin

View File

@ -68,7 +68,7 @@ nwbind:
Have luck with trying. :) Have luck with trying. :)
Martin Stover <mstover@stover.f.eunet.de> Martin Stover <mstover@compu-art.de>
BTW: The kick to make mars_nwe public was the publication of BTW: The kick to make mars_nwe public was the publication of
linware ( lwared ), the NetWare-Emulator from linware ( lwared ), the NetWare-Emulator from

74
doc/README.FREEBSD Normal file
View File

@ -0,0 +1,74 @@
This is a port of Mars_nwe, a free NetWare(tm) emulator for Linux and
UnixWare to FreeBSD. An original program was written by Martin Stover,
Marburg, Germany. Port to FreeBSD was made by Boris Popov (bp@butya.kz).
Notes given below related only to FreeBSD. For full description
of Mars_nwe, please read README file.
Additional info about IPX on FreeBSD available at
http://www.butya.kz/~bp/
1. Kernel configuration
To enable kernel support for IPX protocol you must include
"options IPX" keyword and rebuild kernel. If you are running FreeBSD
3.x or 2.2.8, please download patched versions for IPX stack and
IPXrouted frow above URL. These changes already commited in to -current
branch.
2. Interface configuration
If it's first NCP server in your network you can select any network
number for ethernet interface. If not, take it from Netware server
configuration. Network number must be the same as assigned to Ethernet_II
frame.
After net number is selected you can configure interface:
ifconfig ed0 ipx 0x101
If FreeBSD machine have a two network cards you must choose
different network numbers for each card.
Also select an unqiue number for internal net and configure it
as follows:
ifconfig lo0 ipx 0xbebe.1
Note, that you should set host number to 1.
3. Running IPXrouted
FreeBSD have its own SAP/RIP daemon which must be run before
Mars_nwe and after interface configuration. IPXrouted must be running
with switch '-s'. Please use only patched version of IPXrouted if you
are run 2.2.8 or 3.x of FreeBSD.
4. Client configuration
This port of Mars_nwe was tested with VLM, Client32 and
native FreeBSD clients. Since FreeBSD support only Ethernet_II frame
it is necessary to create net.cfg file (for VLM) to enable this
frame:
LINK DRIVER NE2000
Frame Ethernet_802.3
Frame Ethernet_II
5. Configuring Mars_nwe
Section 3 of nwserv.conf file specified network number in hexadecimal
format. This should be an internal network number configured on interface lo0.
For above example set following:
3 0xbebe
Section 4 are completly ignored.
6. Problems
If you have any questions do not hesitate to contact me, Boris Popov at
bp@butya.kz.

View File

@ -68,7 +68,7 @@ der fehlenden bzw. fehlerhaften NCP-Calls wuerde ich mich freuen.
Martin Martin
<mstover@stover.f.eunet.de> <mstover@compu-art.de>
PS: Den Anstoss, mars_nwe zu veroeffentlichen, gab die PS: Den Anstoss, mars_nwe zu veroeffentlichen, gab die
Veroeffentlichung von linware ( lwared ), dem Novell-Server-Emulator Veroeffentlichung von linware ( lwared ), dem Novell-Server-Emulator

72
doc/TRUSTEES Normal file
View File

@ -0,0 +1,72 @@
last changed: 12-May-98
First simple trustee handling is added in 0.99.pl9.
some notes/restrictions:
NOT ALL functions will work correct with trustees rights.
Trustee handling still needs to be hard tested to avoid
SECURITY holes.
- trustee handling must be activated by setting the volumes 't' flag.
- if activated for the SYS directory then the following default
trustees should be set.
GROUP EVERYBODY: C in SYS:MAIL
FR in SYS:PUBLIC
SUPERVISOR: SRWCEMFA in SYS:
the standard user rights in mail diretories are not so important,
because user has unix rights in this diretory.
every USER: RWCEMF in SYS:MAIL/userid
A non root supervisor and user with supervisor equivalences
get default full trustee rights in root directory. These rights
could be altered in subdirectories to less rights.
A root supervisor always has full rights.
- if SYS volume is marked as trusttee volume then some
checking routines will reduce g+o unix accesses in
SYS:MAIL subdirectories.
- symlink directories must get direct trustees, inheritated_mask
is set to 0 to prevent user making symlinks to directories
they do not have real access.
- when stepping through directories,
inheritated_mask will be set to 0 if st_dev changes.
- only root assigned user may give trustee rights to
file/dir which st_dev differs from VOLUMES st_dev.
- only additional rights are given by trustees, existing
unix user rights are not reduced.
therefore trustee volumes should get low unix rights.
for example: 0711 for directories and 0600 for files.
- for many routines the user still needs the 'x' directory right.
- the trusttee search is limitated to user and first level groups.
'group in group' and 'normal' security equivalences are not supported.
Supervisor equivalences are supported.
- an user can only be member of 32 groups.
- some changes of trustees only have effect after new login.
- must never be switched on volumes which do not have fix inodes,
because trustees are represented by device and inode number of the
file or directory.
- standard trustee directory is /var/nwserv/trustees
( see nwserv.conf section 47 )
- representation under this directory is:
- for user trustees:
volumename/device/ino0/ino1/ino2/t.ino3/id -> trustee
ino0 .. ino3 = byte 0 .. 3 of inode
id = user id as hex number.
- for inherit right masks ( we use 'userid' 0 )
volumename/device/ino0/ino1/ino2/t.ino3/0 -> inherit_right_mask
- and for scanning trustees:
volumename/device/ino0/ino1/ino2/n.ino3 -> path
path is relativ to volumes root path.
- and for 'trustees are changed' notifications:
volumename/ts -> sernum (hex value)
all values are represented by symbolic links, not files similar
to the attribute handling.

30
doc/VRAGEN.NL Normal file
View File

@ -0,0 +1,30 @@
Een aantal vragen en antwoorden. ( Mendel Mobach <mendel@mobach.nl> )
V: Welke Novell DOS programma's moet ik minimaal hebben?
A: Het minimun vereiste is LOGIN.EXE
Andere handige programma's zijn:
MAP.EXE wordt gebruikt om server volume's te verbinden met een
schijfletter.
CAPTURE.EXE wordt gebruikt om een printer-poort te verbinden met
een printer op de mars/novell server.
SYSCON.EXE wordt gebruikt voor het beheren van de server.
V: Heb ik het device '/dev/ipx' nodig? Ik zie verwijzingen vanuit de mars_nwe.
A: Als je Linux gebruikt, NEE. Dit device is alleen nodig indien men een OS
gebruikt met TLI-interfaces, b.v. Unixware (tm).
V: Ik begrijp entry 12/13 in de configuratie niet.
Wat gebeurt er als ik hier niks opgeef?
Wordt de '/etc/passwd' of '/etc/shadow' gebruikt?
A: Het wachtwoord in 12/13 wordt versleuteld opgeslagen in de bindery,
De wachtwoorden uit de '/etc/passwd' of '/etc/shadow' worden alleen gebruikt
als men werkt met 'unencryted login calls', oftewel ongecodeerde wachtwoorden
vanaf de client.
V: Welke rol speelt entry '15' in de configuratie?
A: In deze entry staat een wachtwoord, wat alleen wordt gebruikt als men
automatische UNIX naar mars_nwe usermapping heeft aanstaan, oftewel als
men in unix een gebruiker toevoegt, en daarna de mars_nwe herstart wordt
die gebruiker ook in de bindery opgenomen en krijgt hij het standaard
wachtwoord.

View File

@ -1,16 +1,16 @@
Begin3 Begin3
Title: mars_nwe Title: mars_nwe
Version: 0.99.pl6 Version: 0.99.pl19
Entered-date: 09-Feb-98 Entered-date: 25-Apr-00
Description: Full netware-emulator (src), beta. Description: Full netware 3.xx emulator (src), beta.
Supports file-services, bindery-services, Supports file-services, bindery-services,
printing-services, routing-services. printing-services, routing-services.
Keywords: novell, netware, server, ipx, ncp, tli Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@compu-art.de (Martin Stover) Author: mstover@compu-art.de (Martin Stover)
Maintained-by: mstover@compu-art.de (Martin Stover) Maintained-by: mstover@compu-art.de (Martin Stover)
Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl6.tgz Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl19.tgz
250 kB 320 kB
Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl6.tgz Alternate-site: ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/mars_nwe/mars_nwe-0.99.pl19.tgz
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), FreeBSD, UnixWare (2.xx)
Copying-policy: GNU Copying-policy: GPL
End End

108
emutli.c
View File

@ -1,4 +1,4 @@
/* emutli.c 07-Jul-97 */ /* emutli.c 04-Apr-00 */
/* /*
* One short try to emulate TLI with SOCKETS. * One short try to emulate TLI with SOCKETS.
*/ */
@ -20,24 +20,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <stdio.h> #include "net.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/config.h> #include <net/if.h>
#include <linux/sockios.h> #include <net/route.h>
#include "net.h" #include <netinet/in.h>
#include <linux/if.h>
#include <linux/route.h>
#include <linux/in.h>
#include <signal.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#ifndef DO_IPX_SEND_TEST #ifndef DO_IPX_SEND_TEST
# define DO_IPX_SEND_TEST 2 # define DO_IPX_SEND_TEST 0
#endif #endif
/* DO_IPX_SEND_TEST is only needed if the ipx sendmsg() bug is not patched /* DO_IPX_SEND_TEST is only needed if the ipx sendmsg() bug is not patched
@ -55,6 +49,9 @@
*/ */
static int locipxdebug=0; static int locipxdebug=0;
#ifdef FREEBSD
static struct ipx_addr fbsd_ipx;
#endif
void set_locipxdebug(int debug) void set_locipxdebug(int debug)
{ {
@ -86,12 +83,31 @@ void set_emu_tli(void)
{ {
int i = get_ini_int(100); int i = get_ini_int(100);
if (i > -1) locipxdebug = i; if (i > -1) locipxdebug = i;
#ifdef FREEBSD
{
uint32 net = 0;
uint8 buff[500];
if( (get_ini_entry(NULL, 3, buff, sizeof(buff)))!=3 ){
errorp(10, "set_emu_tli", "Missing ini entry 3");
return;
}
sscanf((char*)buff, "%lx", &net);
ipx_netlong(fbsd_ipx)=htonl(net);
if( ipx_iffind(NULL,&fbsd_ipx) )
errorp(10, "set_emu_tli", "Can't find ipx interface for net=%lx",net);
}
#endif
} }
int t_open(char *name, int open_mode, char * p) int t_open(char *name, int open_mode, char * p)
{ {
int opt=1; int opt=1;
#ifdef FREEBSD
int sock = socket(AF_IPX, SOCK_DGRAM, 0);
#else
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
#endif
if (sock < 0) return(sock); if (sock < 0) return(sock);
set_sock_debug(sock); /* debug switch */ set_sock_debug(sock); /* debug switch */
@ -115,15 +131,34 @@ int t_bind(int sock, struct t_bind *a_in, struct t_bind *a_out)
&& a_in->addr.len == sizeof(ipxAddr_t)) && a_in->addr.len == sizeof(ipxAddr_t))
ipx2sockadr(&ipxs, (ipxAddr_t*) (a_in->addr.buf)); ipx2sockadr(&ipxs, (ipxAddr_t*) (a_in->addr.buf));
#ifndef FREEBSD
ipxs.sipx_network = 0L; /* allways default net */ ipxs.sipx_network = 0L; /* allways default net */
memset(ipxs.sipx_node, 0, IPX_NODE_SIZE); /* allways default node */ memset(ipxs.sipx_node, 0, IPX_NODE_SIZE); /* allways default node */
/* Hi Volker :) */ /* Hi Volker :) */
#else
ipx_netlong(ipxs.sipx_addr)=ipx_netlong(fbsd_ipx);
memcpy(ipxs.sipx_node, &fbsd_ipx.x_host, IPX_NODE_SIZE);
#endif
if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1) { if (bind(sock, (struct sockaddr*)&ipxs, sizeof(struct sockaddr_ipx))==-1) {
errorp(0, "TLI-BIND", "socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port))); errorp(0, "TLI-BIND", "socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port)));
return(-1); return(-1);
} }
#ifdef FREEBSD
{
int on=1;
if (setsockopt(sock, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
errorp(0, "setsockopt SO_HEADERS_ON_INPUT", NULL);
return (-1);
}
if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on,sizeof(on))==-1){
errorp(0, "setsockopt SO_BROADCAST", NULL);
return(-1);
}
}
#endif
if (a_out != (struct t_bind*) NULL) { if (a_out != (struct t_bind*) NULL) {
if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){ if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){
errorp(0, "TLI-GETSOCKNAME", NULL); errorp(0, "TLI-GETSOCKNAME", NULL);
@ -180,15 +215,14 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
p->revents=0; p->revents=0;
p++; p++;
} }
if (timeout > 1000) {
/* mst:04-Apr-00, patch from (Jukka Ukkonen) */
time_out.tv_sec = timeout / 1000; time_out.tv_sec = timeout / 1000;
time_out.tv_usec = 0; time_out.tv_usec = (timeout % 1000) * 1000;
} else { if (0 > (result = select(high_f+1, &readfs, NULL, NULL,
time_out.tv_sec = 0; (timeout == -1) ? NULL : &time_out)))
time_out.tv_usec = timeout*1000;
}
if (0 > (result = select(high_f+1, &readfs, NULL, NULL, &time_out)))
return(-1); return(-1);
if (result) { if (result) {
int rest=result; int rest=result;
k = (int)nfds; k = (int)nfds;
@ -204,6 +238,7 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
return(result); return(result);
} }
inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags) inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
{ {
struct sockaddr_ipx ipxs; struct sockaddr_ipx ipxs;
@ -211,6 +246,29 @@ inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
int result; int result;
ipxs.sipx_family=AF_IPX; ipxs.sipx_family=AF_IPX;
if (ud->addr.maxlen < sizeof(ipxAddr_t)) return(-1); if (ud->addr.maxlen < sizeof(ipxAddr_t)) return(-1);
#ifdef FREEBSD
{
unsigned char tmpbuf[IPX_MAX_DATA+sizeof(struct ipx)];
struct ipx *ipxhdr=(struct ipx*)tmpbuf;
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(fd,&rfd);
result=select(fd+1, &rfd, NULL, NULL, NULL);
if(result<0) return(-1);
result = recvfrom(fd, tmpbuf,
min(sizeof(tmpbuf), ud->udata.maxlen+sizeof(struct ipx)), 0,
(struct sockaddr *) &ipxs, &sz);
result-=sizeof(struct ipx);
if( result<0 ) return(-1);
memcpy(ud->udata.buf,tmpbuf+sizeof(struct ipx),result);
if (ud->opt.maxlen) {
*((uint8*)ud->opt.buf) = ipxhdr->ipx_pt;
ud->opt.len = 1;
}
}
#else
result = recvfrom(fd, ud->udata.buf, ud->udata.maxlen, 0, result = recvfrom(fd, ud->udata.buf, ud->udata.maxlen, 0,
(struct sockaddr *) &ipxs, &sz); (struct sockaddr *) &ipxs, &sz);
@ -219,6 +277,8 @@ inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
*((uint8*)ud->opt.buf) = ipxs.sipx_type; *((uint8*)ud->opt.buf) = ipxs.sipx_type;
ud->opt.len = 1; ud->opt.len = 1;
} }
#endif
ud->udata.len=result; ud->udata.len=result;
sock2ipxadr((ipxAddr_t*) (ud->addr.buf), &ipxs); sock2ipxadr((ipxAddr_t*) (ud->addr.buf), &ipxs);
ud->addr.len = sizeof(ipxAddr_t); ud->addr.len = sizeof(ipxAddr_t);
@ -260,7 +320,15 @@ inline int t_sndudata(int fd, struct t_unitdata *ud)
memset(&ipxs, 0, sizeof(struct sockaddr_ipx)); memset(&ipxs, 0, sizeof(struct sockaddr_ipx));
ipxs.sipx_family=AF_IPX; ipxs.sipx_family=AF_IPX;
ipx2sockadr(&ipxs, (ipxAddr_t*) (ud->addr.buf)); ipx2sockadr(&ipxs, (ipxAddr_t*) (ud->addr.buf));
#ifdef FREEBSD
{
struct ipx ipxdp;
ipxdp.ipx_pt = (ud->opt.len) ? (uint8) *((uint8*)(ud->opt.buf)) : 0;
setsockopt(fd, 0, SO_DEFAULT_HEADERS, &ipxdp, sizeof(ipxdp));
}
#else
ipxs.sipx_type = (ud->opt.len) ? (uint8) *((uint8*)(ud->opt.buf)) : 0; ipxs.sipx_type = (ud->opt.len) ? (uint8) *((uint8*)(ud->opt.buf)) : 0;
#endif
result = sendto(fd,(void *)ud->udata.buf, result = sendto(fd,(void *)ud->udata.buf,
ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs)); ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs));

View File

@ -1,4 +1,4 @@
/* emutli.h 28-Apr-96 */ /* emutli.h 18-Nov-99 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
@ -20,7 +20,27 @@
#ifndef _EMUTLI_H_ #ifndef _EMUTLI_H_
#define _EMUTLI_H_ #define _EMUTLI_H_
#include <linux/ipx.h> #ifdef FREEBSD
# include <netipx/ipx.h>
# define sipx_node sipx_addr.x_host.c_host
# define sipx_network sipx_addr.x_net.c_net
# define ipx_netlong(iaddr) (((union ipx_net_u *)(&((iaddr).x_net)))->long_e)
# define ETHERTYPE_IPX 0x8137
# define IPX_RT_8022 ETHERTYPE_IPX
# define IPX_RT_8023 ETHERTYPE_IPX
# define IPX_RT_SNAP ETHERTYPE_IPX
# define IPX_RT_BLUEBOOK ETHERTYPE_IPX
int ipx_iffind(char *ifname,struct ipx_addr *addr);
#else
# include <linux/types.h>
# include <netinet/in.h>
# ifdef _GNU_SOURCE_
# include <netipx/ipx.h>
# else
# include <linux/ipx.h>
# endif
#endif
typedef unsigned char uint8; typedef unsigned char uint8;
typedef unsigned short int uint16; typedef unsigned short int uint16;

101
emutli1.c
View File

@ -1,4 +1,4 @@
/* emutli1.c 10-Apr-97 */ /* emutli1.c 05-May-98 */
/* /*
* One short try to emulate TLI with SOCKETS. * One short try to emulate TLI with SOCKETS.
*/ */
@ -34,13 +34,19 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/config.h> #include <linux/config.h>
#include <linux/sockios.h> #if 0
# include <linux/sockios.h>
#endif
#include "net.h" #include "net.h"
#include <linux/if.h> #if 0
#include <linux/route.h> # include <linux/if.h>
#include <linux/in.h> # include <linux/route.h>
#include <signal.h> # include <linux/in.h>
#include <string.h> #else
# include <net/if.h>
# include <net/route.h>
# include <netinet/in.h>
#endif
#include <errno.h> #include <errno.h>
static int have_ipx_started=0; static int have_ipx_started=0;
@ -154,6 +160,9 @@ static void del_special_net(int special, char *devname, int frame)
if (frame < 0) continue; if (frame < 0) continue;
sipx->sipx_type = frame; sipx->sipx_type = frame;
if (flags & 1) { /* primary */ if (flags & 1) { /* primary */
if (flags & 2){ /* primary == internal net */
sipx->sipx_special = IPX_INTERNAL;
} else
strcpy(id.ifr_name, name); strcpy(id.ifr_name, name);
break; break;
} }
@ -273,10 +282,49 @@ int get_frame_name(uint8 *framename, int frame)
return(0); return(0);
} }
int ipx_inuse(int mode)
/* returns 0 if ipx is idle */
{
FILE *f=fopen("/proc/net/ipx", "r");
int idle=0;
if (f) {
char buff[200];
while (fgets((char*)buff, sizeof(buff), f) != NULL){
uint32 network;
int sock;
if (2==sscanf(buff, "%lx:%x", &network, &sock)) {
if (mode == 0) {
if (sock >= 0x4000) { /* user socket */
idle=sock;
break;
}
} else if (sock==mode) {
idle=sock;
break;
}
}
}
fclose(f);
}
return(idle);
}
static void ipx_in_use_abort()
{
errorp(11, "!! IPX IN USE ERROR !!",
"mars_nwe would kill existing IPX programs if starting\n"
"because it must reinit ipx devices.\n"
"Please stop other IPX programs e.g. ncpmount,\n"
"or change mars_nwe's configuration.\n"
);
exit(1);
}
int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags) int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags)
{ {
int result=-1; int result=-1;
int sock; int sock;
uint32 primary_net=0L;
#if INTERNAL_RIP_SAP #if INTERNAL_RIP_SAP
# ifdef CONFIG_IPX_INTERN # ifdef CONFIG_IPX_INTERN
errorp(11, "!! configuration error !!", errorp(11, "!! configuration error !!",
@ -293,36 +341,49 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags)
exit(1); exit(1);
} else { } else {
ipx_config_data cfgdata; ipx_config_data cfgdata;
struct sockaddr_ipx ipxs;
ioctl(sock, SIOCIPXCFGDATA, &cfgdata); ioctl(sock, SIOCIPXCFGDATA, &cfgdata);
org_auto_interfaces = org_auto_interfaces =
auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces; auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces;
set_sock_debug(sock); set_sock_debug(sock);
result=0; result=0;
/* build new internal net */
if (network) {
struct sockaddr_ipx ipxs;
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));
ipxs.sipx_port = htons(SOCK_NCP); ipxs.sipx_port = htons(SOCK_NCP);
ipxs.sipx_family = AF_IPX; ipxs.sipx_family = AF_IPX;
if (bind(sock, (struct sockaddr*)&ipxs, if (bind(sock, (struct sockaddr*)&ipxs,
sizeof(struct sockaddr_ipx))==-1) { sizeof(struct sockaddr_ipx))==-1) {
if (errno == EEXIST || errno == EADDRINUSE) result = -1; if (errno == EEXIST || errno == EADDRINUSE) {
} result = -1;
if (result) {
errorp(1, "EMUTLI:init_ipx socket 0x451", NULL); errorp(1, "EMUTLI:init_ipx socket 0x451", NULL);
exit(1); exit(1);
} }
del_internal_net(); } else {
add_internal_net(network, node); int maxplen=sizeof(struct sockaddr_ipx);
if (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) != -1)
primary_net= ntohl(ipxs.sipx_network);
if (primary_net)
have_ipx_started++;
}
/* build new internal net */
if (network) {
int diffs = (primary_net && (network != primary_net));
if (diffs) {
XDPRINTF((1,0,"Existing primary network will be reinit from %x to %x",
primary_net, network));
if (ipx_inuse(0) && !(flags&4))
ipx_in_use_abort();
}
if ((flags&4) || diffs || !primary_net) { /* if complete reinit or diffs */
del_internal_net();
add_internal_net(network, node);
}
have_ipx_started++; have_ipx_started++;
} }
if ((flags & 2) && !auto_interfaces) { /* set auto interfaces */ if ((flags & 2) && !auto_interfaces) { /* set auto interfaces */
auto_interfaces = 1; auto_interfaces = 1;
ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces); ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces);
} }
close(sock); close(sock);
} }
return(result); return(result);
@ -341,8 +402,10 @@ void exit_ipx(int flags)
ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces); ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces);
close(sock); close(sock);
} }
if (have_ipx_started && flags&4) { if (flags&4) {
del_all_interfaces_nets(); del_all_interfaces_nets();
} else if (!ipx_inuse(0)) {
del_internal_net();
} }
} }
@ -353,8 +416,10 @@ int init_dev(char *devname, int frame, uint32 network, int wildmask)
if (!have_ipx_started) { if (!have_ipx_started) {
if (wildmask) return(-99); if (wildmask) return(-99);
have_ipx_started++; have_ipx_started++;
if (!ipx_inuse(0)) {
del_primary_net(); del_primary_net();
add_primary_net(devname, frame, network); add_primary_net(devname, frame, network);
}
} else { } else {
if (!wildmask) if (!wildmask)
return(add_device_net(devname, frame, network)); return(add_device_net(devname, frame, network));

View File

@ -1,4 +1,4 @@
/* emutli1.h 10-Apr-97 */ /* emutli1.h 05-May-98 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
@ -29,15 +29,12 @@ extern int get_interface_frame_name(char *name, uint32 net);
extern int add_device_net(char *devname, int frame, uint32 netnum); extern int add_device_net(char *devname, int frame, uint32 netnum);
extern int get_frame_name(uint8 *framename, int frame); extern int get_frame_name(uint8 *framename, int frame);
extern int ipx_inuse(int mode);
extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags); extern int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags);
extern void exit_ipx(int full); extern void exit_ipx(int full);
extern int init_dev(char *devname, int frame, uint32 network, int wildmask); extern int init_dev(char *devname, int frame, uint32 network, int wildmask);
extern void exit_dev(char *devname, int frame); extern void exit_dev(char *devname, int frame);
#if 0
extern int get_ipx_addr(ipxAddr_t *addr);
#endif
extern void ipx_route_add(uint32 dest_net, extern void ipx_route_add(uint32 dest_net,
uint32 route_net, uint32 route_net,
uint8 *route_node); uint8 *route_node);

View File

@ -1,17 +1,33 @@
/* /* comm.c 22-Oct-98
* simple demo for a command programm which do a * simple demo for a command programm which do a
* DOS <-> UNX command handling using PIPE filesystem. * DOS/WIN <-> UNX command handling using PIPE filesystem.
* Most problem under W95 is the file caching.
* Only the 32-bit version (comm32) works correct under W95.
* NT do not have this problems.
*
* can be used with unxcomm for UNX. * can be used with unxcomm for UNX.
* *
* Can also be used under Linux for ncpfs <-> mars_nwe. * Can also be used under Linux for ncpfs <-> mars_nwe.
* * comm and unxcomm must be same version !
*/ */
#define MAXARGLEN 1024
/* Environment string could be in the form: UNXCOMM=p:/unxcomm
* or under 32bit: UNXCOMM=\\lx1\pipes\unxcomm
* or under linux: UNXCOMM=/pipes/unxcomm
*
*/
#define ENV_UNXCOMM "UNXCOMM" #define ENV_UNXCOMM "UNXCOMM"
#ifdef LINUX #ifdef LINUX
# define DEFAULT_COMM "/pipes/unxcomm" # define DEFAULT_COMM "/pipes/unxcomm"
#else
# ifdef DEFAULT_UNC
# define DEFAULT_COMM DEFAULT_UNC
# else # else
# define DEFAULT_COMM "p:/unxcomm" # define DEFAULT_COMM "p:/unxcomm"
# endif
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -19,6 +35,8 @@
#include <stddef.h> #include <stddef.h>
#ifndef LINUX #ifndef LINUX
# include <io.h> # include <io.h>
#else
# define O_BINARY 0
#endif #endif
#include <fcntl.h> #include <fcntl.h>
@ -28,32 +46,172 @@ static int usage(char *progname)
return(1); return(1);
} }
#ifdef WIN32
#include <windows.h>
#include <direct.h>
int get_server_name(char *servername, char *path)
/* returns len of servername if exist or 0 */
{
int result=0;
char remotepath[300];
if (path && *path != '\\' && *path != '/' && *(path+1) != ':'){
getcwd(remotepath, sizeof(remotepath)-1);
path=remotepath;
}
if (path && path[1] == ':') {
char localpath[10];
DWORD size=sizeof(remotepath);
memcpy(localpath, path, 2);
*(localpath+2)='\0';
if (WNetGetConnection(localpath, remotepath,
&size)==NO_ERROR) {
path=remotepath;
}
}
if (path && (*path == '\\' || *path == '/')
&& (*(++path) == '\\' || *path == '/') ) {
char *p=++path;
while (*p && *p!='/' && *p!='\\') ++p;
result= (int)(p-path);
if (result&&servername) {
memcpy(servername, path, result );
servername[result] = '\0';
}
}
return(result);
}
HANDLE loc_open(char *fn, int mode)
{
HANDLE fd=CreateFile(fn, GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_SEQUENTIAL_SCAN|
FILE_FLAG_NO_BUFFERING, /* IMPORTANT !!! */
NULL);
return(fd);
}
int loc_read(HANDLE fd, char *buf, int size)
{
if (ReadFile(fd, buf, size, &size, NULL))
return(size);
return(-1);
}
#define loc_close(fd) CloseHandle(fd)
#define loc_lseek(fd, offs, what) /* not yet used */
#else
#define loc_lseek lseek
#define loc_read read
#define loc_open open
#define loc_close close
typedef int HANDLE;
#define INVALID_HANDLE_VALUE -1
#endif
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *unxcomm=getenv(ENV_UNXCOMM); char *unxcomm=getenv(ENV_UNXCOMM);
if (NULL == unxcomm) unxcomm=DEFAULT_COMM; if (NULL == unxcomm) unxcomm=DEFAULT_COMM;
if (argc > 1) { if (argc > 1) {
int fdout = open(unxcomm, O_RDWR);
int fdin = dup(fdout);
if (fdout > -1 && fdin > -1) {
char **pp=argv+1; char **pp=argv+1;
unsigned char b=32;
int size; int size;
int buf[512]; char buf[MAXARGLEN+1024];
while(--argc) { HANDLE fdin = loc_open(unxcomm, O_RDONLY|O_BINARY);
write(fdout, *pp, strlen(*pp)); int fdout = -1;
++pp; #ifdef WIN32
write(fdout, &b, 1); char buf_unxcomm[200];
if (fdin == INVALID_HANDLE_VALUE) {
char servername[100];
if (get_server_name(servername, argv[0])>0){
sprintf(buf_unxcomm, "\\\\%s\\pipes\\unxcomm", servername);
unxcomm=buf_unxcomm;
fdin = loc_open(unxcomm, O_RDONLY|O_BINARY);
} }
b=0; }
write(fdout, &b, 1); #endif
if (fdin != INVALID_HANDLE_VALUE) {
int count=loc_read(fdin, buf, 10);
char pipepath[200];
char *pipeext=pipepath;
int tries=0;
while (count < 10 && tries < 20) {
int nc;
if (count < 0) count =0;
nc=loc_read(fdin, buf+count, 1);
if (nc > 0) count+=nc;
tries++;
}
if (count == 10 && buf[0]=='#' && buf[9] == '\n') {
char *p;
strcpy(pipepath, unxcomm);
p=pipepath+strlen(unxcomm);
while (p>pipepath) {
if (*p=='\\' || *p=='/')
break;
--p;
}
if (p > pipepath) {
++p;
*p++='r';
*p++='u';
*p++='n';
*p++='/';
memcpy(p, buf+1, 8);
p += 8;
*p++='.';
pipeext = p;
strcpy(pipeext, "in");
} else pipepath[0] = '\0';
tries=0;
do {
fdout = open(pipepath, O_WRONLY|O_BINARY);
} while (fdout < 0 && tries++ < 5);
if (fdout <0) {
fprintf(stderr, "Cannot open pipe '%s'\n", pipepath);
}
} else {
buf[count>0 ? count : 0]='\0';
fprintf(stderr, "%d Bytes read are wrong'%s'\n", count, buf);
}
if (fdout > -1) {
char *p=buf;
while(--argc) {
int l=strlen(*pp);
memcpy(p, *pp, l);
++pp;
p+=l;
*p++ = 32;
}
*p++='\0';
write(fdout, buf, (int)(p-buf));
close(fdout); close(fdout);
while (0 < (size = read(fdin, buf, sizeof(buf)))) { loc_lseek(fdin, 0, 0);
memset(buf, 0, 512);
while (0 < (size = loc_read(fdin, buf, 512 /*sizeof(buf)*/))) {
write(1, buf, size); write(1, buf, size);
loc_lseek(fdin, 0, 2);
} }
close(fdin);
loc_close(fdin);
return(0); return(0);
}
loc_close(fdin);
} else } else
fprintf(stderr, "Cannot open PIPECOMMAND '%s'\n", unxcomm); fprintf(stderr, "Cannot open PIPECOMMAND '%s'\n", unxcomm);
} }

Binary file not shown.

BIN
examples/comm32.exe Normal file

Binary file not shown.

View File

@ -1,4 +1,4 @@
/* config.h: 04-Feb-98 */ /* config.h: 11-Jul-98 */
/* some of this config is needed by make, others by cc */ /* some of this config is needed by make, others by cc */
#define DO_DEBUG 1 /* compile in debug code */ #define DO_DEBUG 1 /* compile in debug code */
@ -14,7 +14,7 @@
# define FILENAME_NW_INI "/etc/nwserv.conf" # define FILENAME_NW_INI "/etc/nwserv.conf"
/* full name of ini (conf) file */ /* full name of ini (conf) file */
# define PATHNAME_PROGS "/usr/sbin" /* where to find the executables */ # define PATHNAME_PROGS "/usr/sbin" /* where to find the executables */
# define PATHNAME_BINDERY "/etc" /* directory for bindery-files */ # define PATHNAME_BINDERY "/var/nwserv/db" /* directory for bindery-files */
#endif #endif
#define PATHNAME_PIDFILES "/var/run" /* directory for 'pidfiles' */ #define PATHNAME_PIDFILES "/var/run" /* directory for 'pidfiles' */
@ -77,9 +77,7 @@
#define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */ #define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */
/* main idea from Victor Khimenko */ /* main idea from Victor Khimenko */
/* in 0.99.pl0 still NOT working !! */ /* still NOT working !! */
#define NEW_ATTRIB_HANDLING 0 /* better (if working ;)) attrib handling */
/* <--------------- next is for linux only ----------------------------> */ /* <--------------- next is for linux only ----------------------------> */
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */ #define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */

BIN
examples/e.pck Normal file

Binary file not shown.

1
examples/mk Executable file
View File

@ -0,0 +1 @@
make unxcomm && mv unxcomm /u3/pipes/.

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# mk.li 10-Jul-97 # mk.li 15-Dec-99
# please edit this file ! # please edit this file !
mk() mk()
@ -43,7 +43,8 @@ case $UNX in
CPP="cc -E" CPP="cc -E"
# CFLAGS="-pipe -O2 -fomit-frame-pointer" # CFLAGS="-pipe -O2 -fomit-frame-pointer"
# problems gcc2.5.8 ^^^^^^^^^^^^^^^^^^^^^ # problems gcc2.5.8 ^^^^^^^^^^^^^^^^^^^^^
CFLAGS="-pipe -Wall" # CFLAGS="-pipe -Wall -Dsignal=sysv_signal"
CFLAGS="$RPM_OPT_FLAGS -pipe -Wall -D_GNU_SOURCE"
case $MASCHINE in case $MASCHINE in
sparc) sparc)
@ -59,7 +60,17 @@ if [ -f /usr/lib/libgdbm.a ] || [ -f /usr/lib/libgdbm.so ] ; then
else else
NDBMLIB="-ldbm" NDBMLIB="-ldbm"
fi fi
if [ -f /usr/lib/libcrypt.so ] ; then
CRYPTLIB="-lcrypt"
else
CRYPTLIB="" CRYPTLIB=""
fi
if [ -f /usr/include/sys/quota.h ] ; then
HOSTCFLAGS="$HOSTCFLAGS -DQTAINSYS"
fi
NSLLIB="" NSLLIB=""
MAKE=make MAKE=make
TMP=/tmp TMP=/tmp
@ -80,6 +91,28 @@ fi
TMP=/tmp TMP=/tmp
INSTALL=/usr/ucb/install INSTALL=/usr/ucb/install
;; ;;
########## FreeBSD ############
# created by Boris Popov
freebsd)
V_VPATH=".."
OBJDIR="obj"
CC=gcc
CPP="gcc -E"
if [ "x$CFLAGS" = "x" ]; then
CFLAGS="native"
fi
HOSTCFLAGS="-DFREEBSD -DLINUX"
CRYPTLIB="-lcrypt -lipx"
NSLLIB=""
MAKE=make
TMP="./"
INSTALL="install -c"
;;
*) echo "mk.li: Unknown or not supported OS, probably you must set \$UNX" *) echo "mk.li: Unknown or not supported OS, probably you must set \$UNX"
;; ;;
esac esac
@ -95,7 +128,9 @@ esac
export CC export CC
export CPP export CPP
export CFLAGS if [ "X$CFLAGS" != "Xnative" ]; then
export CFLAGS
fi
export HOSTCFLAGS export HOSTCFLAGS
export NDBMLIB export NDBMLIB
export CRYPTLIB export CRYPTLIB

View File

@ -2,8 +2,11 @@
# This is the configuration-file for "mars_nwe", a free netware-emulator # This is the configuration-file for "mars_nwe", a free netware-emulator
# for Linux. # for Linux.
# #
# last changed: 08-Feb-98 # last changed: 04-Apr-00
# # !! section 31 : flags added in 0.99.pl18, but not used
# !! section 8 : new flags added in 0.99.pl18 !!
# !! section 9 : default directory/file umask changed in 0.99.pl9 !!
# !! section 46 : default attrib location changed in 0.99.pl9 !!
# !! section 5 : deleting of ipx devices/routes changed in 0.99.pl6 !! # !! section 5 : deleting of ipx devices/routes changed in 0.99.pl6 !!
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !! # !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
# #
@ -97,15 +100,18 @@
# #
# OPTIONS: none or some of the following characters (without a seperator) # OPTIONS: none or some of the following characters (without a seperator)
# - Placeholder. # - Placeholder.
#
# Next two options control DOS and OS/2 namespace. # Next two options control DOS and OS/2 namespace.
# i ignore case, handle mixing upper/lowercase filenames (slow) # i ignore case, handle mixing upper/lowercase filenames (slow)
# should only be used if you really need it. # should only be used if you really need it.
# k use lowercase-filenames (if you don't set this, # k use lowercase-filenames (if you don't set this,
# and you don't set 'i' all files _must_ be upper-case) # and you don't set 'i' all files _must_ be upper-case)
#
# m removable volume (e.g. cd-roms) or volumes, which # m removable volume (e.g. cd-roms) or volumes, which
# should be remountable when mars_nwe is running. # should be remountable when mars_nwe is running.
# r volume is read-only and always reports "0 byte free" # n (n)o fixed inodes. This volume do not have fixed inodes.
# (this is intended for copies of CD-ROMs on harddisks) # e.g. DOS-Volumes, CD-ROMS. This flag is very important for
# attrib and trustee handling.
# o (lowercase o) # o (lowercase o)
# volume has only one filesystem/device/namespace # volume has only one filesystem/device/namespace
# this is for filesystems with high inode > 0xFFFFFFF. # this is for filesystems with high inode > 0xFFFFFFF.
@ -114,6 +120,17 @@
# between several devices/namespaces for one volume. # between several devices/namespaces for one volume.
# p "PIPE"-filesystem. All files are pipe commands. # p "PIPE"-filesystem. All files are pipe commands.
# See `doc/PIPE-FS'. # See `doc/PIPE-FS'.
# r volume is read-only and always reports "0 byte free"
# (this is intended for copies of CD-ROMs on harddisks)
# t volume has trustees.
# Real access is trustee rights + unix rights.
# Trustees are stored in extra directories,
# normally under /var/nwserv/trustees.
# Must only be used for volume which have fix inodes.
# A volume with trustees should never be renamed.
# For some more notes see 'doc/TRUSTEES'.
# T volume has trustees & ignore the rights granted in UN*X filesystem
# exactly like option "t" except that the unix rights are not added
# #
# additional Namespaces # additional Namespaces
# O (uppercase o) # O (uppercase o)
@ -123,21 +140,21 @@
# #
# UMASKDIR: default directory creat umask. # UMASKDIR: default directory creat umask.
# UMASKFILE: default file creat umask. # UMASKFILE: default file creat umask.
# value are always octal, overwrite standard section 9 entries # values are always octal, they overwrite standard
# for this specific volume. # section 9 values for this specific volume.
# #
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# #
# Examples: # Examples:
# 1 SYS /var/local/nwe/SYS k # 1 SYS /var/local/nwe/SYS kt 711 600
# 1 CDROM /cdrom kmor # 1 CDROM /cdrom kmnor
# 1 HOME ~ k -1 # 1 HOME ~ k -1
# 1 HOMETMP ~/tmp kiO # 1 HOMETMP ~/tmp kiO
# 1 PRIVAT ~/privat kO 700 600 # 1 PRIVAT ~/privat kO 700 600
# 1 WORLD /var/world kiO 777 666 # 1 WORLD /var/world kiO 777 666
# 1 FAXQ /var/spool/fax/faxqueue k
1 SYS /u3/SYS/ kt 711 600
1 SYS /u3/SYS/ k -1
# ========================================================================= # =========================================================================
@ -297,18 +314,24 @@
# beyond the lifetime of the server or router. # beyond the lifetime of the server or router.
# If this flag is not set then all by nwserv/nwrouted added # If this flag is not set then all by nwserv/nwrouted added
# ipx-devices/routes will be deleted when # ipx-devices/routes will be deleted when
# nwserv/nwrouted ends (default). # nwserv/nwrouted ends and if no ipx socket is still
# open. (default).
# #
# 0x2 Switch on automatic kernel creation of ipx-interfaces. # 0x2 Switch on automatic kernel creation of ipx-interfaces.
# The automatic kernel creating of ipx-devices sometimes # The automatic kernel creating of ipx-devices sometimes
# make trouble (Win95). It should only be used in the # make trouble (Win95). It should only be used in the
# beginning or for testing. # beginning or for testing !!
# #
# 0x4 do remove ALL routes and ipx-devices # 0x4 do remove ALL routes and ipx-devices
# beyond the lifetime of the server or router. # beyond the lifetime of the server or router.
# If this flag is set then all ipx-devices/routes # If this flag is set then all ipx-devices/routes
# will be deleted when nwserv/nwrouted ends. # will be deleted when nwserv/nwrouted ends,
# without looking for open ipx sockets.
# This was the default prior mars_nwe 0.99.pl6 ! # This was the default prior mars_nwe 0.99.pl6 !
# This also do complete ipx reinit when starting
# mars_nwe.
# This was the default prior mars_nwe 0.99.pl9 !
#
# #
# #
# other flags may follow. # other flags may follow.
@ -412,6 +435,15 @@
# in some volume info calls. # in some volume info calls.
# some DOS clients need it. # some DOS clients need it.
# #
# 0x80 allows renaming a file even if the file is opened by
# other process.
# ( this was standard before mars_nwe-0.99.pl18 )
#
# 0x100 not used yet.
#
# 0x200 needed for direct int17 printing on NETX clients
# (patch from Przemyslaw Czerpak)
#
# other flags may follow. # other flags may follow.
# value will be interpreted as hex value. # value will be interpreted as hex value.
@ -426,9 +458,9 @@
# if -1 is specified for directories the st_mode of parent directory # if -1 is specified for directories the st_mode of parent directory
# will be used. # will be used.
# Volumes depended values can be set in section 1. # Volumes depended values can be set in section 1.
# 9 -1 0664 # 9 -1 0640
# #
9 0755 0664 9 0751 0640
# Section 10: UID and GID with minimal rights # Section 10: UID and GID with minimal rights
# ========================================================================= # =========================================================================
@ -536,17 +568,19 @@
# a '-' sign as password. # a '-' sign as password.
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Syntax: # Syntax:
# 13 NW_LOGIN LINUX_LOGIN [PASSWORD] [FLAGS] # 13 NW_LOGIN [LINUX_LOGIN] [PASSWORD] [FLAGS]
# #
# FLAGS must be a hex value begin with 0x # FLAGS must be a hex value begin with 0x
# the only FLAG value in the moment is 0x1 for 'fixed passwords' # the only FLAG value in the moment is 0x1 for 'fixed passwords'
# which cannot be changed by user. # which cannot be changed by user.
# Example: # Example:
# 13 MARTIN
# 13 MARTIN martin # 13 MARTIN martin
# 13 DAREK martin # 13 DAREK martin
# 13 COMMON common gast 0x1 # no password change by user. # 13 COMMON common gast 0x1 # no password change by user.
# 13 COMMON common 0x1 # syntax is allowed too. # 13 COMMON common 0x1 # syntax is allowed too.
13 GUEST nobody - 0x1
# Section 14: currently not used # Section 14: currently not used
@ -594,21 +628,45 @@
15 0 top-secret 15 0 top-secret
# ========================================================================= # =========================================================================
# Section 16: Tests on startup # Section 16: Tests on startup
# #
# If you want some sanity checks at startup, set this flag to 1. # If you want some sanity checks at startup, set this flag to > 0.
# "mars_nwe" will try to create/change missing directories: # "mars_nwe" will try to create/change missing directories:
# SYS:LOGIN, SYS:MAIL, SYS:MAIL/XXX, SYS:PUBLIC, SYS:SYSTEM ... # SYS:LOGIN, SYS:MAIL, SYS:MAIL/XXX, SYS:PUBLIC, SYS:SYSTEM ...
# (with the "right" permissions, of course) if you enable this. # (with the "right" permissions, of course) if you enable this.
# should also be enabled when you use a new mars_nwe version. # should also be enabled when you use a new mars_nwe version.
# Disabling this test only spares little time when starting mars_nwe. # Disabling this test only spares little time when starting mars_nwe.
# some values:
# 1 few important tests.
# 2 also check/compress bindery.
16 1 16 1
# Section 17-20: currently not used # Section 17: some bindery / user related flags.
# =========================================================================
# Flags
# 0x1 give all user an empty! login script, if they do not
# already have one. Is interpreted by test routines
# which run if section 16 is set and nwserv starts
# or got a SIGHUP. ( nwserv -h )
#
# other flags may follow.
# value will be interpreted as hex value.
17 0x0
# Section 18: some queue handling related flags.
# =========================================================================
# Flags
# 0x1 always unset (disable) the print banner flag.
#
# other flags may follow.
# value will be interpreted as hex value.
18 0x0
# Section 19-20: currently not used
# ========================================================================= # =========================================================================
@ -650,7 +708,10 @@
# Examples: # Examples:
# 21 LASER - lpr -Plaser # 21 LASER - lpr -Plaser
# 21 OCTOPUSS # 21 OCTOPUSS
# 21 FAXPRINT - /usr/bin/psfaxprn /var/spool/fax/faxqueue
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
21 LP - lpr -
21 LP_PS
# ========================================================================= # =========================================================================
@ -659,10 +720,17 @@
# e.g. to enable printing with ncpfs pserver # e.g. to enable printing with ncpfs pserver
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
# Syntax: # Syntax:
# 22 PSERVER_NAME QUEUE_NAME # 22 PSERVER_NAME QUEUE_NAME [FLAGS]
#
# FLAGS:
# 1 Let PSERVER_NAME be a 'normal' user (type 1).
# Used for simple qserver which works under 'normal' user login.
#
# Examples: # Examples:
# 22 PS1 OCTOPUSS # 22 PS1 OCTOPUSS
22 PS_NWE LP_PS 1
# ========================================================================= # =========================================================================
# Section 30: Burst mode values (optional) # Section 30: Burst mode values (optional)
@ -675,6 +743,13 @@
# 30 0x2000 0x2000 # 30 0x2000 0x2000
# =========================================================================
# Section 31: not used yet
# =========================================================================
# Flags not used yet
#
31 0x0
# ========================================================================= # =========================================================================
# Section 40ff: Some pathes (optional) # Section 40ff: Some pathes (optional)
# #
@ -688,9 +763,11 @@
# #
# #
# 45 = path for bindery file's # 45 = path for bindery file's
45 /etc 45 /var/nwserv/db
# 46 = path for attribute handling and later trustees # 46 = path for attribute handling
46 /var/lib/nwserv/attrib 46 /var/nwserv/attrib
# 47 = path for trustee handling
47 /var/nwserv/trustees
# ========================================================================= # =========================================================================
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru> # Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
# Tables for DOS->Unix names translation & upper/lowercase translations # Tables for DOS->Unix names translation & upper/lowercase translations

View File

@ -1,6 +1,7 @@
# example for nwopt file. # example for nwopt file.
# !!!! NOT USED !!!!!
# #
# last changed: 18-Nov-97 # last changed: 10-May-98
# #
# Syntax similar like nwserv.conf file. # Syntax similar like nwserv.conf file.
# #

View File

@ -1,12 +1,21 @@
/* unxcomm.c 08-Jun-97 */ /* unxcomm.c 22-Oct-98
/* simple UNX program to work together with 'comm' */ * simple UNX program to work together with 'comm'
/* to demonstrate usage of pipefilesystem */ * to demonstrate usage of pipefilesystem
* needs mars_nwe version >= 0.99.pl13 !
* comm and unxcomm must be same version !
* 'run' directory must exist and must have
* read and write permission for every user.
*/
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
static char **build_argv(int bufsize, char *command, int len) static char **build_argv(int bufsize, char *command, int len)
/* routine returns **argv for use with execv routines */ /* routine returns **argv for use with execv routines */
@ -51,8 +60,8 @@ int bl_read(int fd, void *buf, int size)
int result; int result;
FD_ZERO(&fdin); FD_ZERO(&fdin);
FD_SET(fd, &fdin); FD_SET(fd, &fdin);
t.tv_sec = 0; t.tv_sec = 1;
t.tv_usec = 100; /* 100 msec should be enough */ t.tv_usec = 0;
result = select(fd+1, &fdin, NULL, NULL, &t); result = select(fd+1, &fdin, NULL, NULL, &t);
if (result > 0) if (result > 0)
result=read(fd, buf, size); result=read(fd, buf, size);
@ -61,15 +70,49 @@ int bl_read(int fd, void *buf, int size)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int size=0; int size=-1;
int l; int pid=getpid();
char buf[MAXARGLEN+1024]; char buf[MAXARGLEN+1024];
char fifopath[257];
char *p;
close(2); close(2);
dup2(1,2); dup2(1,2);
while (0 < (l=bl_read(0, buf+size, MAXARGLEN-size))) if (argc > 3) {
strcpy(fifopath, argv[0]);
p=strrchr(fifopath, '/');
if (p) {
++p;
sprintf(p, "run/%08x.in", pid);
if (mkfifo(fifopath, 0600)) {
perror("mkfifo");
fprintf(stderr, "unxcomm:fifo.in=`%s`\n", fifopath);
} else {
fprintf(stdout, "#%08x\n", pid);
fflush(stdout);
size=0;
}
}
}
if (!size) {
int tries=0;
int fd = open(fifopath, O_RDONLY);
if (fd > -1) {
while (tries++ < 5) {
int l;
while (0 < (l=bl_read(fd, buf+size, MAXARGLEN-size))) {
size+=l; size+=l;
}
if (size && buf[size-1] == '\0') break;
}
close(fd);
} else {
perror("open fifo");
size=-1;
}
unlink(fifopath);
}
if ( 0 < size) { if ( 0 < size) {
char **argvv=build_argv(sizeof(buf), buf, size); char **argvv=build_argv(sizeof(buf), buf, size);
if (argvv) { if (argvv) {

View File

@ -1,4 +1,4 @@
/* extpipe.c 08-Aug-97 */ /* extpipe.c 03-Aug-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -19,7 +19,7 @@
#include "net.h" #include "net.h"
#include "extpipe.h" #include "extpipe.h"
static char **build_argv(char *buf, int bufsize, char *command) static char **build_argv(char *buf, int bufsize, char *command, int flags)
/* routine returns **argv for use with execv routines */ /* routine returns **argv for use with execv routines */
/* buf will contain the path component */ /* buf will contain the path component */
{ {
@ -43,7 +43,7 @@ static char **build_argv(char *buf, int bufsize, char *command)
*(++pp)=p; *(++pp)=p;
i++; i++;
} }
} else if (!i && c == '/') { /* here i must get argv[0] */ } else if (!i && (flags&1) && c == '/') { /* here i must get argv[0] */
*pp=p; *pp=p;
} }
} }
@ -73,13 +73,13 @@ static void close_piped(int piped[3][2])
} }
} }
static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp) static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp, int flags)
{ {
int piped[3][2]; int piped[3][2];
int lpid=-1; int lpid=-1;
int j=3; int j=3;
char buf[300]; char buf[300];
char **argv=build_argv(buf, sizeof(buf), command); char **argv=build_argv(buf, sizeof(buf), command, flags);
if (argv == NULL) return(-1); if (argv == NULL) return(-1);
while (j--){ while (j--){
int k=2; int k=2;
@ -113,7 +113,10 @@ static int x_popen(char *command, int uid, int gid, FILE_PIPE *fp)
if (gid > -1) setegid(gid); if (gid > -1) setegid(gid);
if (uid > -1) seteuid(uid); if (uid > -1) seteuid(uid);
} }
if (flags&1)
execvp(buf, argv); execvp(buf, argv);
else
execv(buf, argv);
exit(1); /* Never reached I hope */ exit(1); /* Never reached I hope */
} }
j=-1; j=-1;
@ -134,12 +137,18 @@ int ext_pclose(FILE_PIPE *fp)
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN); void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
int j = 3; int j = 3;
int tries=5;
while (j--) close(fp->fds[j]); while (j--) close(fp->fds[j]);
if (fp->command_pid != waitpid(fp->command_pid, &status, 0)) { while (fp->command_pid != waitpid(fp->command_pid, &status, WNOHANG)
&& tries>0) {
--tries;
XDPRINTF((10,0, "ext_pclose, tries=%d", tries));
if (tries==2 || tries==1)
kill(fp->command_pid, SIGTERM); kill(fp->command_pid, SIGTERM);
waitpid(fp->command_pid, &status, 0); else if (!tries)
}
kill(fp->command_pid, SIGKILL); kill(fp->command_pid, SIGKILL);
sleep(1);
}
signal(SIGINT, intsave); signal(SIGINT, intsave);
signal(SIGQUIT, quitsave); signal(SIGQUIT, quitsave);
signal(SIGHUP, hupsave); signal(SIGHUP, hupsave);
@ -147,13 +156,14 @@ int ext_pclose(FILE_PIPE *fp)
return(status); return(status);
} }
FILE_PIPE *ext_popen(char *command, int uid, int gid) FILE_PIPE *ext_popen(char *command, int uid, int gid, int flags)
/* flags & 1 use path version of exec */
{ {
FILE_PIPE *fp=(FILE_PIPE*) xcmalloc(sizeof(FILE_PIPE)); FILE_PIPE *fp=(FILE_PIPE*) xcmalloc(sizeof(FILE_PIPE));
void (*intsave) (int) = signal(SIGINT, SIG_IGN); void (*intsave) (int) = signal(SIGINT, SIG_IGN);
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN); void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN); void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
if ((fp->command_pid = x_popen(command, uid, gid, fp)) < 0) { if ((fp->command_pid = x_popen(command, uid, gid, fp, flags)) < 0) {
xfree(fp); xfree(fp);
fp=NULL; fp=NULL;
XDPRINTF((1, 0x10, "ext_popen failed:uid=%d, gid=%d,command='%s'", XDPRINTF((1, 0x10, "ext_popen failed:uid=%d, gid=%d,command='%s'",

View File

@ -1,4 +1,4 @@
/* extpipe.h 08-Aug-97 */ /* extpipe.h 31-Jul-98 */
#ifndef _EXTPIPE_H_ #ifndef _EXTPIPE_H_
#define _EXTPIPE_H_ #define _EXTPIPE_H_
@ -11,6 +11,6 @@ typedef struct {
} FILE_PIPE; } FILE_PIPE;
extern int ext_pclose(FILE_PIPE *fp); extern int ext_pclose(FILE_PIPE *fp);
extern FILE_PIPE *ext_popen(char *command, int uid, int gid); extern FILE_PIPE *ext_popen(char *command, int uid, int gid, int flags);
#endif #endif

233
ftrustee.c Normal file
View File

@ -0,0 +1,233 @@
/* ftrustee.c, 19.09.99 */
/* (C)opyright (C) 1999 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "net.h"
#include "trustee.h"
#include "nwvolume.h"
int default_uid=-1;
int default_gid=-1;
int act_uid=0; // unix uid
int act_gid=0; // unix uid
int act_id_flags=0; /* &1 == supervisor equivalence !!! */
int act_obj_id=0L; /* mars_nwe UID, 0=not logged in, 1=supervisor */
static gid_t *act_grouplist=NULL; /* first element is counter !! */
void set_default_guid(void)
{
seteuid(0);
setgroups(0, NULL);
if (setegid(default_gid) < 0 || seteuid(default_uid) < 0) {
errorp(1, "set_default_guid, !! SecurityAbort !!",
"Cannot set default gid=%d and uid=%d" , default_gid, default_uid);
exit(1);
}
act_gid = default_gid;
act_uid = default_uid;
xfree(act_grouplist);
}
void set_guid(int gid, int uid)
{
if ( gid < 0 || uid < 0
|| seteuid(0)
|| setegid(gid)
|| seteuid(uid) ) {
set_default_guid();
if (gid < 0 && uid < 0) {
/* don't print error */
gid = act_gid;
uid = act_uid;
}
} else if (act_gid != gid || act_uid != uid) {
struct passwd *pw = getpwuid(uid);
if (NULL != pw) {
seteuid(0);
initgroups(pw->pw_name, gid);
}
act_gid = gid;
act_uid = uid;
xfree(act_grouplist);
if (seteuid(uid))
set_default_guid();
else {
int k=getgroups(0, NULL);
if (k > 0) {
act_grouplist=(gid_t*)xmalloc((k+1) * sizeof(gid_t));
getgroups(k, act_grouplist+1);
*act_grouplist=(gid_t)k;
}
}
}
XDPRINTF((5,0,"SET GID=%d, UID=%d %s", gid, uid,
(gid==act_gid && uid == act_uid) ? "OK" : "failed"));
}
void reset_guid(void)
{
set_guid(act_gid, act_uid);
}
void reseteuid(void)
{
if (seteuid(act_uid))
reset_guid();
}
int in_act_groups(gid_t gid)
/* returns 1 if gid is member of act_grouplist else 0 */
{
int k;
gid_t *g;
if (!act_grouplist) return(0);
k=(int)*act_grouplist;
g = act_grouplist;
while (k--) {
if (*(++g) == gid) return(1);
}
return(0);
}
int get_unix_eff_rights(struct stat *stb)
/* returns F_OK, R_OK, W_OK, X_OK */
/* ORED with 0x10 if owner access */
/* ORED with 0x20 if group access */
{
int mode = 0;
if (!act_uid)
return(0x10 | R_OK | W_OK | X_OK) ; /* root */
else {
if (act_uid == stb->st_uid) {
mode |= 0x10;
if (stb->st_mode & S_IXUSR)
mode |= X_OK;
if (stb->st_mode & S_IRUSR)
mode |= R_OK;
if (stb->st_mode & S_IWUSR)
mode |= W_OK;
} else if ( (act_gid == stb->st_gid)
|| in_act_groups(stb->st_gid) ) {
mode |= 0x20;
if (stb->st_mode & S_IXGRP)
mode |= X_OK;
if (stb->st_mode & S_IRGRP)
mode |= R_OK;
if (stb->st_mode & S_IWGRP)
mode |= W_OK;
} else {
if (stb->st_mode & S_IXOTH)
mode |= X_OK;
if (stb->st_mode & S_IROTH)
mode |= R_OK;
if (stb->st_mode & S_IWOTH)
mode |= W_OK;
}
}
return(mode);
}
#if 0
FILE *open_trustee_file(char *volname, char *opmode)
{
FILE *f=fopen(
return(f);
}
#endif
int do_export_trustees(char *expfn)
{
int j=0;
NW_VOL *v = nw_volumes;
while (j++ < used_nw_volumes) {
FILE *f=NULL;
if (v->options & VOL_OPTION_TRUSTEES) {
char fn[300];
memcpy(fn, v->unixname, v->unixnamlen);
strmaxcpy(fn+v->unixnamlen, ".trustees", 300-v->unixnamlen-1);
printf("volume %d, '%s', '%s', '%s'\n",
j, v->sysname, v->unixname, fn);
if (NULL != (f=fopen(fn, "w")) ) {
chmod(fn, 0600);
chown(fn, 0, 0);
fclose(f);
} else
errorp(0, "do_export_trustees", "cannot open '%s'", fn);
}
v++;
}
return(-1);
}
int do_import_trustees(char *expfn)
{
return(-1);
}
static int localinit(void)
{
FILE *f= open_nw_ini();
if (f != (FILE*) NULL){
int k=-1;
nw_init_volumes(f);
fclose(f);
printf("Count Volumes = %d, trusteepath=%s\n",
used_nw_volumes, path_trustees);
#if 1
while (++k < used_nw_volumes) {
NW_VOL *v = nw_volumes+k;
printf("volume %2d|%-15s|%s\n", k, v->sysname, v->unixname);
}
#endif
} else
printf("open_nw_ini failed\n");
return(0);
}
static int usage(char *s)
{
char *p=strrchr(s, '/');
fprintf(stderr, "usage:\t%s e | i | r [path]\n", p ? p+1 : s);
fprintf(stderr, "\te = export\n");
fprintf(stderr, "\ti = import\n");
fprintf(stderr, "\tr = repair\n");
return(1);
}
int main(int argc, char *argv[])
{
init_tools(0, 0);
nw_debug = 5;
localinit();
if (argc < 2) return(usage(argv[0]));
if (*argv[1] == 'e') return(do_export_trustees(argv[2]));
else if (*argv[1] == 'i') return(do_import_trustees(argv[2]));
else if (*argv[1] == 'r') if (!do_export_trustees(argv[2]))
return(do_import_trustees(argv[2]));
else return(1);
else usage(argv[0]);
return(0);
}

197
ipxif.c Normal file
View File

@ -0,0 +1,197 @@
/* inserted by Boris Popov <bp@butya.kz> */
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <net/if.h>
#ifndef if_mtu
# include <net/if_var.h>
#endif
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
/* IPX */
#include <netipx/ipx.h>
#include <netipx/ipx_if.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "emutli.h"
static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
static int if_ipxscan __P((int addrcount, struct sockaddr_dl *sdl, struct if_msghdr *ifm,
struct ifa_msghdr *ifam,struct ipx_addr *addr));
/*
* Find IPX interface.
* ifname specifies interface name, if NULL search for all interfaces
* if ifname[0]='0', also all interfaces, but return its name
* addr on input preferred net address can be specified or 0 for any,
* on return contains full address (except port)
* returns 0 if interface was found
*/
int
ipx_iffind(char *ifname,struct ipx_addr *addr){
char name[32];
int all=0, flags, foundit = 0, addrcount;
struct if_msghdr *ifm, *nextifm;
struct ifa_msghdr *ifam;
struct sockaddr_dl *sdl;
char *buf, *lim, *next;
size_t needed;
int mib[6];
if( ifname!=NULL ) {
strncpy(name,ifname,sizeof(name)-1);
if( name[0]==0 )
all=1;
} else
all = 1;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_IPX;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
return(1);
if ((buf = malloc(needed)) == NULL)
return(1);
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
free(buf);
return(1);
}
lim = buf + needed;
next = buf;
while (next < lim) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
flags = ifm->ifm_flags;
} else {
fprintf(stderr, "if_ipxfind: out of sync parsing NET_RT_IFLIST\n");
fprintf(stderr, "expected %d, got %d\n", RTM_IFINFO, ifm->ifm_type);
fprintf(stderr, "msglen = %d\n", ifm->ifm_msglen);
fprintf(stderr, "buf:%p, next:%p, lim:%p\n", buf, next, lim);
free(buf);
return(1);
}
next += ifm->ifm_msglen;
ifam = NULL;
addrcount = 0;
while (next < lim) {
nextifm = (struct if_msghdr *)next;
if (nextifm->ifm_type != RTM_NEWADDR)
break;
if (ifam == NULL)
ifam = (struct ifa_msghdr *)nextifm;
addrcount++;
next += nextifm->ifm_msglen;
}
if (all) {
if ((flags & IFF_UP) == 0)
continue; /* not up */
strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
name[sdl->sdl_nlen] = '\0';
} else {
if (strlen(name) != sdl->sdl_nlen)
continue; /* not same len */
if (strncmp(name, sdl->sdl_data, sdl->sdl_nlen) != 0)
continue; /* not same name */
}
foundit=if_ipxscan(addrcount, sdl, ifm, ifam, addr);
if( foundit ) {
if( ifname!=NULL && ifname[0]==0) {
strncpy(ifname,sdl->sdl_data, sdl->sdl_nlen);
ifname[sdl->sdl_nlen]=0;
}
break;
}
}
free(buf);
return foundit ? 0:1;
}
int
if_ipxscan(addrcount, sdl, ifm, ifam, addr)
int addrcount;
struct sockaddr_dl *sdl;
struct if_msghdr *ifm;
struct ifa_msghdr *ifam;
struct ipx_addr *addr;
{
struct rt_addrinfo info;
struct sockaddr_ipx *sipx;
int s;
if ((s = socket(AF_IPX, SOCK_DGRAM, 0)) < 0) {
perror("ifconfig: socket");
return 0;
}
while (addrcount > 0) {
info.rti_addrs = ifam->ifam_addrs;
/* Expand the compacted addresses */
rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
addrcount--;
ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
if (info.rti_info[RTAX_IFA]->sa_family == AF_IPX) {
sipx = (struct sockaddr_ipx *)info.rti_info[RTAX_IFA];
if( ipx_nullnet(sipx->sipx_addr) ) continue;
if( ipx_nullnet(*addr) ||
ipx_neteq(sipx->sipx_addr,*addr) ) {
*addr=sipx->sipx_addr;
close(s);
return(1);
}
}
}
close(s);
return(0);
}
/*
* Expand the compacted form of addresses as returned via the
* configuration read via sysctl().
*/
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
static void
rt_xaddrs(cp, cplim, rtinfo)
caddr_t cp, cplim;
struct rt_addrinfo *rtinfo;
{
struct sockaddr *sa;
int i;
memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
if ((rtinfo->rti_addrs & (1 << i)) == 0)
continue;
rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
ADVANCE(cp, sa);
}
}

View File

@ -1,5 +1,5 @@
#if 0 #if 0
#makefile.unx 04-Feb-98 #makefile.unx 15-Apr-00
#endif #endif
VPATH=$(V_VPATH) VPATH=$(V_VPATH)
@ -9,7 +9,7 @@ C=.c
V_H=0 V_H=0
V_L=99 V_L=99
P_L=6 P_L=19
#define D_P_L 1 #define D_P_L 1
DISTRIB=mars_nwe DISTRIB=mars_nwe
@ -79,6 +79,7 @@ PROG5=nwclient
PROG6=nwbind PROG6=nwbind
PROG7=nwrouted PROG7=nwrouted
PROG8=dbmtool PROG8=dbmtool
PROG9=ftrustee
#include "config.h" #include "config.h"
#ifdef FILENAME_NW_INI #ifdef FILENAME_NW_INI
@ -93,45 +94,55 @@ M_PATHNAME_PROGS=PATHNAME_PROGS
M_PATHNAME_PROGS="." M_PATHNAME_PROGS="."
#endif #endif
#ifndef INTERNAL_RIP_SAP M_PATHNAME_BINDERY=PATHNAME_BINDERY
#define INTERNAL_RIP_SAP 1
#endif
#ifdef LINUX #ifdef LINUX
# ifdef FREEBSD
EMUTLIOBJ=emutli$(O) ipxif$(O)
NWROUTE_O=nwroute1$(O)
NWROUTED=
# else
# ifndef INTERNAL_RIP_SAP
# define INTERNAL_RIP_SAP 1
# endif
EMUTLIOBJ=emutli$(O) EMUTLIOBJ=emutli$(O)
EMUTLIOBJ1=emutli1$(O)
# if INTERNAL_RIP_SAP # if INTERNAL_RIP_SAP
EMUTLIOBJ1=emutli1$(O)
NWROUTE_O=nwroute$(O) NWROUTE_O=nwroute$(O)
# else # else
EMUTLIOBJ1=
NWROUTE_O=nwroute1$(O) NWROUTE_O=nwroute1$(O)
NWROUTED=$(PROG7) NWROUTED=$(PROG7)
# endif # endif
# endif
#else #else
NWROUTE_O=nwroute1$(O) NWROUTE_O=nwroute1$(O)
NWROUTED=
#endif #endif
INSTALLPROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED) INSTALLPROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED)
PROGS=$(INSTALLPROGS) $(PROG8) PROGS=$(INSTALLPROGS) $(PROG8) $(PROG9)
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O) OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \ OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \ nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwattrib$(O) nwattrib$(O) trustee$(O)
OBJ4= $(OBJ1) OBJ4= $(OBJ1)
OBJ5= $(OBJ1) OBJ5= $(OBJ1)
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) unxfile$(O)
OBJ7= $(OBJ1) $(EMUTLIOBJ1) OBJ7= $(OBJ1) emutli1$(O)
OBJ8= $(OBJ6) OBJ8= $(OBJ6)
OBJ9= tools$(O) nwfname$(O) unxfile$(O) nwvolume$(O) nwattrib$(O) trustee$(O)
OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \ OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
$(EMUTLIOBJ1) $(NWROUTE_O) \ $(EMUTLIOBJ1) $(NWROUTE_O) \
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\ connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O)\
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \ nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
nwattrib$(O) \ nwattrib$(O) trustee$(O) \
nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \ nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) \
$(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \ $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) \
$(PROG7)$(O) $(PROG8)$(O) $(PROG7)$(O) $(PROG8)$(O) $(PROG9)$(O)
HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \ HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) \
unxfile$(O) unxfile$(O)
@ -168,6 +179,9 @@ $(PROG7): $(PROG7)$(O) $(OBJ7)
$(PROG8): $(PROG8)$(O) $(OBJ8) $(PROG8): $(PROG8)$(O) $(OBJ8)
$(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) $(CC) -o $(VPATH)/$(PROG8) $(PROG8)$(O) $(OBJ8) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB)
$(PROG9): $(PROG9)$(O) $(OBJ9)
$(CC) -o $(VPATH)/$(PROG9) $(PROG9)$(O) $(OBJ9) $(CRYPTLIB) $(NSLLIB)
$(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h
$(HOBJ6): nwbind.h sema.h $(HOBJ6): nwbind.h sema.h
$(OBJS): net.h config.h $(OBJS): net.h config.h
@ -195,6 +209,19 @@ n_install:
echo "remove old version in /sbin ?" ; \ echo "remove old version in /sbin ?" ; \
(cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \ (cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \
fi ; fi ;
@-if [ -r /etc/nwobj.pag ] ; then \
( \
if [ ! -r $(M_PATHNAME_BINDERY) ] ; then \
if $(VPATH)/tools.sh yesno "move bindery files from /etc to $(M_PATHNAME_BINDERY) ?" ; then \
mkdir -p $(M_PATHNAME_BINDERY); \
(cd /etc && mv \
nwiobj.pag nwiobj.dir nwobj.pag nwobj.dir \
nwprop.pag nwprop.dir nwval.pag nwval.dir \
$(M_PATHNAME_BINDERY) ) ; \
fi; \
fi; \
) \
fi ;
@cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \ @cd $(VPATH) && (if [ -r $(M_FILENAME_NW_INI) ] ; then \
echo ""; \ echo ""; \
echo "********************************************************"; \ echo "********************************************************"; \
@ -246,6 +273,7 @@ make_dir:
; ln -f \ ; ln -f \
$(STERN).[ch] \ $(STERN).[ch] \
makefile.unx \ makefile.unx \
tools.sh \
Makefile \ Makefile \
COPYING \ COPYING \
README \ README \

File diff suppressed because it is too large Load Diff

View File

@ -418,6 +418,10 @@ static void close_all(void)
{ {
int k=0; int k=0;
while (k++ < count_connections) clear_connection(k); while (k++ < count_connections) clear_connection(k);
kill_connections();
k=0;
while (k++ < count_connections) clear_connection(k);
kill_connections();
if (ncp_fd > -1) { if (ncp_fd > -1) {
t_unbind(ncp_fd); t_unbind(ncp_fd);
t_close(ncp_fd); t_close(ncp_fd);

30
net.h
View File

@ -1,4 +1,4 @@
/* net.h 02-Jun-97 */ /* net.h 12-Jan-99 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
@ -19,10 +19,21 @@
#ifndef _M_NET_H_ #ifndef _M_NET_H_
#define _M_NET_H_ #define _M_NET_H_
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 1
#endif
#define _SVID_SOURCE 1
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> /* moved 12-May-98 0.99.pl9 */
#include <signal.h> #include <signal.h>
#ifdef __USE_BSD
# undef signal
# define signal sysv_signal
#endif
#include <string.h> #include <string.h>
#ifndef LINUX #ifndef LINUX
@ -31,9 +42,12 @@
#endif #endif
#include <sys/fcntl.h> #include <sys/fcntl.h>
#include <sys/types.h> /* #include <sys/types.h> moved 12-May-98 0.99.pl9 */
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef S_ISLNK
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#include <time.h> #include <time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <utmp.h> #include <utmp.h>
@ -50,7 +64,6 @@ extern int errno;
/* # include "common.h" */ /* # include "common.h" */
/* # include "portable.h" , needed ??? */ /* # include "portable.h" , needed ??? */
# include <sys/ipx_app.h> # include <sys/ipx_app.h>
#else #else
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include "emutli.h" /* TLI-EMULATION */ # include "emutli.h" /* TLI-EMULATION */
@ -180,7 +193,7 @@ extern int errno;
#endif #endif
#ifndef PATHNAME_BINDERY #ifndef PATHNAME_BINDERY
# define PATHNAME_BINDERY "/etc" /* location of bindery files */ # define PATHNAME_BINDERY "/var/nwserv/db" /* location of bindery files */
#endif #endif
#ifndef PATHNAME_PIDFILES #ifndef PATHNAME_PIDFILES
@ -280,6 +293,11 @@ extern int errno;
# ifndef INTERNAL_RIP_SAP # ifndef INTERNAL_RIP_SAP
# define INTERNAL_RIP_SAP 1 # define INTERNAL_RIP_SAP 1
# endif # endif
# ifdef FREEBSD
/* FreeBSD has own rip/sap router */
# undef INTERNAL_RIP_SAP
# define INTERNAL_RIP_SAP 0
# endif
#else #else
/* USL has rip/sap router builtin */ /* USL has rip/sap router builtin */
# undef INTERNAL_RIP_SAP # undef INTERNAL_RIP_SAP
@ -370,7 +388,7 @@ typedef union {
*/ */
} diaresp; } diaresp;
struct S_NCPRESPONSE { /* size = 8 */ struct S_NCPRESPONSE { /* size = 8 */
uint8 type[2]; /* 0x3333 */ uint8 type[2]; /* 0x3333 or internal 0x3232 */
uint8 sequence; uint8 sequence;
uint8 connection; /* low connection */ uint8 connection; /* low connection */
uint8 task; uint8 task;
@ -379,7 +397,7 @@ typedef union {
uint8 connect_status; uint8 connect_status;
} ncpresponse; } ncpresponse;
struct S_NCPREQUEST { /* size = 7 */ struct S_NCPREQUEST { /* size = 7 */
uint8 type[2]; /* 0x1111 od 0x2222 */ uint8 type[2]; /* 0x1111 or 0x2222 or internal 0x1212 */
uint8 sequence; uint8 sequence;
uint8 connection; /* low connection */ uint8 connection; /* low connection */
uint8 task; uint8 task;

43
net1.c
View File

@ -1,6 +1,6 @@
/* net1.c, 11-Mar-97 */ /* net1.c, 19.09.99 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-99 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -355,3 +355,42 @@ int get_ipx_addr(ipxAddr_t *addr)
return(result); return(result);
} }
#endif #endif
uint8 *station_fn=NULL;
int find_station_match(int entry, ipxAddr_t *addr)
{
int matched = 0;
if (station_fn && *station_fn) {
FILE *f=fopen((char*)station_fn, "r");
if (f) {
uint8 buff[200];
uint8 addrstring[100];
int what;
ipx_addr_to_adr((char*)addrstring, addr);
upstr(addrstring);
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))){
if (what == entry) {
uint8 *p = buff + strlen((char*)buff);
while (p-- > buff && *p==32) *p='\0';
upstr(buff);
if (name_match(addrstring, buff)) {
matched=1;
break;
}
}
}
fclose(f);
} else {
XDPRINTF((3, 0, "find_station_match, cannot open '%s'",
station_fn));
}
}
XDPRINTF((3, 0, "find_station_match entry=%d, matched=%d, addr=%s",
entry, matched, visable_ipx_adr(addr)));
return(matched);
}

7
net1.h
View File

@ -1,6 +1,6 @@
/* net1.h 25-Oct-96 */ /* net1.h 19.09.99 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-99 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -48,4 +48,7 @@ extern int send_own_reply(int fd, int result, int sequence, ipxAddr_t *toaddr);
extern int get_ipx_addr(ipxAddr_t *addr); extern int get_ipx_addr(ipxAddr_t *addr);
extern uint8 *station_fn;
extern int find_station_match(int entry, ipxAddr_t *addr);
#endif #endif

View File

@ -1,4 +1,4 @@
/* nwattrib.c 09-Feb-98 */ /* nwattrib.c 10-May-98 */
/* (C)opyright (C) 1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -16,12 +16,14 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* Attrib routines for mars_nwe */
#include "net.h" #include "net.h"
#include <dirent.h> #include <dirent.h>
#include "unxfile.h" #include "unxfile.h"
#include "nwvolume.h" #include "nwvolume.h"
#include "connect.h" #include "connect.h"
#include "trustee.h"
#include "nwattrib.h" #include "nwattrib.h"
static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib) static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib)
@ -86,36 +88,42 @@ static int get_attr_from_disk(int dev, ino_t inode, uint32 *attrib)
return(0); return(0);
} }
} }
*attrib=0;
return(-1); return(-1);
} }
uint32 get_nw_attrib_dword(struct stat *stb, int voloptions) uint32 get_nw_attrib_dword(int volume, char *unixname, struct stat *stb)
/* returns full attrib_dword */ /* returns full attrib_dword */
{ {
uint32 attrib=0; uint32 attrib = S_ISDIR(stb->st_mode) ? FILE_ATTR_DIR
int is_dir=S_ISDIR(stb->st_mode); : FILE_ATTR_A;
if (!is_dir && (voloptions & VOL_OPTION_IS_PIPE)) int voloptions = get_volume_options(volume);
return(FILE_ATTR_SHARE|FILE_ATTR_A);
if (voloptions & VOL_OPTION_READONLY) if (voloptions & VOL_OPTION_IS_PIPE) {
return((is_dir)?FILE_ATTR_DIR|FILE_ATTR_R:FILE_ATTR_R); attrib |= (FILE_ATTR_DELETE_INH|FILE_ATTR_RENAME_INH);
if (!S_ISDIR(stb->st_mode)){
if (!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) { attrib|=FILE_ATTR_SHARE;
if (is_dir) attrib |= FILE_ATTR_DIR; }
else attrib &= (~FILE_ATTR_DIR); return(attrib);
} else {
if (is_dir)
attrib = FILE_ATTR_DIR;
else
attrib = FILE_ATTR_A; /* default archive flag */
} }
if ( (voloptions & VOL_OPTION_ATTRIBUTES) &&
!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) {
if (S_ISDIR(stb->st_mode)) attrib |= FILE_ATTR_DIR;
else attrib &= (~FILE_ATTR_DIR);
}
if (voloptions & VOL_OPTION_READONLY){
attrib |= (FILE_ATTR_DELETE_INH|FILE_ATTR_RENAME_INH|FILE_ATTR_R);
}
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
/* only for volumes without attribute handling */
if (act_uid) { if (act_uid) {
/* if not root */ /* if not root */
int acc=get_real_access(stb); int acc=get_unix_eff_rights(stb);
if (!(acc & W_OK)) { if (!(acc & W_OK)) {
attrib |= FILE_ATTR_R; /* RO */ attrib |= FILE_ATTR_R; /* RO */
} }
@ -123,207 +131,111 @@ uint32 get_nw_attrib_dword(struct stat *stb, int voloptions)
attrib |= FILE_ATTR_H; /* We say hidden here */ attrib |= FILE_ATTR_H; /* We say hidden here */
} }
} }
}
return(attrib); return(attrib);
} }
int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib) static int set_nw_attrib(
int volume, char *unixname, struct stat *stb, uint32 attrib, uint32 mode)
/* mode == 0 : set_nw_attrib_dword
1 : set_nw_attrib_byte
2 : set_nw_attrib_word
*/
{ {
int is_dir=S_ISDIR(stb->st_mode); int is_dir=S_ISDIR(stb->st_mode);
if (voloptions & VOL_OPTION_READONLY) uint32 oldattrib,newattrib;
return(-0x8c); /* no modify rights */ int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_IS_PIPE) if (voloptions & VOL_OPTION_IS_PIPE)
return(0); return(0); /* we return with no error */
if (tru_eff_rights_exists(volume, unixname, stb, TRUSTEE_M))
if (!(get_real_access(stb) & W_OK))
return(-0x8c); /* no modify rights */ return(-0x8c); /* no modify rights */
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
if (!(get_unix_eff_rights(stb) & W_OK)) {
if (!(attrib & FILE_ATTR_R)) { /* if not setting RO */
if (!chmod(unixname, stb->st_mode | S_IWUSR)) {
stb->st_mode |= S_IWUSR;
} else
return(-0x8c); /* no modify rights */
}
}
}
if (mode || !(voloptions & VOL_OPTION_ATTRIBUTES)) {
oldattrib=get_nw_attrib_dword(volume, unixname, stb);
if (mode==1) { /* byte */
newattrib = (oldattrib & ~0xff);
newattrib |= (attrib & 0xff);
} else if (mode==2) { /* word */
newattrib = (oldattrib & ~0xffff);
newattrib |= (attrib & 0xffff);
} else newattrib=attrib;
} else {
newattrib=attrib;
}
if (is_dir) attrib |= 0x10; if ((!mode) || (newattrib != oldattrib) ) {
else attrib &= ~0x10; if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
put_attr_to_disk(stb->st_dev, stb->st_ino, attrib); if ((!is_dir) && ((newattrib&FILE_ATTR_R)!=(oldattrib&FILE_ATTR_R))) {
int oldmode=stb->st_mode;
if (newattrib & FILE_ATTR_R) /* R/O */
stb->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
else
stb->st_mode |= (S_IWUSR | S_IWGRP);
if (chmod(unixname, stb->st_mode)) {
stb->st_mode = oldmode;
return(-0x8c); /* no modify rights */
}
}
} else {
if (is_dir) newattrib |= 0x10;
else newattrib &= ~0x10;
put_attr_to_disk(stb->st_dev, stb->st_ino, newattrib);
}
}
return(0); return(0);
} }
int set_nw_attrib_byte(struct stat *stb, int voloptions, int battrib) int set_nw_attrib_dword(int volume, char *unixname, struct stat *stb, uint32 attrib)
/* wattrib = ext_attrib, attrib */
{ {
int is_dir=S_ISDIR(stb->st_mode); return(set_nw_attrib(volume,unixname,stb,attrib, 0));
uint32 attrib,oldattrib;
if (voloptions & VOL_OPTION_READONLY)
return(-0x8c); /* no modify rights */
if (voloptions & VOL_OPTION_IS_PIPE)
return(0);
if (!(get_real_access(stb) & W_OK))
return(-0x8c); /* no modify rights */
oldattrib=get_nw_attrib_dword(stb, voloptions);
attrib = (oldattrib & ~0xff);
attrib |= battrib;
if (is_dir) attrib |= 0x10;
else attrib &= ~0x10;
if (attrib != oldattrib)
put_attr_to_disk(stb->st_dev, stb->st_ino, attrib);
return(0);
} }
void set_nw_archive_bit(int dev, ino_t inode) int set_nw_attrib_byte(int volume, char *unixname, struct stat *stb, int battrib)
/* only called for files */
{ {
uint32 attrib; return(set_nw_attrib(volume,unixname,stb,(uint32)battrib, 1));
}
int set_nw_attrib_word(int volume, char *unixname, struct stat *stb, int wattrib)
/* wattrib = ext_attrib, attrib */
{
return(set_nw_attrib(volume,unixname,stb,(uint32)wattrib, 2));
}
void set_nw_archive_bit(int volume, char *unixname, int dev, ino_t inode)
/* sets archive bit on files, is called when file is closed */
{
uint32 attrib=0L;
int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_ATTRIBUTES) {
if ( (!get_attr_from_disk(dev, inode, &attrib)) if ( (!get_attr_from_disk(dev, inode, &attrib))
&& !(attrib & FILE_ATTR_A)) { && !(attrib & FILE_ATTR_A)) {
attrib|=FILE_ATTR_A; attrib|=FILE_ATTR_A;
put_attr_to_disk(dev, inode, attrib); put_attr_to_disk(dev, inode, attrib);
} }
}
} }
void free_nw_ext_inode(int volume, char *unixname, int dev, ino_t inode)
/* trustees */
static void put_trustee_to_disk(int dev, ino_t inode, uint32 id, int trustee)
{
char buf[255];
char btrustee[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unx_xmkdir(buf, 0755);
sprintf(buf+l, "/%x", (unsigned int) id);
unlink(buf);
l=sprintf(btrustee, "%04x", (unsigned int) trustee);
symlink(btrustee, buf);
reseteuid();
}
static void free_trustees_from_disk(int dev, ino_t inode)
{
char buf[255];
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
unx_xrmdir(buf);
reseteuid();
}
static int get_trustee_from_disk(int dev, ino_t inode, uint32 id)
{
char buf[255];
char btrustee[255];
int l;
uint8 buf_uc[4];
U32_TO_BE32(inode, buf_uc);
sprintf(buf, "%s/%x/%x/%x/%x/%x.t/%x", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3],
(unsigned int) id);
seteuid(0);
l=readlink(buf, btrustee, 254);
reseteuid();
if (l > 0) {
unsigned int utrustee=0;
btrustee[l]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
return((int)utrustee);
}
}
return(-1);
}
static int scan_trustees_from_disk(int dev, ino_t inode, int *offset,
int max_trustees, uint32 *trustee_ids, int *trustees)
/* returns count of trustees if all ok */
{
char buf[255];
int l;
int count=0;
uint8 buf_uc[4];
DIR *d;
U32_TO_BE32(inode, buf_uc);
l=sprintf(buf, "%s/%x/%x/%x/%x/%x.t", path_attributes,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
seteuid(0);
d = opendir(buf);
if (NULL != d) {
uint8 *p=buf+l;
struct dirent *dirbuff;
*p++ = '/';
l=0;
if ((unsigned int)(*offset) >= MAX_U16)
*offset=0;
while (count < max_trustees &&
(dirbuff = readdir(d)) != (struct dirent*)NULL){
if (l++ > *offset) {
if (dirbuff->d_ino) {
char btrustee[255];
int len;
unsigned int id;
if (1 == sscanf(dirbuff->d_name, "%x", &id) && id > 0) {
strcpy(p, dirbuff->d_name);
len=readlink(buf, btrustee, 254);
if (len > 0) {
unsigned int utrustee=0;
btrustee[len]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
*trustee_ids++ = (uint32) id;
*trustees++ = (int) utrustee;
count++;
}
}
}
}
}
}
*offset=l;
closedir(d);
}
reseteuid();
return(count);
}
int get_own_trustee(int dev, ino_t inode, int look_for_trustee)
{
if (act_obj_id == 1){ /* supervisor */
if ( (look_for_trustee == TRUSTEE_S) || (look_for_trustee == TRUSTEE_M)
|| (look_for_trustee == (TRUSTEE_S | TRUSTEE_M)) )
return(look_for_trustee | TRUSTEE_S);
}
return(0);
}
int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee)
{
return(0);
#if 0
if (get_own_trustee(dev, inode, TRUSTEE_M) & (TRUSTEE_M | TRUSTEE_S)){
} else return(-0x8c); /* no modify privileges */
#endif
}
void free_nw_ext_inode(int dev, ino_t inode)
/* removes all attrib or trustees entries for files or dirs */ /* removes all attrib or trustees entries for files or dirs */
/* must be called after deleting nw file or dir */ /* must be called after deleting nw file or dir */
{ {
int voloptions=get_volume_options(volume);
if (voloptions & VOL_OPTION_ATTRIBUTES)
free_attr_from_disk(dev, inode); free_attr_from_disk(dev, inode);
free_trustees_from_disk(dev, inode); if (voloptions & VOL_OPTION_TRUSTEES) {
int i=used_nw_volumes;
while(i--)
tru_free_file_trustees_from_disk(i, dev, inode);
}
} }

View File

@ -1,16 +1,27 @@
/* nwattrib.h 01-Feb-98 */ /* nwattrib.h 30-Apr-98 */
#ifndef _NWATTRIB_H_ #ifndef _NWATTRIB_H_
#define _NWATTRIB_H_ #define _NWATTRIB_H_
extern uint32 get_nw_attrib_dword(struct stat *stb, int voloptions); /* <-------------- File Attributes -------------> */
extern int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib); #define FILE_ATTR_NORMAL 0x00000000
extern int set_nw_attrib_byte (struct stat *stb, int voloptions, int battrib); #define FILE_ATTR_R 0x00000001
extern void set_nw_archive_bit(int dev, ino_t inode); #define FILE_ATTR_H 0x00000002
#define FILE_ATTR_S 0x00000004
#define FILE_ATTR_DIR 0x00000010
#define FILE_ATTR_A 0x00000020
#define FILE_ATTR_SHARE 0x00000080
extern int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee); #define FILE_ATTR_RENAME_INH 0x00020000
#define FILE_ATTR_DELETE_INH 0x00040000
extern uint32 get_nw_attrib_dword(int volume, char *unixname, struct stat *stb);
extern int set_nw_attrib_dword(int volume, char *unixname, struct stat *stb, uint32 attrib);
extern int set_nw_attrib_byte (int volume, char *unixname, struct stat *stb, int battrib);
extern int set_nw_attrib_word(int volume, char *unixname, struct stat *stb, int wattrib);
extern void set_nw_archive_bit(int volume, char *unixname, int dev, ino_t inode);
extern void free_nw_ext_inode(int dev, ino_t inode); extern void free_nw_ext_inode(int volume, char *unixname, int dev, ino_t inode);
#endif #endif

575
nwbind.c
View File

@ -1,9 +1,9 @@
/* nwbind.c */ /* nwbind.c */
#define REVISION_DATE "04-Feb-98" #define REVISION_DATE "25-Apr-00"
/* NCP Bindery SUB-SERVER */ /* NCP Bindery SUB-SERVER */
/* authentification and some message handling */ /* authentification and some message and queue handling */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,6 +19,15 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* history since 21-Apr-00
*
* mst:25-Apr-00: added login control routines from Paolo Prandini
* mst:25-Apr-00: added simple example for getting nwconn data
*
*/
#include "net.h" #include "net.h"
#include "nwdbm.h" #include "nwdbm.h"
#include "unxlog.h" #include "unxlog.h"
@ -82,9 +91,236 @@ static int max_nw_vols=MAX_NW_VOLS;
static int max_connections=MAX_CONNECTIONS; static int max_connections=MAX_CONNECTIONS;
static CONNECTION *connections=NULL; static CONNECTION *connections=NULL;
static CONNECTION *act_c=(CONNECTION*)NULL; static CONNECTION *act_c=(CONNECTION*)NULL;
static int act_connection;
static int internal_act=0; static int internal_act=0;
// Check if the new cleartext password is acceptable or not
static int nw_valid_newpasswd(uint32 obj_id, char *newpasswd)
{
LOGIN_CONTROL lc;
int result;
XDPRINTF((99, 0, "Change password for user %x with '%s'", obj_id, newpasswd));
result = nw_get_login_control(obj_id, &lc);
if (result < 0) return(0); /* No restrictions available */
XDPRINTF((2, 0, "len(pwd)=%d limit=%d", strlen(newpasswd), lc.minimumPasswordLength));
if (strlen(newpasswd)<lc.minimumPasswordLength)
return (-0xd8); // PASSWORD TOO SHORT
return 0;
}
static int nw_test_time_access(uint32 obj_id)
/*
* Code from Matt Paley, Mark Robson, Paolo Prandini
*/
{
time_t t,expiry;
struct tm exptm;
struct tm *tm;
int half_hours;
LOGIN_CONTROL lc;
int result;
result=nw_get_login_control(obj_id,&lc);
if (result < 0) return(0); /* No time limits available */
/* Check if account disabled - MR */
if (lc.accountExpired) /* Disabled */
{
XDPRINTF((1, 0, "No access for user %x - disabled.",obj_id));
return (-0xdc);
}
/* Account expires at 23:59:59 on the expiry day :) */
if (lc.accountExpiresYear) {
exptm.tm_year = lc.accountExpiresYear;
exptm.tm_mon = lc.accountExpiresMonth-1;
exptm.tm_mday = lc.accountExpiresDay;
exptm.tm_hour = 23;
exptm.tm_min = 59;
exptm.tm_sec = 59;
expiry = mktime(&exptm);
} else expiry = 0;
time(&t);
tm = localtime(&t);
if (expiry>0) /* if expiry is enabled */
{
XDPRINTF((1,0,"user has expiry of %d but time is %d",expiry,t));
if (t>expiry) /* has it expired ? */
{
XDPRINTF((1, 0, "No access for user %x - expired.",obj_id));
return (-0xdc);
}
}
half_hours = tm->tm_wday*48 + tm->tm_hour*2 + ((tm->tm_min>=30)? 1 : 0);
XDPRINTF((5,0,"half_hours=%d",half_hours));
{
char s[200];
int i;
for (i=0;i<42;i++) sprintf(s+i*3,"%02x ",lc.timeBitMap[i]);
XDPRINTF((5,0,"TIMEBITMAP=%s",s));
}
if ((lc.timeBitMap[half_hours/8] & (1<<(half_hours % 8))) == 0) {
XDPRINTF((1, 0, "No access for user %x at day %d %02d:%02d",
obj_id, tm->tm_wday, tm->tm_hour, tm->tm_min));
return(-0xda); /* unauthorized login time */
}
/* Password expires at 23:59:59 on the expiry day :) */
if (lc.passwordExpiresYear) {
exptm.tm_year = lc.passwordExpiresYear;
exptm.tm_mon = lc.passwordExpiresMonth-1;
exptm.tm_mday = lc.passwordExpiresDay;
exptm.tm_hour = 23;
exptm.tm_min = 59;
exptm.tm_sec = 59;
expiry = mktime(&exptm);
} else expiry = 0;
if (expiry>0) /* if expiry is enabled */
{
XDPRINTF((2, 0,"user has password expiry of %d and time is %d",expiry,t));
if (t>expiry) /* has it expired ? */ {
if (lc.passwordGraceLogins==0) {
XDPRINTF((1, 0, "No access for user %x - password expired,no grace.",obj_id));
return (-0xde);
}
if (lc.passwordGraceLogins!=255) {
// Decrement grace logins
lc.passwordGraceLogins--;
nw_set_login_control(obj_id, &lc);
XDPRINTF((1, 0, "Access for user %x - password expired, grace=%d.",obj_id,
lc.passwordGraceLogins));
return (-0xdf);
}
}
}
return 0;
}
static int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr)
{
uint8 more_segments;
uint8 property_flags;
char *propname="NODE_CONTROL";
uint8 buff[200];
uint8 wildnode[]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int segment = 1 ;
int i,j;
LOGIN_CONTROL lc;
/*
** Start by checking the authorized login stations
*/
int result=nw_get_prop_val_by_obj_id(obj_id, segment,
propname, strlen(propname),
buff, &more_segments, &property_flags);
if (result >=0 ) {
uint8 *p=buff;
int k=0;
result=-0xdb; /* unauthorized login station */
while (k++ < 12) {
if ( (IPXCMPNET(client_adr->net, p))
&& ( (IPXCMPNODE(client_adr->node, p+4) )
|| (IPXCMPNODE(wildnode, p+4))) ) {
result=0;
break;
}
p+=10;
}
} else {
// if bindery object not found, no station restrictions
result=0;
}
if (result<0) {
XDPRINTF((1, 0, "No access for user %x at Station %s",
obj_id, visable_ipx_adr(client_adr)));
return result;
}
// Read LOGIN_CONTROL object
result=nw_get_login_control(obj_id,&lc);
if (result<0) return 0;
/*
** Now check the number of concurrent connections
*/
for (i=j=0;i<max_connections;i++)
if (connections[i].active) {
// If the object logged in is the same requesting access now,
// increment the connection counter
if (connections[i].object_id==obj_id)
j++;
}
XDPRINTF((3, 0, "Found connections for user %x = %d", obj_id, j));
// If the number of active connections is >0 then check permissions
if ( (j>0) && GET_BE16(lc.maxConcurrentConnections) ) {
if (j >= GET_BE16(lc.maxConcurrentConnections)) {
XDPRINTF((1, 0, "No access for user %x - max connections=%d",obj_id,
(int)GET_BE16(lc.maxConcurrentConnections)));
return (-0xd9);
}
}
return 0;
}
int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr)
{
int result;
struct tm *tm;
time_t t;
LOGIN_CONTROL lc;
time(&t);
tm = localtime(&t);
if (obj_id==1 && (entry8_flags & 8)) {
if (nw_get_login_control(obj_id,&lc)==0) {
lc.lastLoginDate[0]=tm->tm_year;
lc.lastLoginDate[1]=tm->tm_mon+1;
lc.lastLoginDate[2]=tm->tm_mday;
lc.lastLoginDate[3]=tm->tm_hour;
lc.lastLoginDate[4]=tm->tm_min;
lc.lastLoginDate[5]=tm->tm_sec;
nw_set_login_control(obj_id,&lc);
}
return(0); /* no limits for SU */
}
result=nw_test_adr_access(obj_id, client_adr);
if (!result) result=nw_test_time_access(obj_id);
if ((result==0)||(result==-0xdf)) {
if (nw_get_login_control(obj_id,&lc)==0) {
lc.lastLoginDate[0]=tm->tm_year;
lc.lastLoginDate[1]=tm->tm_mon+1;
lc.lastLoginDate[2]=tm->tm_mday;
lc.lastLoginDate[3]=tm->tm_hour;
lc.lastLoginDate[4]=tm->tm_min;
lc.lastLoginDate[5]=tm->tm_sec;
nw_set_login_control(obj_id,&lc);
}
}
XDPRINTF((result?1:5, 0, "Access for user %x = %x.",obj_id,-result));
return(result);
}
int b_acc(uint32 obj_id, int security, int forwrite) int b_acc(uint32 obj_id, int security, int forwrite)
{ {
/* security levels /* security levels
@ -107,8 +343,8 @@ int b_acc(uint32 obj_id, int security, int forwrite)
if (act_c->object_id > 0) return(0); /* rights for all logged */ if (act_c->object_id > 0) return(0); /* rights for all logged */
} else if (security == 2) { } else if (security == 2) {
if ( act_c->object_id == obj_id if ( act_c->object_id == obj_id
|| act_c->object_id == 1 ) return(0); /* rights for the user */ || (act_c->id_flags&1) ) return(0); /* rights for the user */
} else if (security == 3 && act_c->object_id == 1) return(0); } else if (security == 3 && (act_c->id_flags&1)) return(0);
switch (forwrite&0xf) { switch (forwrite&0xf) {
case 0 : acc_what = "read"; break; case 0 : acc_what = "read"; break;
@ -145,6 +381,8 @@ int b_acc(uint32 obj_id, int security, int forwrite)
return(errcode); return(errcode);
} }
static void sent_down_message(void) static void sent_down_message(void)
{ {
int k = -1; int k = -1;
@ -152,12 +390,24 @@ static void sent_down_message(void)
while (++k < max_connections) { while (++k < max_connections) {
CONNECTION *cn=&connections[k]; CONNECTION *cn=&connections[k];
if (cn->active) { if (cn->active) {
#if 0
strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58); strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58);
#else
strmaxcpy(cn->message, "MARS_NWE IS DIEING", 58);
#endif
nwserv_handle_msg(k+1); nwserv_handle_msg(k+1);
} }
} /* while */ } /* while */
} }
static void delete_nwconn_request(CONNECTION *c)
{
if (c && c->request_nwconn) {
xfree(c->request_nwconn->data);
xfree(c->request_nwconn);
}
}
static void open_clear_connection(int conn, int activate, uint8 *addr) static void open_clear_connection(int conn, int activate, uint8 *addr)
{ {
if (conn > 0 && --conn < max_connections) { if (conn > 0 && --conn < max_connections) {
@ -178,6 +428,11 @@ static void open_clear_connection(int conn, int activate, uint8 *addr)
} }
} }
c->object_id = 0; c->object_id = 0;
c->id_flags = 0;
delete_nwconn_request(c);
c->last_used_sequence=0;
} }
} }
@ -198,19 +453,31 @@ static void get_login_time(uint8 login_time[], CONNECTION *cx)
static int build_login_response(uint8 *responsedata, uint32 obj_id) static int build_login_response(uint8 *responsedata, uint32 obj_id)
{ {
uint8 pw_name[40]; uint8 pw_name[40];
uint8 *p;
int result; int result;
int i;
act_c->object_id = obj_id; /* actuell Object ID */ act_c->object_id = obj_id; /* actuell Object ID */
act_c->t_login = akttime; /* and login Time */ act_c->t_login = akttime; /* and login Time */
act_c->id_flags = 0;
internal_act=1; internal_act=1;
if (HAVE_SU_RIGHTS(obj_id)) {
act_c->id_flags|=1; /* supervisor equivalence */
}
get_guid((int*) responsedata, get_guid((int*) responsedata,
(int*) (responsedata+sizeof(int)), (int*) (responsedata+sizeof(int)),
obj_id, pw_name); obj_id, pw_name);
*((uint32*) (responsedata+2*sizeof(int))) = obj_id; *((int*)(responsedata+2*sizeof(int))) = act_c->id_flags;
*((uint32*) (responsedata+3*sizeof(int))) = obj_id;
result = get_home_dir(responsedata + 3 * sizeof(int)+1, obj_id); result=4*sizeof(int);
*(responsedata + 3 * sizeof(int)) = (uint8) result; p = responsedata + result;
result = 3 * sizeof(int) + 1 + (int) *(responsedata+ 3 * sizeof(int)); i = (uint8)get_groups_i_m_in(obj_id, (uint32*) (p+sizeof(int)) );
*(int*)(p) = i;
result+= (sizeof(int)+i*sizeof(uint32));
p=responsedata + result;
i=strlen(pw_name);
*p = (uint8) i;
memcpy(p+1, pw_name, i);
result += ( i + 1 );
write_utmp(1, act_connection, act_c->pid_nwconn, write_utmp(1, act_connection, act_c->pid_nwconn,
&(act_c->client_adr), pw_name); &(act_c->client_adr), pw_name);
internal_act=0; internal_act=0;
@ -233,7 +500,7 @@ static void handle_fxx(int gelen, int func)
uint8 connect_status= 0; uint8 connect_status= 0;
int data_len = 0; int data_len = 0;
if (func==0x19) { if (func==0x18||func==19) {
ufunc = 0; ufunc = 0;
rdata = requestdata; rdata = requestdata;
} else if (func==0x20) { } else if (func==0x20) {
@ -330,7 +597,7 @@ static void handle_fxx(int gelen, int func)
} }
internal_act=0; internal_act=0;
/* OK if supervisor or trying to read (0x29) own limits */ /* OK if supervisor or trying to read (0x29) own limits */
if (act_c->object_id == 1 || if ( (act_c->id_flags&1) ||
(act_c->object_id == id && ufunc == 0x29)) (act_c->object_id == id && ufunc == 0x29))
((int *) responsedata)[2] = 0; /* OK */ ((int *) responsedata)[2] = 0; /* OK */
else else
@ -518,8 +785,12 @@ static void handle_fxx(int gelen, int func)
memset(password, 0, 50); memset(password, 0, 50);
if (!result) if (!result)
data_len = build_login_response(responsedata, obj.id); data_len = build_login_response(responsedata, obj.id);
else else {
completition = (uint8) -result; completition = (uint8) -result;
if (result==-0xdf) { /* PaPr,mst:25-Apr-00 */
data_len = build_login_response(responsedata, obj.id);
}
}
} break; } break;
case 0x15 : { /* Get Object Connection List (old) */ case 0x15 : { /* Get Object Connection List (old) */
@ -620,13 +891,17 @@ static void handle_fxx(int gelen, int func)
} }
if (result > -1) if (result > -1)
data_len = build_login_response(responsedata, obj.id); data_len = build_login_response(responsedata, obj.id);
else else {
completition = (uint8) -result; completition = (uint8) -result;
if (result==-0xdf) { /*PaPr,mst:25-Apr-00 */
data_len = build_login_response(responsedata, obj.id);
}
}
/* /*
* completition = 0xde means login time has expired * completition = 0xde means login time has expired
* completition = 0xdf means good login, but * completition = 0xdf means good login, but
* login time has expired * login time has expired, using grace logins
* perhaps I will integrate it later.
*/ */
} }
break; break;
@ -686,7 +961,7 @@ static void handle_fxx(int gelen, int func)
case 0x34 : { /* rename OBJECT, only SU */ case 0x34 : { /* rename OBJECT, only SU */
int result=-0xff; int result=-0xff;
if (1 == act_c->object_id) { if (act_c->id_flags&1) {
uint8 *p = rdata; uint8 *p = rdata;
NETOBJ obj; NETOBJ obj;
uint8 newname[256]; uint8 newname[256];
@ -774,7 +1049,7 @@ static void handle_fxx(int gelen, int func)
case 0x38 : { /* change Bindery Objekt Security */ case 0x38 : { /* change Bindery Objekt Security */
/* only SU ! */ /* only SU ! */
int result= -0xff; int result= -0xff;
if (1 == act_c->object_id) { if (act_c->id_flags&1) {
uint8 *p = rdata; uint8 *p = rdata;
NETOBJ obj; NETOBJ obj;
obj.type = GET_BE16(p+1); obj.type = GET_BE16(p+1);
@ -926,19 +1201,20 @@ static void handle_fxx(int gelen, int func)
if (0 == (result = find_obj_id(&obj))) { if (0 == (result = find_obj_id(&obj))) {
XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword, XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword,
newpassword)); newpassword));
internal_act=1;
internal_act = 1; if ((act_c->id_flags&1) ||
if (act_c->object_id == 1 ||
(0 == (result=test_allow_password_change(act_c->object_id)) (0 == (result=test_allow_password_change(act_c->object_id))
&& /* PaPr,mst:25-Apr-00 */
0 == (result=nw_valid_newpasswd(act_c->object_id,newpassword))
&& &&
0 == (result=nw_test_unenpasswd(obj.id, oldpassword)))){ 0 == (result=nw_test_unenpasswd(obj.id, oldpassword)))){
if ( (act_c->object_id != 1) if ( (!(act_c->id_flags&1))
|| *newpassword || *newpassword
|| !(password_scheme & PW_SCHEME_LOGIN)) || !(password_scheme & PW_SCHEME_LOGIN))
result=nw_set_passwd(obj.id, newpassword, 0); result=nw_set_passwd(obj.id, newpassword, 0);
else result = -0xff; else result = -0xff;
} }
internal_act = 0; internal_act=0;
} }
if (result < 0) completition = (uint8) -result; if (result < 0) completition = (uint8) -result;
memset(oldpassword, 0, 50); memset(oldpassword, 0, 50);
@ -1003,7 +1279,6 @@ static void handle_fxx(int gelen, int func)
if (result) completition = (uint8) -result; if (result) completition = (uint8) -result;
} break; } break;
case 0x44 : { /* CLOSE BINDERY */ case 0x44 : { /* CLOSE BINDERY */
; ;
} break; } break;
@ -1025,7 +1300,7 @@ static void handle_fxx(int gelen, int func)
*xdata = (uint8) 0; *xdata = (uint8) 0;
memset(xdata+1, 0xff, 4); memset(xdata+1, 0xff, 4);
} else { } else {
*xdata = (act_c->object_id == 1) ? (uint8) 0x33 *xdata = (act_c->id_flags&1) ? (uint8) 0x33
: (uint8) 0x22; : (uint8) 0x22;
U32_TO_BE32(act_c->object_id, (xdata+1)); U32_TO_BE32(act_c->object_id, (xdata+1));
} }
@ -1035,19 +1310,10 @@ static void handle_fxx(int gelen, int func)
} }
break; break;
case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */ #if 0
/* TODO !!! */ case 0x47 : /* SCAN BINDERY OBJECT TRUSTEE PATH */
struct XDATA { handled in nwconn
uint8 nextsequence[2]; #endif
uint8 id[4];
uint8 access_mask;
uint8 pathlen;
uint8 path[1];
} *xdata = (struct XDATA*) responsedata;
memset(xdata, 0, 8);
data_len = 8;
}
break;
case 0x48 : { /* GET BINDERY ACCES LEVEL from OBJECT ??? */ case 0x48 : { /* GET BINDERY ACCES LEVEL from OBJECT ??? */
struct XDATA { struct XDATA {
@ -1059,7 +1325,7 @@ static void handle_fxx(int gelen, int func)
result = nw_get_obj(&obj); result = nw_get_obj(&obj);
if (!result) { if (!result) {
/* don't know whether this is ok ?? */ /* don't know whether this is ok ?? */
if (act_c->object_id == 1) { if (act_c->id_flags&1) {
xdata->acces_level = 0x33; xdata->acces_level = 0x33;
} else if (act_c->object_id == obj.id) { } else if (act_c->object_id == obj.id) {
xdata->acces_level = 0x22; xdata->acces_level = 0x22;
@ -1072,7 +1338,7 @@ static void handle_fxx(int gelen, int func)
break; break;
case 0x49 : { /* IS CALLING STATION A MANAGER */ case 0x49 : { /* IS CALLING STATION A MANAGER */
completition = (act_c->object_id == 1) ? 0 : 0xff; completition = (act_c->id_flags&1) ? 0 : 0xff;
/* here only SU = Manager */ /* here only SU = Manager */
/* not manager, then completition = 0xff */ /* not manager, then completition = 0xff */
} }
@ -1091,8 +1357,8 @@ static void handle_fxx(int gelen, int func)
internal_act = 0; internal_act = 0;
} }
if (result < 0) completition = (uint8) -result; if (result < 0) completition = (uint8) -result;
XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', result=%d", XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', type=0x%x, result=%d",
obj.name, result)); obj.name, obj.type, result));
} }
break; break;
@ -1113,14 +1379,14 @@ static void handle_fxx(int gelen, int func)
result=test_allow_password_change(obj.id); result=test_allow_password_change(obj.id);
if (!result) if (!result)
result=nw_keychange_passwd(obj.id, act_c->crypt_key, result=nw_keychange_passwd(obj.id, act_c->crypt_key,
rdata, (int)*p, p+1, act_c->object_id); rdata, (int)*p, p+1, act_c->id_flags);
if (!result) test_ins_unx_user(obj.id); if (!result) test_ins_unx_user(obj.id);
internal_act = 0; internal_act = 0;
} }
if (result< 0) completition = (uint8) -result; if (result< 0) completition = (uint8) -result;
XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', type=0x%x, result=0x%x",
obj.name, result)); obj.name, obj.type, result));
} }
break; break;
@ -1153,7 +1419,7 @@ static void handle_fxx(int gelen, int func)
case 0x65 : { /* Destroy Queue */ case 0x65 : { /* Destroy Queue */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
int result=-0xd3; /* no rights */ int result=-0xd3; /* no rights */
if (1 == act_c->object_id) if (act_c->id_flags&1)
result=nw_destroy_queue(q_id); result=nw_destroy_queue(q_id);
if (result < 0) if (result < 0)
completition=(uint8)(-result); completition=(uint8)(-result);
@ -1198,6 +1464,20 @@ static void handle_fxx(int gelen, int func)
} }
break; break;
case 0x67 : /* Set Queue Current Status,old */
case 0x7e : { /* Set Queue Current Status */
uint32 q_id = GET_BE32(rdata);
int status = *(rdata+4);
int result =
(act_c->id_flags&1) /* TODO BETTER */
? nw_set_queue_status(q_id, status)
: -0xd3; /* no rights */
if (result< 0)
completition=(uint8)-result;
/* NO REPLY */
}
break;
case 0x6A : /* Remove Job from Queue OLD */ case 0x6A : /* Remove Job from Queue OLD */
case 0x80 : { /* Remove Job from Queue NEW */ case 0x80 : { /* Remove Job from Queue NEW */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
@ -1241,13 +1521,15 @@ static void handle_fxx(int gelen, int func)
} }
break; break;
case 0x6C : { /* Get Queue Job Entry old */
case 0x6C: /* Get Queue Job Entry old */
case 0x7A: { /* Read Queue Job Entry */
uint32 q_id = GET_BE32(rdata); uint32 q_id = GET_BE32(rdata);
int job_id = GET_BE16(rdata+4); int job_id = GET_BE16(rdata+4);
/* added by nwconn */ /* added by nwconn */
uint32 fhandle = GET_BE32(rdata+8); uint32 fhandle = GET_BE32(rdata+8);
int result=nw_get_q_job_entry(q_id, job_id, fhandle, int result=nw_get_q_job_entry(q_id, job_id, fhandle,
responsedata, 1); responsedata, ufunc==0x6c);
if (result > -1) if (result > -1)
data_len=result; data_len=result;
else completition=(uint8)-result; else completition=(uint8)-result;
@ -1337,7 +1619,18 @@ static void handle_fxx(int gelen, int func)
} }
break; break;
#if 1
case 0x7B: /* Change Queue Job Entry */
{
uint32 q_id = GET_BE32(rdata);
/* uint32 job_id = GET_BE16(rdata+4); */
int result = nw_change_queue_job_entry(q_id, rdata+4);
if (result < 0)
completition=(uint8)-result;
}
break;
#endif
case 0x7d : { /* Read Queue Current Status, new */ case 0x7d : { /* Read Queue Current Status, new */
struct XDATA { struct XDATA {
uint8 id[4]; /* queue id */ uint8 id[4]; /* queue id */
@ -1378,16 +1671,20 @@ static void handle_fxx(int gelen, int func)
} break; } break;
case 0x81 : { /* Get Queue Job List */ case 0x81 : { /* Get Queue Job List */
NETOBJ obj; uint32 q_id = GET_BE32(rdata);
uint32 offset = GET_BE32(rdata+4);
#if 0
struct XDATA { struct XDATA {
uint8 total_jobs[4]; uint8 total_jobs[4];
uint8 reply_numbers[4]; uint8 reply_numbers[4]; /* max. 125 replies */
uint8 job_list[4]; /* this is repeated */ uint8 job_list[4]; /* this is repeated */
} *xdata = (struct XDATA*) responsedata; } *xdata = (struct XDATA*) responsedata;
obj.id = GET_BE32(rdata); #endif
XDPRINTF((2, 0, "TODO:GET QUEUE JOB List of Q=0x%lx", obj.id)); int result=nw_get_queue_job_list(q_id, offset, responsedata);
memset(xdata, 0, sizeof(struct XDATA)); if (result > -1)
data_len=sizeof(struct XDATA); data_len=result;
else
completition=(uint8)-result;
}break; }break;
case 0x72: /* finish servicing queue job (old)*/ case 0x72: /* finish servicing queue job (old)*/
@ -1421,12 +1718,12 @@ static void handle_fxx(int gelen, int func)
} }
}break; }break;
case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */
XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); /* to use fileserver service functions */
XDPRINTF((1, 0, "MAKE BETTER: CHECK CONSOLE PRIV"));
/* !!!!!! TODO completition=0xc6 (no rights) */ /* !!!!!! TODO completition=0xc6 (no rights) */
if (act_c->object_id != 1) completition=0xc6; /* no rights */ if (!(act_c->id_flags&1))
completition=0xc6; /* no rights */
} break; } break;
case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */ case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */
@ -1438,15 +1735,8 @@ static void handle_fxx(int gelen, int func)
int l; int l;
memset(responsedata, 0, 512); memset(responsedata, 0, 512);
strcpy(responsedata, company); strcpy(responsedata, company);
l = 1 + sprintf(responsedata+k, revision, l = 1 + sprintf(responsedata+k, revision,
_VERS_H_, _VERS_L_, _VERS_P_ ); _VERS_H_, _VERS_L_, _VERS_P_ );
#if 0
k+=l;
#else
/* BUG in LIB */
k += (1 + strlen(responsedata+k));
#endif
strcpy(responsedata+k, revision_date); strcpy(responsedata+k, revision_date);
k += (strlen(revision_date)+1); k += (strlen(revision_date)+1);
strcpy(responsedata+k, copyright); strcpy(responsedata+k, copyright);
@ -1493,10 +1783,17 @@ static void handle_fxx(int gelen, int func)
break; break;
case 0xd3 : { /* down File Server */ case 0xd3 : { /* down File Server */
if (act_c->object_id == 1) { /* only SUPERVISOR */ internal_act=1;
if (HAVE_SU_RIGHTS(act_c->object_id)) { /* only SUPERVISOR */
/* inform nwserv */ /* inform nwserv */
nwserv_down_server(); nwserv_down_server();
} else completition = 0xff; } else {
/* 16-May-99
* correct completition code from Paolo Prandini
*/
completition = 0xc6; /* not authorized */
}
internal_act=0;
} }
break; break;
@ -1508,9 +1805,14 @@ static void handle_fxx(int gelen, int func)
default : completition = 0xfb; /* not known here */ default : completition = 0xfb; /* not known here */
break; break;
} /* switch */ } /* switch */
} else if (func == 0x18) { /* End of Job */
if (!(entry8_flags&0x200)) /* pcz: 14-Apr-00 */
nw_close_connection_jobs(act_connection, ncprequest->task); /* close print jobs */
} else if (func == 0x19) { /* logout */ } else if (func == 0x19) { /* logout */
nw_close_connection_jobs(act_connection, -1); /* close all print jobs */
write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL); write_utmp(0, act_connection, act_c->pid_nwconn, &(act_c->client_adr), NULL);
act_c->object_id = 0; /* not LOGIN */ act_c->object_id = 0; /* not LOGIN */
act_c->id_flags = 0; /* no flags */
} else if (0x20 == func) { /* Semaphore */ } else if (0x20 == func) { /* Semaphore */
int result = handle_func_0x20(act_c, rdata, ufunc, responsedata); int result = handle_func_0x20(act_c, rdata, ufunc, responsedata);
if (result > -1) data_len = result; if (result > -1) data_len = result;
@ -1532,10 +1834,83 @@ static void handle_fxx(int gelen, int func)
send_ipx_data(ipx_out_fd, 17, data_len, (char*)ncpresponse, send_ipx_data(ipx_out_fd, 17, data_len, (char*)ncpresponse,
&my_addr, NULL); &my_addr, NULL);
XDPRINTF((2, 0, "func=0x%x ufunc=0x%x compl:0x%x, written count = %d", XDPRINTF((6, 0, "func=0x%x ufunc=0x%x compl:0x%x, written count = %d",
(int)func, (int)ufunc, (int) completition, data_len)); (int)func, (int)ufunc, (int) completition, data_len));
} }
/* mst:25-Apr-00 */
static void send_request_to_nwconn(int connection, int function,
char *data, int data_len,
RESPONSE_FUNC func)
{
CONNECTION *c = &(connections[connection-1]);
if (c->active && c->send_to_sock > 0) {
IPX_DATA buf;
NCPREQUEST *req = (NCPREQUEST*)&buf;
U16_TO_BE16(0x2121, req->type);
delete_nwconn_request(c);
if (++c->last_used_sequence > 255)
c->last_used_sequence=1;
req->sequence = c->last_used_sequence;
req->task = 1;
req->connection = (connection & 0xff);
req->high_connection = ((connection >> 8) & 0xff);
req->function = function;
c->request_nwconn = (NWCONN_REQUEST*)xcmalloc(sizeof(NWCONN_REQUEST));
c->request_nwconn->sequence = req->sequence;
c->request_nwconn->function = function;
c->request_nwconn->sendtime = time(NULL);
c->request_nwconn->func = func;
if (data_len) {
memcpy(req+1, data, data_len);
c->request_nwconn->data = xmalloc(data_len);
memcpy(c->request_nwconn->data, data, data_len);
}
data_len+=sizeof(NCPREQUEST);
U16_TO_BE16(c->send_to_sock, my_addr.sock);
XDPRINTF((1, 0, "send_request_to_nwconn: connection=%d, data_len=%d",
connection, data_len));
send_ipx_data(ipx_out_fd, 17, data_len, (char*)req, &my_addr, NULL);
}
}
static void nwconn_callback(int connection,
char *data, int data_len,
int completition)
{
struct XDATA {
uint8 count_handles[4];
uint8 handles[4];
} *xdata = (struct XDATA*) data;
int open_files = GET_BE32(xdata->count_handles);
int handle0 = open_files < 1 ? 0 : GET_BE32(xdata->handles);
int handle1 = open_files < 2 ? 0 : GET_BE32(xdata->handles+4);
XDPRINTF((1, 0, "Got Response form con=%d, open_files=%d, handle0=%d, handle1=%d",
connection, open_files, handle0, handle1));
}
static void handle_usr2(void)
/* handles SIGUSR2, testfunction */
{
int k;
for (k=0; k < max_connections; k++) {
CONNECTION *c = &connections[k];
if (c->active) {
struct {
uint8 offset[4]; /* handle offset */
} data = { {0} };
send_request_to_nwconn(k+1, 0x1, (char*)&data, sizeof(data), nwconn_callback);
}
}
}
static void handle_bind_calls(uint8 *p) static void handle_bind_calls(uint8 *p)
{ {
int func = (int) *p; int func = (int) *p;
@ -1673,6 +2048,7 @@ static void set_sig(void)
{ {
signal(SIGQUIT, sig_handler); signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler); signal(SIGHUP, sig_handler);
signal(SIGUSR2, sig_handler);
signal(SIGTERM, SIG_IGN); signal(SIGTERM, SIG_IGN);
signal(SIGINT, SIG_IGN); signal(SIGINT, SIG_IGN);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
@ -1681,18 +2057,16 @@ static void set_sig(void)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int sock_nwbind; int sock_nwbind;
int i;
if (argc != 4) { if (argc != 4) {
fprintf(stderr, "usage nwbind nwname address nwbindsock\n"); fprintf(stderr, "usage nwbind nwname address nwbindsock\n");
exit(1); exit(1);
} }
init_tools(NWBIND, 0); init_tools(NWBIND, 0);
strmaxcpy(my_nwname, argv[1], 47); strmaxcpy(my_nwname, argv[1], 47);
adr_to_ipx_addr(&my_addr, argv[2]); adr_to_ipx_addr(&my_addr, argv[2]);
sscanf(argv[3], "%x", &sock_nwbind); sscanf(argv[3], "%x", &sock_nwbind);
internal_act = 1; internal_act = 1;
if (nw_init_dbm(my_nwname, &my_addr) <0) { if (nw_init_dbm(my_nwname, &my_addr) <0) {
errorp(1, "nw_init_dbm", NULL); errorp(1, "nw_init_dbm", NULL);
@ -1708,7 +2082,6 @@ int main(int argc, char *argv[])
max_nw_vols=get_ini_int(61); /* max. volumes */ max_nw_vols=get_ini_int(61); /* max. volumes */
if (max_nw_vols < 1) if (max_nw_vols < 1)
max_nw_vols = MAX_NW_VOLS; max_nw_vols = MAX_NW_VOLS;
#ifdef LINUX #ifdef LINUX
set_emu_tli(); set_emu_tli();
#endif #endif
@ -1718,7 +2091,6 @@ int main(int argc, char *argv[])
#endif #endif
XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s", XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s",
(ipx_out_fd > -1) ? "enabled" : "disabled")); (ipx_out_fd > -1) ? "enabled" : "disabled"));
ud.opt.len = sizeof(ipx_pack_typ); ud.opt.len = sizeof(ipx_pack_typ);
ud.opt.maxlen = sizeof(ipx_pack_typ); ud.opt.maxlen = sizeof(ipx_pack_typ);
ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual Typ */ ud.opt.buf = (char*)&ipx_pack_typ; /* gets actual Typ */
@ -1737,6 +2109,8 @@ int main(int argc, char *argv[])
if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){ if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){
time(&akttime); time(&akttime);
XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr))); XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr)));
act_ncpsequence = (int)ncprequest->sequence;
if ( ncprequest->type[0] == 0x22 if ( ncprequest->type[0] == 0x22
&& ncprequest->type[1] == 0x22) { && ncprequest->type[1] == 0x22) {
act_connection = (int)ncprequest->connection act_connection = (int)ncprequest->connection
@ -1757,8 +2131,46 @@ int main(int argc, char *argv[])
visable_ipx_adr(&from_addr), act_connection)); visable_ipx_adr(&from_addr), act_connection));
} }
} else { } else {
XDPRINTF((1, 0, "NWBIND-LOOP connection=%d is wrong", XDPRINTF((1, 0, "NWBIND-LOOP connection=%d,adr=%s is wrong",
act_connection)); act_connection,
visable_ipx_adr(&from_addr)
));
}
} else if ( ncprequest->type[0] == 0x32
&& ncprequest->type[1] == 0x32 ) {
/* response from nwconn */
act_connection = (int)ncprequest->connection
| (((int)ncprequest->high_connection) << 8);
if (act_connection > 0 && act_connection <= max_connections) {
act_c = &(connections[act_connection-1]);
internal_act = 0;
if (act_c->active && act_c->request_nwconn
&& act_c->request_nwconn->sequence == ncprequest->sequence
&& IPXCMPNODE (from_addr.node, my_addr.node)
&& IPXCMPNET (from_addr.net, my_addr.net)
&& GET_BE16 (from_addr.sock) == SOCK_NCP ) {
XDPRINTF((1, 0, "GOT 0x3232k OK connection=%d", act_connection));
if (act_c->request_nwconn->func) {
(*act_c->request_nwconn->func)(
act_connection,
((char*)&ipx_in_data) + sizeof(NCPRESPONSE),
ud.udata.len - sizeof(NCPRESPONSE),
(int) ((NCPRESPONSE*)ipx_in_data)->completition);
}
/* now delete request */
delete_nwconn_request(act_c);
} else {
XDPRINTF((1, 0, "NWBIND-LOOP 0x3232 wrong connection %d, active=%d, seq=%d from %s",
act_connection, act_c->active,
(int) ncprequest->sequence, visable_ipx_adr(&from_addr) ));
}
} else {
XDPRINTF((1, 0, "NWBIND-LOOP 0x3232 wrong connection %d from %s",
act_connection, visable_ipx_adr(&from_addr) ));
} }
} else if ( ncprequest->type[0] == 0xee } else if ( ncprequest->type[0] == 0xee
&& ncprequest->type[1] == 0xee && ncprequest->type[1] == 0xee
@ -1776,13 +2188,16 @@ int main(int argc, char *argv[])
/* here I update some Bindery stuff from nwserv.conf */ /* here I update some Bindery stuff from nwserv.conf */
reinit_nwbind(); reinit_nwbind();
got_sig = 0; got_sig = 0;
} else if (got_sig == SIGUSR2) {
handle_usr2(); /* mst:25-Apr-00 */
got_sig = 0;
} }
} }
/* perhaps some connections need clearing (utmp), hint from Ambrose Li */ /* perhaps some connections need clearing (utmp), hint from Ambrose Li */
got_sig=max_connections+1; i=max_connections+1;
while (--got_sig) while (--i)
open_clear_connection(got_sig, 0, NULL); open_clear_connection(i, 0, NULL);
if (ncp_fd > -1) { if (ncp_fd > -1) {
t_unbind(ncp_fd); t_unbind(ncp_fd);

View File

@ -1,9 +1,9 @@
/* nwbind.h 07-Aug-97 */ /* nwbind.h 23-Apr-98 */
#ifndef _NWBIND_H_ #ifndef _NWBIND_H_
#define _NWBIND_H_ #define _NWBIND_H_
#define MAX_SEMA_CONN 10 /* 10 Semaphore pre connection */ #define MAX_SEMA_CONN 10 /* 10 Semaphore / connection */
typedef struct { typedef struct {
@ -11,16 +11,37 @@ typedef struct {
int opencount; /* times open */ int opencount; /* times open */
} SEMA_CONN; } SEMA_CONN;
typedef void (*RESPONSE_FUNC)(int connection,
char *data,
int data_len,
int completition);
typedef struct {
int sequence;
int function;
time_t sendtime;
char *data;
int data_len;
RESPONSE_FUNC func;
} NWCONN_REQUEST;
typedef struct { typedef struct {
ipxAddr_t client_adr; /* address remote client */ ipxAddr_t client_adr; /* address remote client */
uint32 object_id; /* logged object */ uint32 object_id; /* logged object */
/* 0 = not logged in */ /* 0 = not logged in */
int id_flags; /* &1 == supervisor (equivalence) */
/* flags are also availible in */
/* connection based routines */
uint8 crypt_key[8]; /* password generation */ uint8 crypt_key[8]; /* password generation */
time_t t_login; /* login time */ time_t t_login; /* login time */
uint8 message[60]; /* saved BCastmessage */ uint8 message[60]; /* saved BCastmessage */
int active; /* 0=closed, 1= active */ int active; /* 0=closed, 1= active */
int send_to_sock; /* this is the receiving sock */ int send_to_sock; /* this is the receiving sock */
int pid_nwconn; /* pid of user process nwconn */ int pid_nwconn; /* pid of user process nwconn */
NWCONN_REQUEST *request_nwconn; /* last request to nwconn */
int last_used_sequence;
int count_semas; /* open semahores */ int count_semas; /* open semahores */
SEMA_CONN semas[MAX_SEMA_CONN]; SEMA_CONN semas[MAX_SEMA_CONN];
} CONNECTION; } CONNECTION;

830
nwconn.c

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,6 @@
/* nwconn.h 19-Nov-97 */ /* nwconn.h 13-May-98 */
#ifndef _NWCONN_H_ #ifndef _NWCONN_H_
#define _NWCONN_H_ #define _NWCONN_H_
extern int act_connection;
extern int act_pid; extern int act_pid;
extern void nwconn_set_program_title(char *s); extern void nwconn_set_program_title(char *s);
#endif #endif

1051
nwdbm.c

File diff suppressed because it is too large Load Diff

77
nwdbm.h
View File

@ -1,5 +1,5 @@
/* nwdbm.h 01-Oct-97 */ /* nwdbm.h 25-Apr-00 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -78,12 +78,71 @@ extern uint8 *sys_sysname; /* Name of first Volume, normally SYS */
extern uint32 network_serial_nmbr; extern uint32 network_serial_nmbr;
extern uint16 network_appl_nmbr; extern uint16 network_appl_nmbr;
extern int entry8_flags;
#define PW_SCHEME_CHANGE_PW 1 #define PW_SCHEME_CHANGE_PW 1
#define PW_SCHEME_LOGIN 2 #define PW_SCHEME_LOGIN 2
#define PW_SCHEME_GET_KEY_FAIL 4 #define PW_SCHEME_GET_KEY_FAIL 4
#define PW_SCHEME_ALLOW_EMPTY_PW 8 #define PW_SCHEME_ALLOW_EMPTY_PW 8
/*
** LOGIN_CONTROL structure is an 86 byte structure that contains
** account password information
** Paolo Prandini <prandini@spe.it> mst:25-Apr-00
**
*/
typedef struct {
uint8 accountExpiresYear;
uint8 accountExpiresMonth;
uint8 accountExpiresDay;
uint8 accountExpired;
uint8 passwordExpiresYear;
uint8 passwordExpiresMonth;
uint8 passwordExpiresDay;
uint8 passwordGraceLogins;
uint8 expirationInterval[2]; /* hi-lo */
uint8 graceReset;
uint8 minimumPasswordLength;
uint8 maxConcurrentConnections[2]; /* hi-lo */
uint8 timeBitMap[42];
uint8 lastLoginDate[6];
uint8 restrictionFlags; // bit 0=1 disallow pwd change,
// bit 1=1 require unique pwd
uint8 filler;
uint8 maxDiskBlocks[4]; /* hi-lo */
uint8 badLoginCount[2]; /* hi-lo */
uint8 nextResetTime[4]; /* hi-lo */
uint8 badStationAddress[12];
} LOGIN_CONTROL;
/*
** USER_DEFAULTS structure is a structure that contains
** default account password information
*/
typedef struct {
uint8 accountExpiresYear;
uint8 accountExpiresMonth;
uint8 accountExpiresDay;
uint8 restrictionFlags;
uint8 expirationInterval[2]; /* hi-lo */
uint8 graceReset;
uint8 minimumPasswordLength;
uint8 maxConcurrentConnections[2]; /* hi-lo */
uint8 timeBitMap[42];
uint8 balance[4]; /* ?? */
uint8 creditLimit[4]; /* ?? */
uint8 maxDiskBlocks[4]; /* hi-lo */
uint8 createHomeDir;
} USER_DEFAULTS;
/* next routine is in nwbind.c !!!! */ /* next routine is in nwbind.c !!!! */
extern int b_acc(uint32 obj_id, int security, int forwrite); extern int b_acc(uint32 obj_id, int security, int forwrite);
@ -135,7 +194,6 @@ extern int nw_is_obj_in_set(int object_type,
int member_type, int member_type,
uint8 *member_name, int member_namlen); uint8 *member_name, int member_namlen);
extern int nw_add_obj_to_set(int object_type, extern int nw_add_obj_to_set(int object_type,
uint8 *object_name, int object_namlen, uint8 *object_name, int object_namlen,
uint8 *prop_name, int prop_namlen, uint8 *prop_name, int prop_namlen,
@ -183,14 +241,20 @@ extern int nw_create_prop(int object_type,
uint8 *prop_name, int prop_namlen, uint8 *prop_name, int prop_namlen,
int prop_flags, int prop_security); int prop_flags, int prop_security);
extern uint32 nw_new_obj_prop(uint32 wanted_id, extern uint32 nw_new_obj_prop(uint32 wanted_id,
char *objname, int objtype, int objflags, int objsecurity, char *objname, int objtype, int objflags, int objsecurity,
char *propname, int propflags, int propsecurity, char *propname, int propflags, int propsecurity,
char *value, int valuesize, int ever); char *value, int valuesize, int ever);
extern int nw_is_security_equal(uint32 id1, uint32 id2);
#define HAVE_SU_RIGHTS(id) ( ((id)==1L) || !nw_is_security_equal(1L, (id)))
extern int get_groups_i_m_in(uint32 id, uint32 *gids);
extern int get_guid(int *gid, int *uid, uint32 obj_id, uint8 *name); extern int get_guid(int *gid, int *uid, uint32 obj_id, uint8 *name);
extern int get_home_dir(uint8 *homedir, uint32 obj_id);
/* mst:25-Apr-00 */
extern int nw_get_login_control(uint32 obj_id, LOGIN_CONTROL *plc);
extern int nw_set_login_control(uint32 obj_id, LOGIN_CONTROL *plc);
extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key); extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key);
extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password); extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password);
@ -199,7 +263,7 @@ extern int nw_set_passwd(uint32 obj_id, char *password, int dont_ch);
extern int nw_keychange_passwd(uint32 obj_id, extern int nw_keychange_passwd(uint32 obj_id,
uint8 *cryptkey, uint8 *oldpass, uint8 *cryptkey, uint8 *oldpass,
int cryptedlen, uint8 *newpass, int cryptedlen, uint8 *newpass,
uint32 act_id); int id_flags);
extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr); extern int nw_test_adr_time_access(uint32 obj_id, ipxAddr_t *client_adr);
@ -215,6 +279,7 @@ extern void nw_exit_dbm(void);
extern int do_export_dbm(char *path); extern int do_export_dbm(char *path);
extern int do_import_dbm(char *path); extern int do_import_dbm(char *path);
extern int do_export_dbm_to_dir(void);
#endif #endif

919
nwfile.c

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* nwfile.h 09-Feb-98 */ /* nwfile.h 10-Nov-99 */
#ifndef _NWFILE_H_ #ifndef _NWFILE_H_
#define _NWFILE_H_ #define _NWFILE_H_
#include "extpipe.h" #include "extpipe.h"
@ -18,6 +18,9 @@ typedef struct {
int st_dev; /* device */ int st_dev; /* device */
int st_ino; /* inode */ int st_ino; /* inode */
char fname[256]; /* UNIX filename */ char fname[256]; /* UNIX filename */
int volume; /* Volume */
int inuse; /* used for multiple open of filehandle */
int access; /* open access */
} FILE_HANDLE; } FILE_HANDLE;
/* fh_flags */ /* fh_flags */
@ -38,7 +41,7 @@ extern int file_creat_open(int volume, uint8 *unixname,
extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit); extern int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit);
extern int nw_close_file(int fhandle, int reset_reuse); extern int nw_close_file(int fhandle, int reset_reuse, int task);
extern int nw_commit_file(int fhandle); extern int nw_commit_file(int fhandle);
extern uint8 *file_get_unix_name(int fhandle); extern uint8 *file_get_unix_name(int fhandle);
@ -50,12 +53,17 @@ extern int nw_server_copy(int qfhandle, uint32 qoffset,
int zfhandle, uint32 zoffset, int zfhandle, uint32 zoffset,
uint32 size); uint32 size);
extern int nw_lock_file(int fhandle, uint32 offset, uint32 size, int do_lock); extern int nw_log_physical_record(int fhandle, uint32 offset, uint32 size, int do_lock);
extern int fd_2_fname(int fhandle, char *buf, int bufsize); extern int fd_2_fname(int fhandle, char *buf, int bufsize);
extern FILE_HANDLE *fd_2_fh(int fhandle); extern FILE_HANDLE *fd_2_fh(int fhandle);
extern int get_nwfd(int fhandle); extern int get_nwfd(int fhandle);
extern void log_file_module(FILE *f);
extern int nw_get_count_open_files(uint8 *handlebuf, uint32 offset);
extern int nw_unlink(int volume, char *name); extern int nw_log_logical_record(int lock_flag,
int timeout,
int len,
uint8 *data);
#endif #endif

View File

@ -1,4 +1,4 @@
/* nwqconn.c 24-Sep-97 */ /* nwqconn.c 15-Sep-99 */
/* (C)opyright (C) 1997 Martin Stover, Marburg, Germany /* (C)opyright (C) 1997 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -24,16 +24,23 @@
#include "connect.h" #include "connect.h"
#include "nwqconn.h" #include "nwqconn.h"
/*
* the connection based queue stuff is in this module.
* The running process is nwconn.
* the bindery/global queue handling is in nwqueue.c.
*/
typedef struct S_INT_QUEUE_JOB { typedef struct S_INT_QUEUE_JOB {
uint32 queue_id; uint32 queue_id;
int job_id; int job_id;
int fhandle; int fhandle;
int task;
struct S_INT_QUEUE_JOB *next; struct S_INT_QUEUE_JOB *next;
} INT_QUEUE_JOB; } INT_QUEUE_JOB;
INT_QUEUE_JOB *queue_jobs=NULL; INT_QUEUE_JOB *queue_jobs=NULL;
static INT_QUEUE_JOB *new_queue_job(uint32 queue_id, int job_id) static INT_QUEUE_JOB *new_queue_job(uint32 queue_id, int job_id, int task)
{ {
INT_QUEUE_JOB *p=(INT_QUEUE_JOB*)xcmalloc(sizeof(INT_QUEUE_JOB)); INT_QUEUE_JOB *p=(INT_QUEUE_JOB*)xcmalloc(sizeof(INT_QUEUE_JOB));
if (!queue_jobs) { if (!queue_jobs) {
@ -46,6 +53,7 @@ static INT_QUEUE_JOB *new_queue_job(uint32 queue_id, int job_id)
p->next=NULL; p->next=NULL;
p->queue_id=queue_id; p->queue_id=queue_id;
p->job_id=job_id; p->job_id=job_id;
p->task=task;
return(p); return(p);
} }
@ -90,11 +98,13 @@ static int open_creat_queue_file(int mode, uint8
*/ */
{ {
int result; int result;
result=nw_alloc_dir_handle(0, dirname, dirname_len, 99, 2, 1); int eff_rights;
result=nw_alloc_dir_handle(0, dirname, dirname_len, 99, 2, 1, &eff_rights);
if (result > -1) { if (result > -1) {
char unixname[300]; char unixname[300];
int dirhandle=result;
result=conn_get_kpl_unxname(unixname, result, file_name, file_name_len); result=conn_get_kpl_unxname(unixname, sizeof(unixname),
dirhandle, file_name, file_name_len);
if (result > -1) { if (result > -1) {
struct stat stbuff; struct stat stbuff;
if (mode == 0) { /* creat */ if (mode == 0) { /* creat */
@ -104,12 +114,14 @@ static int open_creat_queue_file(int mode, uint8
chmod(unixname, 0600); chmod(unixname, 0600);
} else if (mode == 1) { /* open ro */ } else if (mode == 1) { /* open ro */
result=file_creat_open(result, (uint8*)unixname, result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x9, 4|8, 0); &stbuff, 0x6, 0x9, 8, 0);
/* ...............^^^...not &4 !... */
} else if (mode == 2) { /* open rw */ } else if (mode == 2) { /* open rw */
result=file_creat_open(result, (uint8*)unixname, result=file_creat_open(result, (uint8*)unixname,
&stbuff, 0x6, 0x6, 4|8, 0); &stbuff, 0x6, 0x6, 4|8, 0);
} else result=-1; } else result=-1;
} }
nw_free_dir_handle(dirhandle, 1);
} }
if (result < 0) { if (result < 0) {
uint8 dn[300]; uint8 dn[300];
@ -123,7 +135,8 @@ static int open_creat_queue_file(int mode, uint8
return(result); return(result);
} }
int creat_queue_job(uint32 q_id, int creat_queue_job(int task,
uint32 q_id,
uint8 *queue_job, uint8 *queue_job,
uint8 *responsedata, uint8 *responsedata,
uint8 old_call) uint8 old_call)
@ -138,7 +151,7 @@ int creat_queue_job(uint32 q_id,
if (old_call) { if (old_call) {
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */ QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
job_id = GET_BE16(job->job_id); job_id = GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id); jo = new_queue_job(q_id, job_id, task);
result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name), result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname); dirname+1, *dirname);
if (result > -1) { if (result > -1) {
@ -150,7 +163,7 @@ int creat_queue_job(uint32 q_id,
} else { } else {
QUEUE_JOB *job=(QUEUE_JOB*)responsedata; QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
job_id=GET_BE16(job->job_id); job_id=GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id); jo = new_queue_job(q_id, job_id, task);
result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name), result = open_creat_queue_file(0, job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname); dirname+1, *dirname);
if (result > -1) { if (result > -1) {
@ -172,10 +185,10 @@ int close_queue_job(uint32 q_id, int job_id)
int result = -0xff; int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id); INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
if (jo) { if (jo) {
nw_close_file(jo->fhandle, 0); nw_close_file(jo->fhandle, 0, jo->task);
result=0; result=0;
} }
XDPRINTF((5,0,"close_queue_job Q=0x%x, job=%d, result=%d", XDPRINTF(( (result<0) ? 1 :5 ,0,"close_queue_job Q=0x%x, job=%d, result=%d",
q_id, job_id, result)); q_id, job_id, result));
return(result); return(result);
} }
@ -186,7 +199,6 @@ int close_queue_job2(uint32 q_id, int job_id,
{ {
int result = -0xff; int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id); INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
XDPRINTF((5,0,"close_queue_job2, Q=0x%x, job=%d", q_id, job_id));
if (jo) { if (jo) {
if (prc_len) { if (prc_len) {
char unixname[300]; char unixname[300];
@ -205,7 +217,7 @@ int close_queue_job2(uint32 q_id, int job_id,
qpa.banner_user_name, qpa.banner_file_name); qpa.banner_user_name, qpa.banner_file_name);
} else } else
strmaxcpy((uint8*)printcommand, prc, prc_len); strmaxcpy((uint8*)printcommand, prc, prc_len);
nw_close_file(jo->fhandle, 1); nw_close_file(jo->fhandle, 1, jo->task);
jo->fhandle = 0L; jo->fhandle = 0L;
if (NULL == (f = fopen(unixname, "r"))) { if (NULL == (f = fopen(unixname, "r"))) {
/* OK now we try the open as root */ /* OK now we try the open as root */
@ -215,7 +227,7 @@ int close_queue_job2(uint32 q_id, int job_id,
} }
if (NULL != f) { if (NULL != f) {
int is_ok = 0; int is_ok = 0;
FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid()); FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid(), 1);
if (fp) { if (fp) {
int k; int k;
is_ok++; is_ok++;
@ -244,14 +256,16 @@ int close_queue_job2(uint32 q_id, int job_id,
} }
} else { } else {
result=0; result=0;
nw_close_file(jo->fhandle, 1); nw_close_file(jo->fhandle, 1, jo->task);
} }
free_queue_job(q_id, job_id); free_queue_job(q_id, job_id);
} }
XDPRINTF(((result<0)?1:5,0,"close_queue_job2, Q=0x%x, job=%d", q_id, job_id));
return(result); return(result);
} }
int service_queue_job(uint32 q_id, int service_queue_job(int task,
uint32 q_id,
uint8 *queue_job, uint8 *queue_job,
uint8 *responsedata, uint8 *responsedata,
uint8 old_call) uint8 old_call)
@ -266,7 +280,7 @@ int service_queue_job(uint32 q_id,
if (old_call) { if (old_call) {
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */ QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
job_id = GET_BE16(job->job_id); job_id = GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id); jo = new_queue_job(q_id, job_id,task);
result = open_creat_queue_file(1, result = open_creat_queue_file(1,
job->job_file_name+1, *(job->job_file_name), job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname); dirname+1, *dirname);
@ -279,7 +293,7 @@ int service_queue_job(uint32 q_id,
} else { } else {
QUEUE_JOB *job=(QUEUE_JOB*)responsedata; QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
job_id = GET_BE16(job->job_id); job_id = GET_BE16(job->job_id);
jo = new_queue_job(q_id, job_id); jo = new_queue_job(q_id, job_id,task);
result = open_creat_queue_file(1, result = open_creat_queue_file(1,
job->job_file_name+1, *(job->job_file_name), job->job_file_name+1, *(job->job_file_name),
dirname+1, *dirname); dirname+1, *dirname);
@ -300,7 +314,7 @@ int finish_abort_queue_job(uint32 q_id, int job_id)
int result = -0xff; int result = -0xff;
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id); INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
if (jo) { if (jo) {
nw_close_file(jo->fhandle, 0); nw_close_file(jo->fhandle, 0, jo->task);
free_queue_job(q_id, job_id); free_queue_job(q_id, job_id);
result=0; result=0;
} }
@ -328,3 +342,30 @@ void free_queue_jobs(void)
queue_jobs=NULL; queue_jobs=NULL;
} }
static int loc_free_connection_task_jobs(int task)
{
INT_QUEUE_JOB *qj=queue_jobs;
if (!qj) return(0);
if (qj->task==task){
queue_jobs=qj->next;
nw_close_file(qj->fhandle, 1, task);
xfree(qj);
return(1);
}
while (qj->next) {
if (qj->next->task == task) {
INT_QUEUE_JOB *tmp=qj->next;
qj->next=tmp->next;
nw_close_file(tmp->fhandle, 1, task);
xfree(tmp);
return(1);
} else qj=qj->next;
}
return(0); /* not found */
}
void free_connection_task_jobs(int task)
{
while(loc_free_connection_task_jobs(task)) ;;
}

View File

@ -1,8 +1,9 @@
/* nwqconn.h 26-Aug-97 */ /* nwqconn.h 14-Apr-98 */
#ifndef _NWQCONN_H_ #ifndef _NWQCONN_H_
#define _NWQCONN_H_ #define _NWQCONN_H_
#include "queuedef.h" #include "queuedef.h"
extern int creat_queue_job(uint32 q_id, extern int creat_queue_job(int task,
uint32 q_id,
uint8 *queue_job, uint8 *queue_job,
uint8 *responsedata, uint8 *responsedata,
uint8 old_call); uint8 old_call);
@ -12,7 +13,8 @@ extern int close_queue_job2(uint32 q_id, int job_id,
uint8 *client_area, uint8 *client_area,
uint8 *prc, int prc_len); uint8 *prc, int prc_len);
extern int service_queue_job(uint32 q_id, extern int service_queue_job(int task,
uint32 q_id,
uint8 *queue_job, uint8 *queue_job,
uint8 *responsedata, uint8 *responsedata,
uint8 old_call); uint8 old_call);
@ -21,4 +23,6 @@ extern int finish_abort_queue_job(uint32 q_id, int job_id);
extern uint32 get_queue_job_fhandle(uint32 q_id, int job_id); extern uint32 get_queue_job_fhandle(uint32 q_id, int job_id);
extern void free_queue_jobs(void); extern void free_queue_jobs(void);
extern void free_connection_task_jobs(int task);
#endif #endif

153
nwqueue.c
View File

@ -1,4 +1,4 @@
/* nwqueue.c 08-Oct-97 */ /* nwqueue.c 04-Jun-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -42,8 +42,8 @@ typedef struct S_INT_QUEUE_JOB {
int server_task; int server_task;
uint32 server_id; uint32 server_id;
uint8 job_description[50]; uint8 job_description[50];
uint8 client_area[152];
time_t file_entry_time; /* for filenamehandling */ time_t file_entry_time; /* for filenamehandling */
uint8 client_area[152]; /* must be int aligned */
struct S_INT_QUEUE_JOB *next; struct S_INT_QUEUE_JOB *next;
} INT_QUEUE_JOB; } INT_QUEUE_JOB;
@ -73,6 +73,8 @@ typedef struct S_NWE_QUEUE {
NWE_QUEUE *nwe_queues=NULL; NWE_QUEUE *nwe_queues=NULL;
static int entry18_flags;
static NWE_QUEUE *new_queue(uint32 id) static NWE_QUEUE *new_queue(uint32 id)
{ {
NWE_QUEUE *p=(NWE_QUEUE*)xcmalloc(sizeof(NWE_QUEUE)); NWE_QUEUE *p=(NWE_QUEUE*)xcmalloc(sizeof(NWE_QUEUE));
@ -132,7 +134,7 @@ static INT_QUEUE_JOB *add_queue_job(NWE_QUEUE *que, INT_QUEUE_JOB *p)
if (!que->queue_jobs) { if (!que->queue_jobs) {
que->queue_jobs=p; que->queue_jobs=p;
p->job_position=1; p->job_position=1;
que->last_job_id=1; if (++(que->last_job_id)>999) que->last_job_id=1;
} else { } else {
int flag; int flag;
INT_QUEUE_JOB *qj; INT_QUEUE_JOB *qj;
@ -251,8 +253,11 @@ static void r_w_queue_jobs(NWE_QUEUE *q, int mode)
qj->server_station=0; qj->server_station=0;
qj->server_id=0; qj->server_id=0;
qj->job_control_flags &= ~0x20; qj->job_control_flags &= ~0x20;
add_queue_job(q, qj); add_queue_job(q, qj);
qj=(INT_QUEUE_JOB*)xmalloc(sizeof(INT_QUEUE_JOB)); qj=(INT_QUEUE_JOB*)xmalloc(sizeof(INT_QUEUE_JOB));
} }
xfree(qj); xfree(qj);
} }
@ -371,6 +376,10 @@ static int fill_q_job_entry(INT_QUEUE_JOB *jo,
{ {
memset(job->record_in_use, 0xff, 2); memset(job->record_in_use, 0xff, 2);
memset(job->record_previous, 0, 4); memset(job->record_previous, 0, 4);
if (jo->next) { /* (Alexey) we _must_ set id of next job in job-list */
U32_TO_32(jo->next->job_id, job->record_next);
} else
memset(job->record_next, 0, 4); memset(job->record_next, 0, 4);
U32_TO_32(jo->client_connection, job->client_connection); U32_TO_32(jo->client_connection, job->client_connection);
@ -452,12 +461,17 @@ int nw_creat_queue_job(int connection, int task, uint32 object_id,
int nw_close_queue_job(uint32 q_id, int job_id, int nw_close_queue_job(uint32 q_id, int job_id,
uint8 *responsedata) uint8 *responsedata)
{ {
int result=-0xd8; /* queue not active */
NWE_QUEUE *que=find_queue(q_id); NWE_QUEUE *que=find_queue(q_id);
if (que) { if (que) {
INT_QUEUE_JOB *jo=find_queue_job(que, job_id); INT_QUEUE_JOB *jo=find_queue_job(que, job_id);
if (jo) { if (jo) {
int result=sizeof(jo->client_area);
int i; int i;
QUEUE_PRINT_AREA *qpa=(QUEUE_PRINT_AREA*)jo->client_area;
result=sizeof(jo->client_area);
if (entry18_flags&0x1) { /* always suppress banner */
qpa->print_flags[1] &= ~0x80;
}
jo->job_control_flags &= ~0x20; jo->job_control_flags &= ~0x20;
memcpy(responsedata, jo->client_area, result); memcpy(responsedata, jo->client_area, result);
i = nw_get_q_prcommand(q_id, responsedata+result+1); i = nw_get_q_prcommand(q_id, responsedata+result+1);
@ -468,11 +482,12 @@ int nw_close_queue_job(uint32 q_id, int job_id,
} else } else
*(responsedata+result)=0; *(responsedata+result)=0;
++result; ++result;
} else
result=-0xff;
}
XDPRINTF(((result<0) ? 1 : 5, 0, "nw_close_queue_job, q=%lx, job=%d, result=%d",
q_id, job_id, result));
return(result); return(result);
}
return(-0xff);
}
return(-0xd8); /* queue not active */
} }
int nw_get_queue_status(uint32 q_id, int *status, int *entries, int nw_get_queue_status(uint32 q_id, int *status, int *entries,
@ -493,6 +508,16 @@ int nw_get_queue_status(uint32 q_id, int *status, int *entries,
return(-0xff); return(-0xff);
} }
int nw_set_queue_status(uint32 q_id, int status)
{
NWE_QUEUE *q=find_queue(q_id);
if (q) {
q->status=status;
return(0);
}
return(-0xd3); /* no rights */
}
int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle, int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle,
uint8 *responsedata, int old_call) uint8 *responsedata, int old_call)
{ {
@ -534,22 +559,71 @@ int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata)
return(result); return(result);
} }
int nw_get_queue_job_file_size(uint32 q_id, int job_id) int nw_get_queue_job_list(uint32 q_id, uint32 offset, uint8 *responsedata)
{ {
int result=-0xd5; int result = -0xff;
NWE_QUEUE *q = find_queue(q_id); NWE_QUEUE *q = find_queue(q_id);
INT_QUEUE_JOB *qj = find_queue_job(q, job_id); if (q) {
if (qj) { INT_QUEUE_JOB *qj=q->queue_jobs;
uint8 *p=responsedata+8;
int fullcount=0;
int count=0;
if (offset == MAX_U32)
offset = 0;
while (qj) {
if (++fullcount > offset && count < 125) { /* max. 125 entries */
++count;
U16_TO_BE16(qj->job_id, p);
p+=2;
*p++=0;
*p++=0;
}
qj=qj->next;
}
#if 0
U32_TO_BE32(fullcount, responsedata);
U32_TO_BE32(count, responsedata+4);
#else
/* georg@globaltrading.net */
U32_TO_32(fullcount, responsedata);
U32_TO_32(count, responsedata+4);
#endif
result=8+count*4;
}
return(result);
}
static int get_qj_file_size(NWE_QUEUE *q, INT_QUEUE_JOB *qj)
{
if (q && qj) {
struct stat stb; struct stat stb;
uint8 buf[300]; uint8 buf[300];
build_unix_queue_file(buf, q, qj); build_unix_queue_file(buf, q, qj);
if (!stat(buf, &stb)) if (!stat(buf, &stb))
return(stb.st_size); return(stb.st_size);
return(0);
} }
return(0);
}
int nw_get_queue_job_file_size(uint32 q_id, int job_id)
{
int result=-0xd5;
NWE_QUEUE *q = find_queue(q_id);
INT_QUEUE_JOB *qj = find_queue_job(q, job_id);
if (qj)
return(get_qj_file_size(q, qj));
return(result); return(result);
} }
int nw_change_queue_job_entry(uint32 q_id, uint8 *qjstruct)
{
/* TODO */
return(-0xfb);
}
static int remove_queue_job_file(NWE_QUEUE *q, INT_QUEUE_JOB *qj) static int remove_queue_job_file(NWE_QUEUE *q, INT_QUEUE_JOB *qj)
{ {
struct stat stb; struct stat stb;
@ -582,6 +656,35 @@ int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id)
return(result); return(result);
} }
void nw_close_connection_jobs(int connection, int task)
/*
* this routine closes pending client open queue jobs
* if (task == -1) all jobs of connection are affected
*/
{
NWE_QUEUE *q=(NWE_QUEUE*)nwe_queues;
while (q) {
INT_QUEUE_JOB *qj=q->queue_jobs;
while(qj) {
if (qj->client_connection == connection
&& (qj->client_task == task || task == -1)
&& (qj->job_control_flags & 0x20) ) { /* actual queued */
if (get_qj_file_size(q, qj) > 0) { /* we mark it as not queued */
qj->job_control_flags &= ~0x20;
} else { /* we remove it */
XDPRINTF((1, 0, "Queue job removed by nw_close_connection_jobs, conn=%d, task=%d", connection, task));
(void)remove_queue_job_file(q, qj);
free_queue_job(q, qj->job_id);
}
qj=q->queue_jobs;
continue;
}
qj=qj->next;
}
q=q->next;
}
}
/* ------------------ for queue servers ------------------- */ /* ------------------ for queue servers ------------------- */
static QUEUE_SERVER *new_qserver(uint32 user_id, int connection) static QUEUE_SERVER *new_qserver(uint32 user_id, int connection)
{ {
@ -618,6 +721,8 @@ int nw_attach_server_to_queue(uint32 user_id,
/* we only allow 1 qserver/queue in this version */ /* we only allow 1 qserver/queue in this version */
} }
} }
XDPRINTF((2, 0, "attach TO QUEUE q_id=0x%x, user=0x%x, conn=%d, result=0x%x",
q_id, user_id, connection, result));
return(result); return(result);
} }
@ -647,6 +752,7 @@ int nw_service_queue_job(uint32 user_id, int connection, int task,
if (q && q->qserver if (q && q->qserver
&& q->qserver->user_id == user_id && q->qserver->user_id == user_id
&& q->qserver->connection == connection) { && q->qserver->connection == connection) {
if ( !(q->status & 4) ) { /* not stopped printing */
uint8 *fulldirname = (old_call) ? responsedata+sizeof(QUEUE_JOB_OLD) uint8 *fulldirname = (old_call) ? responsedata+sizeof(QUEUE_JOB_OLD)
: responsedata+sizeof(QUEUE_JOB); : responsedata+sizeof(QUEUE_JOB);
int len = nw_get_q_dirname(q_id, fulldirname+1); int len = nw_get_q_dirname(q_id, fulldirname+1);
@ -664,9 +770,18 @@ int nw_service_queue_job(uint32 user_id, int connection, int task,
&& (qj->target_id == MAX_U32 || qj->target_id == user_id) && (qj->target_id == MAX_U32 || qj->target_id == user_id)
&& (qj->job_typ == MAX_U16 || job_typ==MAX_U16 && (qj->job_typ == MAX_U16 || job_typ==MAX_U16
|| qj->job_typ == job_typ)) { || qj->job_typ == job_typ)) {
if (get_qj_file_size(q, qj) > 0) {
fqj=qj; fqj=qj;
break; break;
} else {
if (time(NULL) - qj->entry_time > 60) { /* ca. 1 min */
XDPRINTF((1, 0, "Queue job of size 0 automaticly removed"));
(void)remove_queue_job_file(q, qj);
free_queue_job(q, qj->job_id);
qj=q->queue_jobs;
continue;
}
}
} else { } else {
XDPRINTF((6, 0, "Queue job ignored: station=%d, target_id=0x%x,job_typ=0x%x, %s", XDPRINTF((6, 0, "Queue job ignored: station=%d, target_id=0x%x,job_typ=0x%x, %s",
qj->server_station, qj->target_id, qj->job_typ, qj->server_station, qj->target_id, qj->job_typ,
@ -694,6 +809,7 @@ int nw_service_queue_job(uint32 user_id, int connection, int task,
} else { } else {
XDPRINTF((1, 0, "Could not get queuedir of q_id=0x%x", q_id)); XDPRINTF((1, 0, "Could not get queuedir of q_id=0x%x", q_id));
} }
} /* if */
} else { } else {
XDPRINTF((1, 0, "Could not find qserver q_id=0x%x, user_id=0x%x, connect=%d", XDPRINTF((1, 0, "Could not find qserver q_id=0x%x, user_id=0x%x, connect=%d",
q_id, user_id, connection)); q_id, user_id, connection));
@ -795,7 +911,7 @@ int nw_creat_queue(int q_typ, uint8 *q_name, int q_name_len,
*path=0; *path=0;
upstr(q_directory); upstr(q_directory);
} else { } else {
strcpy(q_directory, "SYS:SYSTEM"); xstrcpy(q_directory, "SYS:SYSTEM");
path_len=10; path_len=10;
path=q_directory+path_len; path=q_directory+path_len;
} }
@ -868,18 +984,19 @@ int nw_destroy_queue(uint32 q_id)
} }
void init_queues(void) void init_queues(int entry18_flags_p)
{ {
NETOBJ obj; NETOBJ obj;
uint8 buf[300]; uint8 buf[300];
int result; int result;
uint8 *wild="*"; uint8 *wild="*";
uint32 last_obj_id=MAX_U32; uint32 last_obj_id=MAX_U32;
entry18_flags=entry18_flags_p;
exit_queues(); exit_queues();
strmaxcpy(buf, sys_unixname, sys_unixnamlen); strmaxcpy(buf, sys_unixname, sys_unixnamlen);
XDPRINTF((3,0, "init_queues:unixname='%s'", buf)); XDPRINTF((3,0, "init_queues:unixname='%s'", buf));
obj.type = 3; /* queue */ obj.type = 3; /* queue */
strcpy(obj.name, wild); xstrcpy(obj.name, wild);
result = scan_for_obj(&obj, last_obj_id, 1); result = scan_for_obj(&obj, last_obj_id, 1);
while (!result) { while (!result) {
@ -898,7 +1015,7 @@ void init_queues(void)
r_w_queue_jobs(que, 0); r_w_queue_jobs(que, 0);
} }
last_obj_id=obj.id; last_obj_id=obj.id;
strcpy(obj.name, wild); xstrcpy(obj.name, wild);
result = scan_for_obj(&obj, last_obj_id, 1); result = scan_for_obj(&obj, last_obj_id, 1);
} }
} }

View File

@ -1,4 +1,4 @@
/* nwqueue.h 08-Oct-97 */ /* nwqueue.h 14-Apr-98 */
#ifndef _NWQUEUE_H_ #ifndef _NWQUEUE_H_
#define _NWQUEUE_H_ #define _NWQUEUE_H_
#include "queuedef.h" #include "queuedef.h"
@ -15,13 +15,20 @@ extern int nw_close_queue_job(uint32 q_id, int job_id,
extern int nw_get_queue_status(uint32 q_id, int *status, int *entries, extern int nw_get_queue_status(uint32 q_id, int *status, int *entries,
int *servers, int server_ids[], int server_conns[]); int *servers, int server_ids[], int server_conns[]);
extern int nw_set_queue_status(uint32 q_id, int status);
extern int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle, extern int nw_get_q_job_entry(uint32 q_id, int job_id, uint32 fhandle,
uint8 *responsedata, int old_call); uint8 *responsedata, int old_call);
extern int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata); extern int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata);
extern int nw_get_queue_job_list(uint32 q_id, uint32 offset, uint8 *responsedata);
extern int nw_get_queue_job_file_size(uint32 q_id, int job_id); extern int nw_get_queue_job_file_size(uint32 q_id, int job_id);
extern int nw_change_queue_job_entry(uint32 q_id, uint8 *qjstruct);
extern int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id); extern int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id);
extern void nw_close_connection_jobs(int connection, int task);
/* ------------------ for queue servers ------------------- */ /* ------------------ for queue servers ------------------- */
extern int nw_attach_server_to_queue(uint32 user_id, extern int nw_attach_server_to_queue(uint32 user_id,
int connection, int connection,
@ -44,5 +51,5 @@ extern int nw_creat_queue(int q_typ, uint8 *q_name, int q_name_len,
extern int nw_destroy_queue(uint32 q_id); extern int nw_destroy_queue(uint32 q_id);
extern void exit_queues(void); extern void exit_queues(void);
extern void init_queues(void); extern void init_queues(int entry18_flags_p);
#endif #endif

View File

@ -1,5 +1,5 @@
/* nwroute.c 08-Feb-98 */ /* nwroute.c 18-Apr-00 */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -50,7 +50,7 @@ static NW_SERVERS **nw_servers=NULL;
#define NEEDS_UPDATE_RIP_NET 8 #define NEEDS_UPDATE_RIP_NET 8
#define NEEDS_UPDATE_ALL (8|4|2|1) #define NEEDS_UPDATE_ALL (8|4|2|1)
static void insert_delete_net(uint32 destnet, static void insert_delete_net(uint32 destnet, /* destination net */
uint32 rnet, /* routernet */ uint32 rnet, /* routernet */
uint8 *rnode, /* routernode */ uint8 *rnode, /* routernode */
uint16 hops, uint16 hops,
@ -77,7 +77,8 @@ static void insert_delete_net(uint32 destnet,
if (!do_delete) return; /* don't alter device */ if (!do_delete) return; /* don't alter device */
nd_dev = nd; nd_dev = nd;
} }
if (nd->net == rnet) ndticks=nd->ticks; if (nd->net == rnet)
ndticks=nd->ticks;
} }
} }
if (!do_delete && nd_dev && nd_dev->ticks <= ndticks) return; if (!do_delete && nd_dev && nd_dev->ticks <= ndticks) return;
@ -94,7 +95,7 @@ static void insert_delete_net(uint32 destnet,
int new_max_nw = max_nw_routes+5; int new_max_nw = max_nw_routes+5;
NW_ROUTES **new_nwr NW_ROUTES **new_nwr
=(NW_ROUTES**)xcmalloc(new_max_nw*sizeof(NW_ROUTES*)); =(NW_ROUTES**)xcmalloc(new_max_nw*sizeof(NW_ROUTES*));
if (max_nw_servers) if (max_nw_routes)
memcpy(new_nwr, nw_routes, max_nw_routes*sizeof(NW_ROUTES*)); memcpy(new_nwr, nw_routes, max_nw_routes*sizeof(NW_ROUTES*));
xfree(nw_routes); xfree(nw_routes);
nw_routes=new_nwr; nw_routes=new_nwr;
@ -109,14 +110,13 @@ static void insert_delete_net(uint32 destnet,
nr->ticks = 0xffff; nr->ticks = 0xffff;
nr->hops = 0xffff; nr->hops = 0xffff;
} else if (do_delete) { } else if (do_delete) {
nr=nw_routes[k]; nr=nw_routes[k];
if (nr->rnet == rnet && IPXCMPNODE(nr->rnode, rnode) ) { if (nr->rnet == rnet && IPXCMPNODE(nr->rnode, rnode) ) {
/* only delete the routes, which we have inserted */ /* only delete the routes, which we have inserted */
XDPRINTF((2,0,"ROUTE DEL NET=0x%x over Router NET 0x%x", XDPRINTF((2,0,"ROUTE DEL NET=0x%x over Router NET 0x%x",
nr->net, rnet)); nr->net, rnet));
ipx_route_del(nr->net);
ipx_route_del(nr->net);
if (nd_dev != NULL) { /* this is net to our device */ if (nd_dev != NULL) { /* this is net to our device */
/* I must delete and setup new, because there is */ /* I must delete and setup new, because there is */
/* no direct way to delete this route from interface :( */ /* no direct way to delete this route from interface :( */
@ -135,7 +135,7 @@ static void insert_delete_net(uint32 destnet,
ticks+=ndticks; ticks+=ndticks;
if (ticks <= nr->ticks) { if (ticks <= nr->ticks) {
if (ticks == nr->ticks && hops >= nr->hops) return; if (ticks == nr->ticks && hops > nr->hops) return;
nr->hops = hops; nr->hops = hops;
nr->ticks = ticks; nr->ticks = ticks;
nr->rnet = rnet; nr->rnet = rnet;
@ -607,6 +607,10 @@ static FILE *open_route_info_fn(int force, FILE *ff, int section)
} else { } else {
fn=pr_route_info_fn; fn=pr_route_info_fn;
} }
if (is_filelink(fn)) /* security, mst:18-Apr-00 */
unlink(fn);
f=fopen(fn, (print_route_mode&0x1) ? "w" : "a"); f=fopen(fn, (print_route_mode&0x1) ? "w" : "a");
if (section == 1) { if (section == 1) {
if (NULL != f) if (NULL != f)
@ -701,10 +705,11 @@ static int look_for_interfaces(void);
void send_sap_rip_broadcast(int mode) void send_sap_rip_broadcast(int mode)
/* mode=0, standard broadcast */ /* mode=0, standard broadcast */
/* mode=1, first trie */ /* mode=1, first trie */
/* mode=2, shutdown */ /* mode=2, sap shutdown */
/* mode=3, update routes */ /* mode=3, update routes */
/* mode=4, resend to net */ /* mode=4, resend to net */
/* mode=5, force update routes */ /* mode=5, force update routes */
/* mode=22, rip shutdown */
{ {
static int flipflop=1; static int flipflop=1;
int force_print_routes=(mode == 1) ? 1 : 0; int force_print_routes=(mode == 1) ? 1 : 0;
@ -720,16 +725,20 @@ static int flipflop=1;
send_rip_broadcast(1); send_rip_broadcast(1);
send_sap_broadcast(1); send_sap_broadcast(1);
} }
} else if (mode == 22) {
send_rip_broadcast(2);
} else if (mode == 2) {
send_sap_broadcast(2);
} else { } else {
send_rip_broadcast(mode); send_rip_broadcast(mode);
send_sap_broadcast(mode); send_sap_broadcast(mode);
} }
} else { } else {
if (flipflop) { if (flipflop) {
send_rip_broadcast(mode); send_rip_broadcast(0);
flipflop=0; flipflop=0;
} else { } else {
send_sap_broadcast(mode); send_sap_broadcast(0);
flipflop=1; flipflop=1;
} }
} }
@ -948,8 +957,8 @@ static int look_for_interfaces(void)
for (j=0; j < anz_routes; j++){ for (j=0; j < anz_routes; j++){
NW_ROUTES *nr=nw_routes[j]; NW_ROUTES *nr=nw_routes[j];
if (nr && nr->rnet == nd->net) { if (nr && nr->rnet == nd->net) {
XDPRINTF((1,0,"Route to net=0x%x removed", nr->net)); /* !! */
nr->net = 0L; /* remove route */ nr->net = 0L; /* remove route */
XDPRINTF((1,0,"Route to net=0x%x removed", nr->net));
} }
} }
if (nd->wildmask & 1) if (nd->wildmask & 1)

View File

@ -123,8 +123,8 @@ void get_servers(void)
SQP sqp; SQP sqp;
ipxAddr_t wild; ipxAddr_t wild;
memset(&wild, 0, sizeof(ipxAddr_t)); memset(&wild, 0, sizeof(ipxAddr_t));
#ifdef xxxLINUX #ifdef FREEBSD
U32_TO_BE32(internal_net, wild.net); U32_TO_BE32(internal_net, wild.net); /* ask ONLY IPXrouted */
memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE); memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE);
#else #else
memset(wild.node, 0xFF, IPX_NODE_SIZE); memset(wild.node, 0xFF, IPX_NODE_SIZE);
@ -150,11 +150,9 @@ void send_sap_rip_broadcast(int mode)
IPX_DATA ipx_data; IPX_DATA ipx_data;
ipxAddr_t wild; ipxAddr_t wild;
memset(&wild, 0, sizeof(ipxAddr_t)); memset(&wild, 0, sizeof(ipxAddr_t));
#ifdef xxxLINUX memset(wild.node, 0xFF, IPX_NODE_SIZE); /* broadcast */
U32_TO_BE32(internal_net, wild.net); #ifdef FREEBSD
memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE); U32_TO_BE32(internal_net, wild.net); /* there is no default net */
#else
memset(wild.node, 0xFF, IPX_NODE_SIZE);
#endif #endif
U16_TO_BE16(SOCK_SAP, wild.sock); U16_TO_BE16(SOCK_SAP, wild.sock);
memset(&ipx_data, 0, sizeof(ipx_data.sip)); memset(&ipx_data, 0, sizeof(ipx_data.sip));
@ -169,6 +167,16 @@ void send_sap_rip_broadcast(int mode)
sizeof(ipx_data.sip), sizeof(ipx_data.sip),
(char *)&(ipx_data.sip), (char *)&(ipx_data.sip),
&wild, "SIP Broadcast"); &wild, "SIP Broadcast");
#ifdef FREEBSD
U32_TO_BE32(internal_net, wild.net);
memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE);
/* tell to IPXrouted for single server case */
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");
#endif
if (!mode) get_servers(); if (!mode) get_servers();
if (mode == 1) { if (mode == 1) {
U16_TO_BE16(SOCK_SAP, wild.sock); U16_TO_BE16(SOCK_SAP, wild.sock);

140
nwserv.c
View File

@ -1,4 +1,4 @@
/* nwserv.c 08-Feb-98 */ /* nwserv.c 19-May-98 */
/* MAIN Prog for NWSERV + NWROUTED */ /* MAIN Prog for NWSERV + NWROUTED */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
@ -93,14 +93,7 @@ static uint16 sock_nummern [NEEDED_SOCKETS];
int sockfd [NEEDED_SOCKETS]; int sockfd [NEEDED_SOCKETS];
static struct pollfd polls[NEEDED_POLLS]; static struct pollfd polls[NEEDED_POLLS];
#if 0
static uint16 spx_diag_socket; /* SPX DIAGNOSE SOCKET */ static uint16 spx_diag_socket; /* SPX DIAGNOSE SOCKET */
#endif
#if !IN_NWROUTED
static ipxAddr_t nw386_adr; /* Address of NW-TEST Server */
static int nw386_found = 0;
static int client_mode = 0;
#endif
static int ipxdebug = 0; static int ipxdebug = 0;
static int pid_ncpserv = -1; static int pid_ncpserv = -1;
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */ static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
@ -353,25 +346,6 @@ static int start_nwbind(char *nwname)
} }
#if !IN_NWROUTED #if !IN_NWROUTED
static int start_nwclient(void)
{
switch (fork()){
case 0 : { /* new Process */
char *progname="nwclient";
char pathname[300];
char my_addrstr[100];
char serv_addrstr[100];
ipx_addr_to_adr(my_addrstr, &my_server_adr);
ipx_addr_to_adr(serv_addrstr, &nw386_adr);
execl(get_exec_path(pathname, progname), progname,
my_addrstr, serv_addrstr, NULL);
}
exit(1);
case -1: return(-1); /* error */
}
return(0); /* OK */
}
/* =========================== WDOG =============================== */ /* =========================== WDOG =============================== */
#ifndef _WDOG_TESTING_ #ifndef _WDOG_TESTING_
@ -509,23 +483,6 @@ static void send_bcasts(int conn)
#endif #endif
void get_server_data(char *name,
ipxAddr_t *adr,
ipxAddr_t *from_addr)
{
#if !IN_NWROUTED
if (!nw386_found && strcmp(name, my_nwname)) {
memcpy(&nw386_adr, adr, sizeof(ipxAddr_t));
nw386_found++;
if (client_mode) {
start_nwclient();
client_mode = 0; /* only start once */
}
}
#endif
XDPRINTF((2,0,"NW386 %s found at:%s", name, visable_ipx_adr(adr)));
}
static void handle_sap(int fd, static void handle_sap(int fd,
int ipx_pack_typ, int ipx_pack_typ,
int data_len, int data_len,
@ -579,7 +536,6 @@ static void handle_sap(int fd,
XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name)); XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name));
insert_delete_server(name, type, NULL, NULL, 16, 1, 0); insert_delete_server(name, type, NULL, NULL, 16, 1, 0);
} else { } else {
get_server_data((char*)name, ad, from_addr);
insert_delete_server(name, type, ad, from_addr, hops, 0, 0); insert_delete_server(name, type, ad, from_addr, hops, 0, 0);
if (type == 4) flag=1; if (type == 4) flag=1;
} }
@ -638,7 +594,18 @@ static void response_ipx_diag(int fd, int ipx_pack_typ,
IPX_DATA ipxdata; IPX_DATA ipxdata;
DIAGRESP *dia = &ipxdata.diaresp; DIAGRESP *dia = &ipxdata.diaresp;
uint8 *p = (uint8*) (dia+1); uint8 *p = (uint8*) (dia+1);
int datalen = sizeof(DIAGRESP); /* erstmal */ uint8 *net_count;
FILE *f;
char buff[200];
int i;
unsigned int b;
uint32 rnet;
uint8 dname[25];
char node[20];
int flags;
int fframe;
int datalen = sizeof(DIAGRESP);
dia->majorversion = 1; dia->majorversion = 1;
dia->minorversion = 1; dia->minorversion = 1;
U16_TO_BE16(spx_diag_socket, dia->spx_diag_sock); U16_TO_BE16(spx_diag_socket, dia->spx_diag_sock);
@ -650,15 +617,41 @@ static void response_ipx_diag(int fd, int ipx_pack_typ,
/* now extended */ /* now extended */
*p++ = 6; /* Fileserver/Bridge (internal) */ *p++ = 6; /* Fileserver/Bridge (internal) */
datalen++; datalen++;
*p++ = 1; /* Anz. Networks */ net_count = p++;
*net_count = 0;
datalen++; datalen++;
*p++ = 0; /* LAN BOARD */ /* --- Code by Valeri Bourak ----- */
if (internal_net) {
(*net_count)++;
*p++ = 1; /* virtual board */
datalen++; datalen++;
memcpy(p, my_server_adr.net, IPX_NET_SIZE); U32_TO_BE32(internal_net, p);
p += IPX_NET_SIZE; p += IPX_NET_SIZE;
datalen += IPX_NET_SIZE; datalen += IPX_NET_SIZE;
memcpy(p, my_server_adr.node, IPX_NODE_SIZE); memcpy(p, my_server_adr.node, IPX_NODE_SIZE);
p += IPX_NODE_SIZE;
datalen += IPX_NODE_SIZE; datalen += IPX_NODE_SIZE;
}
if (NULL != (f=fopen("/proc/net/ipx_interface", "r"))) {
while (fgets((char*)buff, sizeof(buff), f) != NULL){
fframe = read_interface_data((uint8*) buff, &rnet, node, &flags, dname);
if (fframe < 0) continue;
if (rnet > 0L && !(flags & 2)) { /* not internal */
(*net_count)++;
*p++ = 0; /* LAN board */
datalen++;
U32_TO_BE32(rnet, p);
p += IPX_NET_SIZE;
datalen += IPX_NET_SIZE;
for (i = 0; i < 12 ; i += 2) {
sscanf(&node[i], "%2x", &b);
*p++ = (uint8)b;
}
datalen += IPX_NODE_SIZE;
}
}
fclose(f);
}
send_ipx_data(fd, ipx_pack_typ, send_ipx_data(fd, ipx_pack_typ,
datalen, datalen,
(char*)&ipxdata, (char*)&ipxdata,
@ -701,8 +694,6 @@ static void handle_extern_call(int fd,
memcpy(&auth_addr, from_addr, sizeof(ipxAddr_t)); memcpy(&auth_addr, from_addr, sizeof(ipxAddr_t));
is_auth=0; is_auth=0;
} }
} }
#endif #endif
@ -963,11 +954,6 @@ static void get_ini(int full)
max_connections=MAX_CONNECTIONS; max_connections=MAX_CONNECTIONS;
} }
break; break;
case 104 : /* nwclient */
if (client_mode && atoi(inhalt))
client_mode++;
break;
#endif #endif
case 210 : server_goes_down_secs=atoi(inhalt); case 210 : server_goes_down_secs=atoi(inhalt);
if (server_goes_down_secs < 1 || if (server_goes_down_secs < 1 ||
@ -1005,9 +991,6 @@ static void get_ini(int full)
} /* while */ } /* while */
fclose(f); fclose(f);
} }
#if !IN_NWROUTED
if (client_mode < 2) client_mode=0;
#endif
if (print_route_tac && !pr_route_info_fn && !*pr_route_info_fn) if (print_route_tac && !pr_route_info_fn && !*pr_route_info_fn)
print_route_tac = 0; print_route_tac = 0;
if (!print_route_tac) xfree(pr_route_info_fn); if (!print_route_tac) xfree(pr_route_info_fn);
@ -1091,9 +1074,16 @@ static void close_all(void)
t_close(ipx_out_fd); t_close(ipx_out_fd);
} }
#endif #endif
while (j--) { while (j--) {
#ifdef RIP_SLOT
if ( j != RIP_SLOT ) {
#endif
t_unbind(sockfd[j]); t_unbind(sockfd[j]);
t_close(sockfd[j]); t_close(sockfd[j]);
#ifdef RIP_SLOT
}
#endif
} }
if (pid_ncpserv > 0) { if (pid_ncpserv > 0) {
@ -1121,6 +1111,13 @@ static void close_all(void)
#ifdef LINUX #ifdef LINUX
# if INTERNAL_RIP_SAP # if INTERNAL_RIP_SAP
#if 1 #if 1
if ((!ipx_inuse(0)) || (ipx_flags&4)) {
send_sap_rip_broadcast(22);
sleep(2);
send_sap_rip_broadcast(22);
sleep(1);
t_unbind(sockfd[RIP_SLOT]);
t_close(sockfd[RIP_SLOT]);
if (!(ipx_flags&1)) { if (!(ipx_flags&1)) {
for (j=0; j<count_net_devices;j++) { for (j=0; j<count_net_devices;j++) {
NW_NET_DEVICE *nd=net_devices[j]; NW_NET_DEVICE *nd=net_devices[j];
@ -1131,6 +1128,9 @@ static void close_all(void)
} }
} }
} }
} else {
XDPRINTF((1, 0, "Not sending rip hangup, because ipxinuse"));
}
#endif #endif
exit_ipx(ipx_flags); exit_ipx(ipx_flags);
# endif # endif
@ -1238,7 +1238,7 @@ static int server_is_down=0;
static int usage(char *prog) static int usage(char *prog)
{ {
#if !IN_NWROUTED #if IN_NWROUTED || INTERNAL_RIP_SAP
fprintf(stderr, "usage:\t%s [-V|-h|-f|-u|-k[q]|y]\n", prog); fprintf(stderr, "usage:\t%s [-V|-h|-f|-u|-k[q]|y]\n", prog);
fprintf(stderr, "or:\t%s -a device frame netnum\n", prog); fprintf(stderr, "or:\t%s -a device frame netnum\n", prog);
fprintf(stderr, "or:\t%s -d device frame\n", prog); fprintf(stderr, "or:\t%s -d device frame\n", prog);
@ -1246,6 +1246,7 @@ static int usage(char *prog)
fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]]\n", prog); fprintf(stderr, "usage:\t%s [-V|-h|-u|-k[q]]\n", prog);
#endif #endif
fprintf(stderr, "\t-V: print version\n"); fprintf(stderr, "\t-V: print version\n");
#if IN_NWROUTED || INTERNAL_RIP_SAP
fprintf(stderr, "\t-a: add interface, frames = '802.2' '802.3' 'etherii' 'snap'\n"); fprintf(stderr, "\t-a: add interface, frames = '802.2' '802.3' 'etherii' 'snap'\n");
fprintf(stderr, "\t-d: delete interface.\n"); fprintf(stderr, "\t-d: delete interface.\n");
fprintf(stderr, "\t-h: send HUP to main process\n"); fprintf(stderr, "\t-h: send HUP to main process\n");
@ -1253,6 +1254,7 @@ static int usage(char *prog)
fprintf(stderr, "\t-u: update int. routing table\n"); fprintf(stderr, "\t-u: update int. routing table\n");
fprintf(stderr, "\t-k: stop main process, wait for it.\n"); fprintf(stderr, "\t-k: stop main process, wait for it.\n");
fprintf(stderr, "\t-kq: don't wait till stop of main process\n"); fprintf(stderr, "\t-kq: don't wait till stop of main process\n");
#endif
#if !IN_NWROUTED #if !IN_NWROUTED
fprintf(stderr, "\t y: start testclient code.\n"); fprintf(stderr, "\t y: start testclient code.\n");
#endif #endif
@ -1267,12 +1269,16 @@ int main(int argc, char **argv)
fprintf(stderr, "You must have root permission !\n"); fprintf(stderr, "You must have root permission !\n");
exit(1); exit(1);
} }
#ifdef FREEBSD
set_emu_tli();
#endif
tzset(); tzset();
while (++j < argc) { while (++j < argc) {
char *a=argv[j]; char *a=argv[j];
if (*a == '-') { if (*a == '-') {
while (*(++a)) { while (*(++a)) {
switch (*a) { switch (*a) {
#ifdef LINUX
case 'a' : case 'a' :
case 'd' : case 'd' :
if ( (*a == 'a' && argc - j == 4) if ( (*a == 'a' && argc - j == 4)
@ -1297,23 +1303,24 @@ int main(int argc, char **argv)
else if (!strcmp(buf, "TOKEN")) else if (!strcmp(buf, "TOKEN"))
frame=IPX_FRAME_TR_8022; frame=IPX_FRAME_TR_8022;
# endif # endif
if (*a == 'a' && frame > -1) { if (*a == 'a' && frame > -1) {
char dummy; char dummy;
if (sscanf(argv[j+3], "%ld%c", &netnum, &dummy) != 1) if (sscanf(argv[j+3], "%ld%c", &netnum, &dummy) != 1)
sscanf(argv[j+3], "%lx", &netnum); sscanf(argv[j+3], "%lx", &netnum);
} }
#if IN_NWROUTED || INTERNAL_RIP_SAP
if (netnum > 0) if (netnum > 0)
result=add_device_net(argv[j+1], frame, netnum); result=add_device_net(argv[j+1], frame, netnum);
else if ( *a == 'd') { else if ( *a == 'd') {
exit_dev(argv[j+1], frame); exit_dev(argv[j+1], frame);
result=0; result=0;
} else } else
#endif
return(usage(argv[0])); return(usage(argv[0]));
return((result<0) ? 1 : 0); return((result<0) ? 1 : 0);
} else } else
return(usage(argv[0])); return(usage(argv[0]));
#endif
case 'h' : init_mode = 1; break; case 'h' : init_mode = 1; break;
case 'k' : init_mode = 2; break; case 'k' : init_mode = 2; break;
case 'u' : init_mode = 3; break; case 'u' : init_mode = 3; break;
@ -1326,13 +1333,7 @@ int main(int argc, char **argv)
default : return(usage(argv[0])); default : return(usage(argv[0]));
} }
} }
} } else
#if !IN_NWROUTED
else if (*a == 'y')
client_mode=1;
/* in client mode the testprog 'nwclient' will be startet. */
#endif
else
return(usage(argv[0])); return(usage(argv[0]));
} }
#if !DO_TESTING #if !DO_TESTING
@ -1555,7 +1556,6 @@ int main(int argc, char **argv)
} else { } else {
#if !IN_NWROUTED #if !IN_NWROUTED
if (call_wdog) send_wdogs(1); if (call_wdog) send_wdogs(1);
if (client_mode && difftime > 5) get_servers(); /* Here more often */
#endif #endif
} }
} }

View File

@ -70,9 +70,9 @@ extern NW_NET_DEVICE **net_devices;
#if INTERNAL_RIP_SAP #if INTERNAL_RIP_SAP
# define RIP_SLOT (SAP_SLOT +1) # define RIP_SLOT (SAP_SLOT +1)
# if 0
# define ROUTE_SLOT (RIP_SLOT +1) # define ROUTE_SLOT (RIP_SLOT +1)
# define DIAG_SLOT (ROUTE_SLOT +1) # define DIAG_SLOT (ROUTE_SLOT +1)
# if 0
# define ECHO_SLOT (DIAG_SLOT +1) # define ECHO_SLOT (DIAG_SLOT +1)
# define ERR_SLOT (ECHO_SLOT +1) # define ERR_SLOT (ECHO_SLOT +1)
# endif # endif

751
nwshare.c
View File

@ -1,6 +1,5 @@
/* nwshare.c 21-Jul-97 */ /* nwshare.c, 13-Apr-00 */
/* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany
/* (C)opyright (C) 1993,1997 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -26,59 +25,216 @@
#include "unxfile.h" #include "unxfile.h"
#include "nwshare.h" #include "nwshare.h"
#define MAX_SH_OP_DEV 20 /* changed by: Ingmar Thiemann <ingmar@gefas.com>
* share_file() is now always called, when a file is opened.
* The open_mode is the access mode of the file open function.
*/
typedef struct { typedef struct _tagShareLock {
int fd_r; int l_start;
int fd_wr; int l_len;
int in_use; int fd;
int exclusive; /* exclusive lock */
struct _tagShareLock *next;
} ShareLock;
typedef struct _tagShareINode {
int inode;
int or; /* open read */
int ow; /* open write */
int dr; /* deny read */
int dw; /* deny write */
#if 0
int cm; /* compatible mode */
#endif
/* ------------ */
int fl; /* file lock */
int ex; /* exlusive file lock */
ShareLock *first_lock;
struct _tagShareINode *next;
} ShareINode;
typedef struct _tagShareDev {
int dev; int dev;
} SH_OP_DEV;
static SH_OP_DEV sh_op_devs[MAX_SH_OP_DEV]; int fd_sm; /* semaphor for locking operation */
static int count_sh_op_dev=0; int fd_or; /* open read */
int fd_ow; /* open write */
int fd_dr; /* deny read */
int fd_dw; /* deny write */
#if 0
int fd_cm; /* compatible mode */
#endif
int fd_fl; /* file lock */
ShareINode *first_inode;
struct _tagShareDev *next;
} ShareDev;
char *path_share_lock_files=NULL; static ShareDev *first_dev = NULL;
int share_file(int dev, int inode, int sh_mode) static char *path_share_lock_files=NULL;
/* sh_mode
* 0 : remove share int share_file(int dev, int inode, int open_mode, int action)
* 1 : add_ro_r_share /* open_mode is the same as 'access' in file_creat_open():
* 4 : add_ro_w_share * 0x001 = open for read
* * 0x002 = open for write
* 2 : add_wr_r_share * 0x004 = deny read
* 8 : add_wr_w_share * 0x008 = deny write
* ----
* 0x10 : test ********* 0x010 = compatible mode
* next are 'open_modes' by nw_log_file() routine.
* 0x100 = file lock ( normally exclusive )
* 0x200 = file lock shared ro flag
* action:
* 0 = remove
* 1 = add
* 2 = only test
*/ */
{ {
int k = count_sh_op_dev; ShareDev *sd = NULL, **psd;
int fr = -1; ShareINode *si = NULL, **psi;
int fo = -1; int result = 0, act_mode = 0;
int result = -1;
SH_OP_DEV *sod;
struct flock flockd; struct flock flockd;
char tbuf[200];
sprintf(tbuf,"dev=0x%x,inode=%d,open_mode=0x%x,action=%d",
dev, inode, open_mode, action);
while (k--) { if (open_mode==0) {
sod=&(sh_op_devs[k]); XDPRINTF((1, 0, "Wrong openmode in share_file %s", tbuf));
if (sod->fd_r < 0) { return(-1);
fr=k; }
} else if (sod->dev == dev) {
fo=k; #if 0
/* mst: 06-Apr-00, map compatible modes */
/* mst: 13-Apr-00 removed */
if (access & 0x10) {
if (!(acces&2)) { /* readonly */
if (entry31_flags&1)
access &= ~0x10;
} else {
if (entry31_flags&2) {
access &= ~0x10;
access |= 0x8;
}
}
}
#endif
/* look for open device */
for (psd=&first_dev; *psd; psd=&(*psd)->next) {
if ((*psd)->dev == dev) {
sd = *psd;
break;
}
}
if (action==0 && !sd) {
XDPRINTF((1, 0, "Could not find share device to remove %s", tbuf));
return(-1);
}
if (!sd) {
/* new device */
sd = (ShareDev*) xcmalloc( sizeof(ShareDev) );
if (!sd) {
XDPRINTF((1, 0, "Could not allocate new share device %s", tbuf));
return(-1);
}
sd->next = *psd;
*psd = sd;
sd->first_inode = NULL;
sd->fd_sm = -1;
sd->dev = dev;
}
/* look for open inode */
for (psi=&sd->first_inode; *psi; psi=&(*psi)->next) {
if ((*psi)->inode == inode) {
si = *psi;
break; break;
} }
} }
if ((!sh_mode) && fo==-1) { if (action==0 && !si) {
XDPRINTF((1, 0, "Could not found share to remove")); XDPRINTF((1, 0, "Could not find share inode to remove %s", tbuf));
if (!sd->first_inode) {
*psd = sd->next;
xfree( sd );
}
return(-1); return(-1);
} }
if (fo==-1 && fr==-1) { if (!si) {
if (count_sh_op_dev < MAX_SH_OP_DEV) /* new inode */
fr=count_sh_op_dev++; si = (ShareINode*) xcmalloc( sizeof(ShareINode) );
else { if (!si) {
XDPRINTF((1, 0, "Too much 'share devs'")); XDPRINTF((1, 0, "Could not allocate new share inode %s", tbuf));
if (!sd->first_inode) {
*psd = sd->next;
xfree( sd );
}
return(-1);
}
si->next = *psi;
*psi = si;
si->first_lock = NULL;
si->inode = inode;
}
if (sd->fd_sm == -1) {
/* open share files */
char buff[300];
int l;
if (NULL==path_share_lock_files) {
/* get path for share files */
if (get_ini_entry(NULL, 41, buff, sizeof(buff)) && *buff)
new_str(path_share_lock_files, buff);
else
new_str(path_share_lock_files, "/var/spool/nwserv/.locks");
seteuid(0);
unx_xmkdir(path_share_lock_files, 0755);
} else
seteuid(0);
l=sprintf(buff, "%s/%x.sm", path_share_lock_files, dev);
sd->fd_sm = open(buff, O_RDWR|O_CREAT, 0600);
#if 0
buff[l-2]='c';
sd->fd_cm = open(buff, O_RDWR|O_CREAT, 0600);
#endif
buff[l-2]='o'; buff[l-1]='r';
sd->fd_or = open(buff, O_RDWR|O_CREAT, 0600);
buff[l-2]='d';
sd->fd_dr = open(buff, O_RDWR|O_CREAT, 0600);
buff[l-1]='w';
sd->fd_dw = open(buff, O_RDWR|O_CREAT, 0600);
buff[l-2]='o';
sd->fd_ow = open(buff, O_RDWR|O_CREAT, 0600);
/* lock file */
buff[l-2]='f'; buff[l-1]='l';
sd->fd_fl = open(buff, O_RDWR|O_CREAT, 0600);
reseteuid();
if (sd->fd_sm<0 || sd->fd_or<0 || sd->fd_dr<0 ||
sd->fd_ow<0 || sd->fd_dw<0
#if 0
|| sd->fd_cm<0
#endif
|| sd->fd_fl<0
)
{
if (sd->fd_sm>-1) close(sd->fd_sm);
if (sd->fd_or>-1) close(sd->fd_or);
if (sd->fd_dr>-1) close(sd->fd_dr);
if (sd->fd_ow>-1) close(sd->fd_ow);
if (sd->fd_dw>-1) close(sd->fd_dw);
#if 0
if (sd->fd_cm>-1) close(sd->fd_cm);
#endif
if (sd->fd_fl>-1) close(sd->fd_fl);
xfree( si );
*psd = sd->next;
xfree( sd );
buff[l-2]='\0';
XDPRINTF((1, 0, "Cannot open sharefile=`%s`", buff));
return(-1); return(-1);
} }
} }
@ -87,79 +243,470 @@ int share_file(int dev, int inode, int sh_mode)
flockd.l_start = inode; flockd.l_start = inode;
flockd.l_len = 1; flockd.l_len = 1;
if (!sh_mode) { flockd.l_type = F_WRLCK;
sod=&(sh_op_devs[fo]); fcntl(sd->fd_sm, F_SETLKW, &flockd); /* set semaphor */
if (action==1 || action==2) { /* TEST */
if (si->or ) act_mode |= 0x01;
if (si->ow ) act_mode |= 0x02;
if (si->dr ) act_mode |= 0x04;
if (si->dw ) act_mode |= 0x08;
#if 0
if (si->cm ) act_mode |= 0x10;
#endif
if (si->fl ) act_mode |= 0x100;
if (si->ex ) act_mode |= 0x200;
if (open_mode & 0xff) {
if (!(act_mode & 0x01)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_or, F_GETLK, &flockd); /* read */
if (flockd.l_type != F_UNLCK)
act_mode |= 0x01;
}
if (!(act_mode & 0x04)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_dr, F_GETLK, &flockd); /* deny read */
if (flockd.l_type != F_UNLCK)
act_mode |= 0x04;
}
if (!(act_mode & 0x02)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_ow, F_GETLK, &flockd); /* write */
if (flockd.l_type != F_UNLCK)
act_mode |= 0x02;
}
if (!(act_mode & 0x08)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_dw, F_GETLK, &flockd); /* deny write */
if (flockd.l_type != F_UNLCK)
act_mode |= 0x08;
}
#if 0
if (!(act_mode & 0x10)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_cm, F_GETLK, &flockd); /* compatible mode */
if (flockd.l_type != F_UNLCK)
act_mode |= 0x10;
}
#endif
}
if ((open_mode & 0x300) && !(act_mode & 0x100)) {
flockd.l_type = F_WRLCK;
fcntl(sd->fd_fl, F_GETLK, &flockd); /* lock file */
if (flockd.l_type != F_UNLCK)
act_mode |= (flockd.l_type == F_WRLCK) ? 0x100|0x200 : 0x100;
}
if (act_mode & 0xff) { // already opened by other
#if 0 /* mst:13-Apr-00, I think this is all NOT needed. */
if (entry8_flags & 0x100) { /* dos ? mode */
if ( (open_mode & 0x10) ? !(act_mode & 0x10) && (act_mode & 0x06) :
(act_mode & 0x10) && (open_mode & 0x06))
result=-1;
} else { /* Standard Novell mode mode, i hope */
if ((open_mode & 0x10) != (act_mode & 0x10))
result = -1; /* if one file opened compatible then all files
must be opened compatible */
#if 0
else if ( (!(act_mode & 0xc)) && (open_mode & 0xc) )
result = -1; /* already opened DENYNO but now DENYXY wanted */
#endif
}
#endif
if (!result && (((open_mode & 0x01) && (act_mode & 0x04)) ||
((open_mode & 0x02) && (act_mode & 0x08)) ||
((open_mode & 0x04) && (act_mode & 0x01)) ||
((open_mode & 0x08) && (act_mode & 0x02))))
result=-1;
}
if (!result && /* lock file */
(((open_mode & 0x100) && (act_mode & 0x200)) ||
((open_mode & 0x200) && (act_mode & 0x100))))
result = -1;
if (action==1 && !result) { /* ADD */
if (open_mode & 0x01) { /* read */
if (!si->or) {
flockd.l_type = F_RDLCK;
fcntl(sd->fd_or, F_SETLK, &flockd);
}
si->or ++;
}
if (open_mode & 0x04) { /* deny read */
if (!si->dr) {
flockd.l_type = F_RDLCK;
fcntl(sd->fd_dr, F_SETLK, &flockd);
}
si->dr ++;
}
if (open_mode & 0x02) { /* write */
if (!si->ow) {
flockd.l_type = F_RDLCK;
fcntl(sd->fd_ow, F_SETLK, &flockd);
}
si->ow ++;
}
if (open_mode & 0x08) { /* deny write */
if (!si->dw) {
flockd.l_type = F_RDLCK;
fcntl(sd->fd_dw, F_SETLK, &flockd);
}
si->dw ++;
}
#if 0
if (open_mode & 0x10) { /* compatible mode */
if (!si->cm) {
flockd.l_type = F_RDLCK;
fcntl(sd->fd_cm, F_SETLK, &flockd);
}
si->cm ++;
}
#endif
if (open_mode & 0x100) { /* lock file */
if (!si->fl) {
flockd.l_type = (open_mode & 0x200) ? F_RDLCK : F_WRLCK;
fcntl(sd->fd_fl, F_SETLK, &flockd);
}
si->fl ++;
if (!(open_mode & 0x200)) /* exclusive */
si->ex ++;
}
}
} else if (action==0) { /* REMOVE */
flockd.l_type = F_UNLCK; flockd.l_type = F_UNLCK;
(void)fcntl(sod->fd_r, F_SETLK, &flockd); if (open_mode & 0x01) /* read */
(void)fcntl(sod->fd_wr, F_SETLK, &flockd); if (si->or && !(--si->or))
if (--sod->in_use < 1) { fcntl(sd->fd_or, F_SETLK, &flockd);
close(sod->fd_r); if (open_mode & 0x04) /* deny read */
close(sod->fd_wr); if (si->dr && !(--si->dr))
sod->fd_r = -1; fcntl(sd->fd_dr, F_SETLK, &flockd);
sod->fd_wr = -1; if (open_mode & 0x02) /* write */
sod->dev = -1; if (si->ow && !(--si->ow))
fcntl(sd->fd_ow, F_SETLK, &flockd);
if (open_mode & 0x08) /* deny write */
if (si->dw && !(--si->dw))
fcntl(sd->fd_dw, F_SETLK, &flockd);
#if 0
if (open_mode & 0x10) /* compatible mode */
if (si->cm && !(--si->cm))
fcntl(sd->fd_cm, F_SETLK, &flockd);
#endif
if (open_mode & 0x100) /* file lock */
if (si->fl && !(--si->fl)) {
fcntl(sd->fd_fl, F_SETLK, &flockd);
si->ex = 0;
} }
} else {
if (fo == -1) {
char buff[300];
int l;
sod=&(sh_op_devs[fr]);
if (NULL==path_share_lock_files) {
if (get_ini_entry(NULL, 41, buff, sizeof(buff)) && *buff)
new_str(path_share_lock_files, buff);
else
new_str(path_share_lock_files, "/var/spool/nwserv/.locks");
seteuid(0);
unx_xmkdir(path_share_lock_files, 0755);
reseteuid();
} }
l=sprintf(buff, "%s/%x.r", path_share_lock_files, dev); flockd.l_type = F_UNLCK;
seteuid(0); fcntl(sd->fd_sm, F_SETLK, &flockd); /* realise semaphor */
if (-1 < (sod->fd_r=open(buff, O_RDWR|O_CREAT, 0600)) ) {
buff[l-1]='w';
if (0 > (sod->fd_wr=open(buff, O_RDWR|O_CREAT, 0600) )){
close(sod->fd_r);
sod->fd_r=-1;
}
}
reseteuid();
if (sod->fd_r < 0) { if (!si->or && !si->ow && !si->dr && !si->dw
XDPRINTF((1, 0, "Cannot open sharefile=`%s`", buff)); #if 0
return(-1); && !si->cm
#endif
&& !si->fl ) {
/* release inode */
while (si->first_lock) {
ShareLock *p = si->first_lock;
si->first_lock = p->next;
xfree( p );
} }
sod->dev = dev; *psi = si->next;
xfree( si );
}
if (!sd->first_inode) {
/* release device */
close(sd->fd_sm);
close(sd->fd_or);
close(sd->fd_ow);
close(sd->fd_dr);
close(sd->fd_dw);
#if 0
close(sd->fd_cm);
#endif
close(sd->fd_fl);
*psd = sd->next;
xfree( sd );
}
XDPRINTF((3, 0, "share_file result=%d %s,act_mode=%x", result, tbuf, act_mode));
return(result);
}
static int _get_inode( int dev, int inode, ShareDev **psd, ShareINode **psi )
{
for (*psd=first_dev; *psd; *psd=(*psd)->next)
if ((*psd)->dev == dev)
break;
if (!*psd)
return 0;
for (*psi=(*psd)->first_inode; *psi; *psi=(*psi)->next)
if ((*psi)->inode == inode)
return 1;
return 0;
}
int share_lock( int dev, int inode, int fd, int action,
int lock_flag, int l_start, int l_len )
/*
* action:
* 0 = unlock
* 1 = lock
* 2 = testonly
*
* lock_flag:
* <0 = unlock
* 1 = exclusive
* 3 = shared ro
*/
{
ShareDev *sd;
ShareINode *si;
ShareLock *sl = NULL, **psl;
int result = 0;
struct flock flockd;
char tbuf[200];
sprintf(tbuf,"dev=0x%x,inode=%d,fd=%d,action=%d,lock_flag=%d",
dev, inode, fd, action, lock_flag);
if (!_get_inode( dev, inode, &sd, &si )) {
XDPRINTF((1, 0, "Could not find share for lock %s", tbuf));
return -1;
}
flockd.l_whence = SEEK_SET;
flockd.l_start = l_start;
flockd.l_len = l_len;
/* find lock */
for (psl=&si->first_lock; *psl; psl=&(*psl)->next) {
if ((*psl)->l_start < l_start + l_len
|| (!l_len && (*psl)->l_start <= l_start)) {
sl = *psl;
break;
}
}
if (!action) {
/* unlock */
if (sl && sl->fd == fd && sl->l_start == l_start && sl->l_len == l_len) {
flockd.l_type = F_UNLCK;
fcntl( fd, F_SETLK, &flockd );
*psl = sl->next;
xfree( sl );
} else } else
sod=&(sh_op_devs[fo]); result = -1;
if (!(sh_mode&0x10)){
if (sh_mode & 1) {
flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK;
result=fcntl(sod->fd_r, F_SETLK, &flockd);
} else result=0;
if ((!result) && (sh_mode & 2) ) {
flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK;
result=fcntl(sod->fd_wr, F_SETLK, &flockd);
}
if (result) {
XDPRINTF((3, 0, "Cannot lock share sh_mode=%d", sh_mode));
} else { } else {
sod->in_use++; /* lock or test */
if (sl && (l_start < sl->l_start + sl->l_len || !sl->l_len)
&& (sl->exclusive || lock_flag == 1) )
result = -1; /* collision */
else {
flockd.l_type = (lock_flag == 1) ? F_WRLCK : F_RDLCK;
result = fcntl( fd, (action==1) ? F_SETLK : F_GETLK, &flockd );
if (!result) {
if (action == 1) {
/* add to list */
sl = (ShareLock*) xmalloc( sizeof(ShareLock) );
sl->next = *psl;
*psl = sl;
sl->l_start = l_start;
sl->l_len = l_len;
sl->fd = fd;
sl->exclusive = (lock_flag == 1) ? 1 : 0;
} else
if (flockd.l_type != F_UNLCK)
result = -1;
} }
} else { /* only testing */
if (sh_mode & 1) {
flockd.l_type = (sh_mode & 4) ? F_WRLCK : F_RDLCK;
result=fcntl(sod->fd_r, F_GETLK, &flockd);
} else if (sh_mode & 2) {
flockd.l_type = (sh_mode & 8) ? F_WRLCK : F_RDLCK;
result=fcntl(sod->fd_wr, F_GETLK, &flockd);
} else result=-1;
return(flockd.l_type == F_UNLCK) ? 0 : -1;
} }
} }
XDPRINTF((3, 0, "share_lock result=%d %s", result, tbuf));
return result;
}
int share_unlock_all( int dev, int inode, int fd )
{
ShareDev *sd;
ShareINode *si;
ShareLock **psl;
int result = 0;
struct flock flockd;
char tbuf[200];
sprintf(tbuf,"dev=0x%x,inode=%d,fd=%d", dev, inode, fd);
if (!_get_inode( dev, inode, &sd, &si )) {
XDPRINTF((1, 0, "Could not find share for unlock_all %s", tbuf));
return -1;
}
flockd.l_type = F_UNLCK;
flockd.l_whence = SEEK_SET;
for (psl=&si->first_lock; *psl; ) {
if ((*psl)->fd == fd) {
ShareLock *sl = *psl;
flockd.l_start = sl->l_start;
flockd.l_len = sl->l_len;
fcntl( fd, F_SETLK, &flockd );
*psl = sl->next;
xfree( sl );
} else
psl=&(*psl)->next;
}
XDPRINTF((3, 0, "share_unlock_all,result=%d %s", result, tbuf));
return result;
}
typedef struct S_SHARESET{
int type;
int lock_flag;
int timeout; /* not used yet */
int locked; /* is entry locked */
int dev;
int inode;
int datalen;
char *data; /* used for Logical Records */
struct S_SHARESET *next;
} SHARESET;
static SHARESET *first_set = NULL;
static int lock_unlock_pset(SHARESET *ps, int lock_flag)
{
int result;
switch (ps->type)
{
case 1: /* file share */
if (lock_flag>-1)
result = share_file(ps->dev, ps->inode,
lock_flag ? lock_flag
: (ps->lock_flag
? ps->lock_flag
: 1),
1);
else
result = share_file(ps->dev, ps->inode, 0x300, 0);
break;
case 2: /* logical records */
if (lock_flag>-1)
result = nw_log_logical_record(
lock_flag ? lock_flag
: (ps->lock_flag
? ps->lock_flag
: 1),
ps->timeout, /* timeout not used yet */
ps->datalen,
ps->data);
else
result = nw_log_logical_record(
-1,
ps->timeout, /* timeout not used yet */
ps->datalen,
ps->data);
break;
default :
result = -1;
}
return(result); return(result);
} }
int share_set_file_add_rm(int lock_flag, int dev, int inode)
{
if (lock_flag > -1) {
SHARESET *ps = (SHARESET*)xcmalloc(sizeof(SHARESET));
ps->next = first_set;
first_set = ps;
ps->dev = dev;
ps->inode = inode;
ps->lock_flag = lock_flag;
} else if (lock_flag == -2) {
SHARESET **pset = &first_set;
while (*pset) {
SHARESET *ps = *pset;
*pset = (*pset)->next;
if (1 == ps->type) {
xfree(ps);
}
}
}
return(0);
}
int share_set_logrec_add_rm(int lock_flag, int timeout, int len, char *data)
{
if (lock_flag > -1) {
SHARESET *ps = (SHARESET*)xcmalloc(sizeof(SHARESET));
ps->next = first_set;
first_set = ps;
ps->datalen = len;
ps->data = xcmalloc(len+1);
memcpy(ps->data, data, len);
ps->lock_flag = lock_flag;
} else if (lock_flag == -2) {
SHARESET **pset = &first_set;
while (*pset) {
SHARESET *ps = *pset;
*pset = (*pset)->next;
if (2 == ps->type) {
xfree(ps->data);
xfree(ps);
}
}
}
return(0);
}
int share_handle_lock_sets(int type, int lock_flag, int timeout)
/* type:
* 1 = file share
* 2 = logical record
*
* lock_flag:
* -2 = clear (delete) set
* -1 = release (unshare/unlock) set
* 0/1/3 = lock/share set
*
* timeout: not used yet. !!
*/
{
SHARESET **pset = &first_set;
while (*pset) {
SHARESET *ps = *pset;
*pset = (*pset)->next;
if (type & ps->type) {
if (ps->locked && (lock_flag < 0)) {
if (!lock_unlock_pset(ps, -1))
ps->locked = 0;
} else if ((!ps->locked) && lock_flag > -1){
if (lock_unlock_pset(ps, lock_flag)){
/* remove all locks */
share_handle_lock_sets(type, -1, 0);
return(-1);
} else
ps->locked = 1;
}
if (lock_flag == -2) { /* remove node */
xfree(ps->data);
xfree(ps);
}
}
}
return(0);
}

View File

@ -1,8 +1,17 @@
/* nwshare.h: 20-Jul-97*/ /* nwshare.h: 25-Sep-99*/
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-1999 Martin Stover, Marburg, Germany
*/ */
#ifndef _NWSHARE_H_ #ifndef _NWSHARE_H_
#define _NWSHARE_H_ 1 #define _NWSHARE_H_ 1
extern int share_file(int dev, int inode, int sh_mode); /* changed by: Ingmar Thiemann <ingmar@gefas.com> */
extern int share_file(int dev, int inode, int open_mode, int action);
extern int share_lock( int dev, int inode, int fd, int action,
int lock_flag, int l_start, int l_len );
extern int share_unlock_all( int dev, int inode, int fd );
extern int share_set_file_add_rm(int lock_flag, int dev, int inode);
extern int share_set_logrec_add_rm(int lock_flag, int timeout, int len, char *data);
extern int share_handle_lock_sets(int type, int lock_flag, int timeout);
#endif #endif

View File

@ -1,5 +1,5 @@
/* nwvolume.c 01-Feb-98 */ /* nwvolume.c 09-Oct-99 */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-1999 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,14 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <sys/vfs.h>
#ifdef FREEBSD
# include <sys/param.h>
# include <sys/mount.h>
#else
# include <sys/vfs.h>
#endif
#include <pwd.h>
#ifndef LINUX #ifndef LINUX
#include <sys/statvfs.h> #include <sys/statvfs.h>
@ -30,8 +37,12 @@
#include <utime.h> #include <utime.h>
#include "nwfname.h" #include "nwfname.h"
#include "nwattrib.h"
#include "trustee.h"
#include "nwvolume.h" #include "nwvolume.h"
#define VOLOPTIONS_DEFAULT VOL_OPTION_ATTRIBUTES
NW_VOL *nw_volumes=NULL; NW_VOL *nw_volumes=NULL;
int used_nw_volumes=0; int used_nw_volumes=0;
int loaded_namespaces=0; int loaded_namespaces=0;
@ -39,9 +50,45 @@ uint8 *home_dir=NULL;
int home_dir_len=0; int home_dir_len=0;
char *path_vol_inodes_cache=NULL; char *path_vol_inodes_cache=NULL;
char *path_attributes=NULL; char *path_attributes=NULL;
char *path_trustees=NULL;
static int max_nw_vols=MAX_NW_VOLS; static int max_nw_vols=MAX_NW_VOLS;
static void free_vol_trustee(NW_VOL *vol)
{
if (vol) {
while(vol->count_trustees-- > 0){
VOLUME_TRUSTEE *vt=vol->trustees+vol->count_trustees;
xfree(vt->path);
}
xfree(vol->trustees);
vol->count_trustees=0;
vol->max_alloc_trustees=0;
vol->trustee_id=0L;
vol->trustee_last_test_time=0;
}
}
static void add_vol_trustee(NW_VOL *vol, uint8 *path, int len, int trustee)
{
VOLUME_TRUSTEE *vt;
if (vol->count_trustees == vol->max_alloc_trustees) {
vol->max_alloc_trustees += 3;
vt=(VOLUME_TRUSTEE*)xcmalloc(sizeof(VOLUME_TRUSTEE) * vol->max_alloc_trustees);
if (vol->count_trustees) {
memcpy(vt, vol->trustees, sizeof(VOLUME_TRUSTEE)*vol->count_trustees);
}
xfree(vol->trustees);
vol->trustees=vt;
}
vt=vol->trustees+vol->count_trustees++;
vt->trustee=trustee;
vt->path=xmalloc(len+1);
vt->len=len;
memcpy(vt->path, path, len);
*(vt->path+len)='\0';
}
static void volume_to_namespace_map(int volume, NW_VOL *vol) static void volume_to_namespace_map(int volume, NW_VOL *vol)
{ {
struct stat statb; struct stat statb;
@ -50,6 +97,8 @@ static void volume_to_namespace_map(int volume, NW_VOL *vol)
XDPRINTF((1, 0, "cannot stat vol=%d, `%s`", volume, vol->unixname)); XDPRINTF((1, 0, "cannot stat vol=%d, `%s`", volume, vol->unixname));
return; return;
} }
vol->dev = statb.st_dev;
vol->inode = statb.st_ino;
dnm.dev = statb.st_dev; dnm.dev = statb.st_dev;
dnm.namespace = 0; /* NAMESPACE DOS */ dnm.namespace = 0; /* NAMESPACE DOS */
(void) nw_vol_inode_to_handle(volume, statb.st_ino, &dnm); (void) nw_vol_inode_to_handle(volume, statb.st_ino, &dnm);
@ -77,13 +126,15 @@ void nw_init_volumes(FILE *f)
while (++i < nw_volumes[k].maps_count) while (++i < nw_volumes[k].maps_count)
xfree(nw_volumes[k].dev_namespace_maps[i]); xfree(nw_volumes[k].dev_namespace_maps[i]);
nw_volumes[k].maps_count = 0; nw_volumes[k].maps_count = 0;
free_vol_trustee(&nw_volumes[k]);
} }
} }
rewind(f); rewind(f);
used_nw_volumes = 0; used_nw_volumes = 0;
loaded_namespaces = 0; loaded_namespaces = 0;
new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache"); new_str(path_vol_inodes_cache, "/var/spool/nwserv/.volcache");
new_str(path_attributes, "/var/lib/nwserv/attrib"); new_str(path_attributes, "/var/nwserv/attrib");
new_str(path_trustees, "/var/nwserv/trustees");
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) {
if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){ if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){
uint8 sysname[256]; uint8 sysname[256];
@ -97,14 +148,14 @@ void nw_init_volumes(FILE *f)
sysname, unixname, optionstr, umode_dirstr, umode_filestr); sysname, unixname, optionstr, umode_dirstr, umode_filestr);
if (founds > 1) { if (founds > 1) {
NW_VOL *vol=&(nw_volumes[used_nw_volumes]); NW_VOL *vol=&(nw_volumes[used_nw_volumes]);
vol->options = VOL_NAMESPACE_DOS; vol->options = VOLOPTIONS_DEFAULT;
vol->options |= VOL_NAMESPACE_DOS;
loaded_namespaces |= VOL_NAMESPACE_DOS; loaded_namespaces |= VOL_NAMESPACE_DOS;
up_fn(sysname); up_fn(sysname);
new_str(vol->sysname, sysname); new_str(vol->sysname, sysname);
len = strlen((char*)unixname); len = strlen((char*)unixname);
if (unixname[0] == '~' && (unixname[1]=='\0' || unixname[1]=='/')) { if (unixname[0] == '~' && (unixname[1]=='\0' || unixname[1]=='/')) {
vol->options |= VOL_OPTION_IS_HOME; vol->options |= VOL_OPTION_IS_HOME;
vol->options |= VOL_OPTION_REMOUNT;
if (len > 2) { /* tail is present */ if (len > 2) { /* tail is present */
if (unixname[len-1] != '/') { if (unixname[len-1] != '/') {
unixname[len++] = '/'; unixname[len++] = '/';
@ -135,6 +186,10 @@ void nw_init_volumes(FILE *f)
|= VOL_OPTION_DOWNSHIFT; |= VOL_OPTION_DOWNSHIFT;
break; break;
case 'n' : vol->options
|= VOL_OPTION_NO_INODES;
break;
case 'm' : vol->options case 'm' : vol->options
|= VOL_OPTION_REMOUNT; |= VOL_OPTION_REMOUNT;
break; break;
@ -151,6 +206,15 @@ void nw_init_volumes(FILE *f)
|= VOL_OPTION_READONLY; |= VOL_OPTION_READONLY;
break; break;
case 't' : vol->options
|= VOL_OPTION_TRUSTEES;
break;
case 'T' : /* option added by Norbert Nemec <nobbi@cheerful.com> */
vol->options
|= (VOL_OPTION_TRUSTEES | VOL_OPTION_IGNUNXRIGHT);
break;
case 'O' : vol->options case 'O' : vol->options
|= VOL_NAMESPACE_OS2; |= VOL_NAMESPACE_OS2;
loaded_namespaces |= VOL_NAMESPACE_OS2; loaded_namespaces |= VOL_NAMESPACE_OS2;
@ -180,76 +244,70 @@ void nw_init_volumes(FILE *f)
vol->max_maps_count = MAX_DEV_NAMESPACE_MAPS; vol->max_maps_count = MAX_DEV_NAMESPACE_MAPS;
vol->high_inode = 0xfffffff; vol->high_inode = 0xfffffff;
} }
if (vol->unixnamlen) if (vol->unixnamlen)
volume_to_namespace_map(used_nw_volumes-1, vol); volume_to_namespace_map(used_nw_volumes-1, vol);
/* few checks */
if (vol->options & VOL_OPTION_IS_HOME) {
vol->options |= VOL_OPTION_REMOUNT;
}
if (vol->options & VOL_OPTION_NO_INODES) {
vol->options &= ~VOL_OPTION_TRUSTEES;
vol->options &= ~VOL_OPTION_IGNUNXRIGHT;
vol->options &= ~VOL_OPTION_ATTRIBUTES;
}
MDEBUG(D_ACCESS, {
xdprintf(1,0,"init vol:=%d(%s),ud=0%o,uf=0%o, opt=0x%4x",
used_nw_volumes-1, vol->sysname,
vol->umode_dir, vol->umode_file, vol->options);
})
} }
} else if (what==40) { /* path for vol/dev/inode->path cache */ } else if (what==40) { /* path for vol/dev/inode->path cache */
new_str(path_vol_inodes_cache, buff); new_str(path_vol_inodes_cache, buff);
} else if (what==46) { /* path for attribute handling */ } else if (what==46) { /* path for attribute handling */
new_str(path_attributes, buff); new_str(path_attributes, buff);
} else if (what==47) { /* path for trustees handling */
new_str(path_trustees, buff);
} }
} /* while */ } /* while */
} }
void nw_setup_home_vol(int len, uint8 *fn) static int get_unx_home_dir(uint8 *homedir, uint8 *unxlogin)
/* searches for UNIX homedir of actual unxlogin name */
{ {
int k=used_nw_volumes; struct passwd *pw;
uint8 unixname[258]; int len=0;
uint8 fullname[258]; endpwent();
if (unxlogin && *unxlogin && NULL != (pw=getpwnam(unxlogin))) {
unixname[0] = '\0'; len=strlen(pw->pw_dir);
xfree(home_dir); if (!len) {
home_dir_len=0; *homedir++ = '/';
if (len > 0) { *homedir = '\0';
strmaxcpy(unixname, fn, len); len =1;
if (unixname[len-1] != '/') {
unixname[len++] = '/';
unixname[len] = '\0';
}
new_str(home_dir, unixname);
home_dir_len=len;
}
while (k--) { /* now set all HOME volumes */
uint8 *fname;
int flen;
if (nw_volumes[k].options & VOL_OPTION_IS_HOME) {
int i = -1;
while (++i < nw_volumes[k].maps_count)
xfree(nw_volumes[k].dev_namespace_maps[i]);
nw_volumes[k].maps_count = 0;
fname = unixname;
flen = len;
if (len > 0 && nw_volumes[k].addonlen) {
if (len + nw_volumes[k].addonlen > 256) {
flen = 0;
fname = "";
} else { } else {
strcpy(fullname, unixname); if (len > 255) len=255;
/* concatenation $HOME/ and add/on/ */ strmaxcpy(homedir, pw->pw_dir, len);
strcpy(fullname + len, nw_volumes[k].homeaddon);
fname = fullname;
flen = len + nw_volumes[k].addonlen;
}
}
nw_volumes[k].unixnamlen = flen;
new_str(nw_volumes[k].unixname, fname);
if (flen>0)
volume_to_namespace_map(k, &(nw_volumes[k]));
} }
} else {
*homedir='\0';
} }
endpwent();
return(len);
} }
void nw_setup_vol_opts(int act_gid, int act_uid, void nw_setup_vol_opts(int act_gid, int act_uid,
int act_umode_dir, int act_umode_file, int act_umode_dir, int act_umode_file,
int homepathlen, uint8 *homepath) uint8 *unxlogin)
/* set's homevolume and volume's umodes */ /* set's homevolume and volume's umodes */
{ {
int k=used_nw_volumes; int k=used_nw_volumes;
uint8 unixname[258]; uint8 unixname[258];
uint8 fullname[258]; uint8 fullname[258];
uint8 homepath[258];
int homepathlen=get_unx_home_dir(homepath, unxlogin);
unixname[0] = '\0'; unixname[0] = '\0';
xfree(home_dir); xfree(home_dir);
home_dir_len=0; home_dir_len=0;
@ -263,26 +321,30 @@ void nw_setup_vol_opts(int act_gid, int act_uid,
home_dir_len=homepathlen; home_dir_len=homepathlen;
} }
while (k--) { /* now set all HOME volumes */ while (k--) {
uint8 *fname; uint8 *fname;
int flen; int flen;
if (nw_volumes[k].options & VOL_OPTION_IS_HOME) { if (nw_volumes[k].options & VOL_OPTION_IS_HOME) {
/* now set HOME volumes */
int i = -1; int i = -1;
while (++i < nw_volumes[k].maps_count) while (++i < nw_volumes[k].maps_count)
xfree(nw_volumes[k].dev_namespace_maps[i]); xfree(nw_volumes[k].dev_namespace_maps[i]);
nw_volumes[k].maps_count = 0; nw_volumes[k].maps_count = 0;
fname = unixname; fname = unixname;
flen = homepathlen; flen = homepathlen;
#if 0 /* removed in 0.99.pl14, 03-Nov-98 */
nw_volumes[k].umode_dir = 0; nw_volumes[k].umode_dir = 0;
nw_volumes[k].umode_file = 0; nw_volumes[k].umode_file = 0;
#endif
if (homepathlen > 0 && nw_volumes[k].addonlen) { if (homepathlen > 0 && nw_volumes[k].addonlen) {
if (homepathlen + nw_volumes[k].addonlen > 256) { if (homepathlen + nw_volumes[k].addonlen > 256) {
flen = 0; flen = 0;
fname = ""; fname = "";
} else { } else {
strcpy(fullname, unixname); xstrcpy(fullname, unixname);
/* concatenation $HOME/ and add/on/ */ /* concatenation $HOME/ and add/on/ */
strcpy(fullname + homepathlen, nw_volumes[k].homeaddon); strmaxcpy(fullname + homepathlen, nw_volumes[k].homeaddon,
sizeof(fullname) - homepathlen - 1);
fname = fullname; fname = fullname;
flen = homepathlen + nw_volumes[k].addonlen; flen = homepathlen + nw_volumes[k].addonlen;
} }
@ -297,9 +359,7 @@ void nw_setup_vol_opts(int act_gid, int act_uid,
if (!nw_volumes[k].umode_file) if (!nw_volumes[k].umode_file)
nw_volumes[k].umode_file=act_umode_file; nw_volumes[k].umode_file=act_umode_file;
} }
} }
@ -387,13 +447,13 @@ int nw_get_volume_number(uint8 *volname, int namelen)
return(result); return(result);
} }
int nw_get_volume_name(int volnr, uint8 *volname) int nw_get_volume_name(int volnr, uint8 *volname, int size_volname)
/* returns < 0 if error, else len of volname */ /* returns < 0 if error, else len of volname */
{ {
int result = -0x98; /* Volume not exist */; int result = -0x98; /* Volume not exist */;
if (volnr > -1 && volnr < used_nw_volumes) { if (volnr > -1 && volnr < used_nw_volumes) {
if (volname != NULL) { if (volname != NULL) {
strcpy((char*)volname, (char*)nw_volumes[volnr].sysname); strmaxcpy((char*)volname, (char*)nw_volumes[volnr].sysname, size_volname-1);
result = strlen((char*)volname); result = strlen((char*)volname);
} else result= strlen((char*)nw_volumes[volnr].sysname); } else result= strlen((char*)nw_volumes[volnr].sysname);
} else { } else {
@ -413,14 +473,28 @@ int nw_get_volume_name(int volnr, uint8 *volname)
int get_volume_umode_dir(int volnr) int get_volume_umode_dir(int volnr)
{ {
return( (volnr > -1 && volnr < used_nw_volumes) ? if (volnr > -1 && volnr < used_nw_volumes) {
nw_volumes[volnr].umode_dir : 0); int result=nw_volumes[volnr].umode_dir;
MDEBUG(D_ACCESS, {
xdprintf(1,0,"get_d_umode vol:=%d(%s), result=0x%x",
volnr, nw_volumes[volnr].sysname, result);
})
return(result);
}
return(0);
} }
int get_volume_umode_file(int volnr) int get_volume_umode_file(int volnr)
{ {
return( (volnr > -1 && volnr < used_nw_volumes) ? if (volnr > -1 && volnr < used_nw_volumes) {
nw_volumes[volnr].umode_file : 0); int result=nw_volumes[volnr].umode_file;
MDEBUG(D_ACCESS, {
xdprintf(1,0,"get_f_umode vol:=%d(%s), result=0x%x",
volnr, nw_volumes[volnr].sysname, result);
})
return(result);
}
return(0);
} }
/* stolen from GNU-fileutils */ /* stolen from GNU-fileutils */
@ -468,12 +542,16 @@ fsd.f_bsize = 1024;
fsp->fsu_ffree = fsd.f_ffree; fsp->fsu_ffree = fsd.f_ffree;
if (limit) { if (limit) {
if (fsp->fsu_blocks > 4000000) if (fsp->fsu_blocks > 4000000) {
fsp->fsu_blocks = 4000000; fsp->fsu_blocks = 4000000;
if (fsp->fsu_bfree > 4000000) }
if (fsp->fsu_bfree > 4000000) {
fsp->fsu_bfree = 4000000; fsp->fsu_bfree = 4000000;
} }
if (fsp->fsu_bavail > 4000000) {
fsp->fsu_bavail = 4000000;
}
}
return(0); return(0);
} }
@ -507,6 +585,10 @@ int get_volume_inode(int volnr, struct stat *stb)
/* returns inode if OK, else errocode < 0 */ /* returns inode if OK, else errocode < 0 */
{ {
int result = -0x98; /* Volume not exist */; int result = -0x98; /* Volume not exist */;
if (stb) {
stb->st_mode=0;
stb->st_ino=0;
}
if (volnr > -1 && volnr < used_nw_volumes) { if (volnr > -1 && volnr < used_nw_volumes) {
struct stat statb; struct stat statb;
if (!stb) stb=&statb; if (!stb) stb=&statb;
@ -518,6 +600,137 @@ int get_volume_inode(int volnr, struct stat *stb)
return(result); return(result);
} }
int get_volume_unixnamlen(int volnr)
{
return( (volnr > -1 && volnr < used_nw_volumes)
? nw_volumes[volnr].unixnamlen
: 0 );
}
static void vol_trustee_scan(NW_VOL *v, int volume,
uint8 *trusteepath, uint8 *p, int size_p)
{
DIR *f;
*p='.';
*(p+1)='\0';
if (NULL != (f=opendir(trusteepath))) {
struct dirent* dirbuff;
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
if (dirbuff->d_ino
&& dirbuff->d_name[0] != 't'
&& dirbuff->d_name[0] != '.') {
struct stat stb;
strmaxcpy(p, dirbuff->d_name, size_p-1);
if (dirbuff->d_name[0] == 'n') {
uint8 path[255];
int l=readlink(trusteepath, path, 254);
if (l > 0) {
uint8 unixname[300];
memcpy(unixname, v->unixname, v->unixnamlen); /* first UNIXNAME VOLUME */
memcpy(unixname+v->unixnamlen, path, l);
unixname[l+v->unixnamlen]='\0';
XDPRINTF((2, 0, "vol_trustee_scan, trustee path=`%s`", unixname));
if (!stat(unixname, &stb)) {
int trustee=tru_get_id_trustee(volume, unixname, &stb,
v->trustee_id);
if (trustee > -1) {
if (!v->trustee_namespace) { /* DOS */
unix2doscharset(path);
up_fn(path);
}
add_vol_trustee(v, path, l, trustee);
XDPRINTF((2, 0, "trustee=0x%x found", trustee));
}
} else {
XDPRINTF((1, 0, "trustee path=`%s` not found",
unixname));
}
}
} else if ((!stat(trusteepath, &stb)) && S_ISDIR(stb.st_mode)) {
int l=strlen(p);
uint8 *pp = p+l;
*pp='/';
vol_trustee_scan(v, volume, trusteepath, pp+1, size_p - l -1);
}
}
}
closedir(f);
}
}
static void build_volume_user_trustee(int volume, uint32 id, int namespace)
{
NW_VOL *v=&(nw_volumes[volume]);
uint8 trusteepath[500];
uint8 *p;
free_vol_trustee(v);
xstrcpy(trusteepath, path_trustees);
p=trusteepath+strlen(trusteepath);
*p++='/';
strmaxcpy(p, v->sysname, sizeof(trusteepath) - (int)(p-trusteepath) -1);
p+=strlen(v->sysname);
*p++='/';
*p='\0';
v->trustee_id=id;
v->trustee_namespace=namespace;
vol_trustee_scan(v, volume, trusteepath, p,
sizeof(trusteepath) - (int) (p - trusteepath) );
}
int vol_trustees_were_changed(int volume)
{
NW_VOL *v=&(nw_volumes[volume]);
if (act_time > v->trustee_last_test_time+60) {
/* normally every minute */
unsigned int new_sernum=tru_vol_sernum(volume, 0);
if (v->trustee_sernum != new_sernum) {
free_vol_trustee(v);
tru_free_cache(volume);
v->trustee_sernum = new_sernum;
return(1);
}
v->trustee_last_test_time=act_time;
}
return(0);
}
int get_volume_user_trustee(int volume, uint32 id,
int namespace,
int *sequence,
int *trustee, uint8 *path)
{
NW_VOL *v=&(nw_volumes[volume]);
int seq=*sequence;
if (!(v->options & VOL_OPTION_TRUSTEES)) {
*path = 0;
*trustee = 0;
*sequence = 0;
return(0);
}
++*sequence;
if (vol_trustees_were_changed(volume) ||
!seq || id != v->trustee_id || namespace != v->trustee_namespace)
build_volume_user_trustee(volume, id, namespace);
if (seq < v->count_trustees) {
VOLUME_TRUSTEE *tr=v->trustees+seq++;
int l=strlen(v->sysname);
memcpy(path, v->sysname, l+1);
up_fn(path);
*(path+l++) =':';
if (tr->len && (tr->len > 1 || tr->path[0] != '.')){
memcpy(path+l, tr->path, tr->len);
l+=tr->len;
}
*(path+l) ='\0';
*trustee=tr->trustee;
return(l);
} else {
*path=0;
*trustee=0;
return(0);
}
}
#if QUOTA_SUPPORT #if QUOTA_SUPPORT
@ -561,11 +774,17 @@ const char *find_device_file(const char *path)
return(mount_device); return(mount_device);
} }
#include <time.h>
#include <sys/types.h>
#ifdef LINUX #ifdef LINUX
# ifndef QTAINSYS
# include <linux/quota.h> # include <linux/quota.h>
# else
# ifdef _GNU_SOURCE_
# include <asm/types.h>
# endif
# include <sys/quota.h>
# endif
# if defined(__alpha__) # if defined(__alpha__)
# include <errno.h> # include <errno.h>
# include <syscall.h> # include <syscall.h>

View File

@ -1,5 +1,5 @@
/* nwvolume.h 01-Feb-98 */ /* nwvolume.h 09-Oct-99 */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-1999 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -31,12 +31,22 @@ typedef struct {
* without loosing too many places. * without loosing too many places.
*/ */
typedef struct {
uint8 *path;
uint8 len;
int trustee;
} VOLUME_TRUSTEE;
typedef struct { typedef struct {
uint8 *sysname; /* VOL_NAME */ uint8 *sysname; /* VOL_NAME */
uint8 *unixname; /* UNIX-DIR with ending '/' */ uint8 *unixname; /* UNIX-DIR with ending '/' */
int unixnamlen; /* len of unixname */ int unixnamlen; /* len of unixname */
/* next 2 fields added by Andrew Sapozhnikov */ /* next 2 fields added by Andrew Sapozhnikov */
/* for Extend "Volume is home" feature */ /* for Extend "Volume is home" feature */
int dev; /* dev and inode of volume root */
int inode;
uint8 *homeaddon; /* tail for $HOME-relative volumes */ uint8 *homeaddon; /* tail for $HOME-relative volumes */
int addonlen; /* len of tail part of unixname */ int addonlen; /* len of tail part of unixname */
DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS]; DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS];
@ -48,6 +58,15 @@ typedef struct {
int umode_dir; /* umask/umode for creating dirs */ int umode_dir; /* umask/umode for creating dirs */
int umode_file; /* umask/umode for creating files */ int umode_file; /* umask/umode for creating files */
/* Trustee handling */
VOLUME_TRUSTEE *trustees;
int max_alloc_trustees;
int count_trustees;
uint32 trustee_id; /* id of last searched vol trustees */
int trustee_namespace;
unsigned int trustee_sernum;
time_t trustee_last_test_time; /* when did we test trustee sernum */
} NW_VOL; } NW_VOL;
/* vol options */ /* vol options */
@ -58,6 +77,10 @@ typedef struct {
#define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */ #define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */
#define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */ #define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */
#define VOL_OPTION_IGNCASE 0x0040 /* Do ignore up/downshift */ #define VOL_OPTION_IGNCASE 0x0040 /* Do ignore up/downshift */
#define VOL_OPTION_NO_INODES 0x0080 /* Volume do not have fixed inodes */
#define VOL_OPTION_TRUSTEES 0x0100 /* Volume use Trustees */
#define VOL_OPTION_ATTRIBUTES 0x0200 /* Volume use 'real' Attributes */
#define VOL_OPTION_IGNUNXRIGHT 0x0400 /* Ignore rights granted in UN*X FS */
/* namespaces */ /* namespaces */
#define VOL_NAMESPACE_DOS 0x1000 #define VOL_NAMESPACE_DOS 0x1000
@ -81,14 +104,15 @@ extern uint8 *home_dir;
extern int home_dir_len; extern int home_dir_len;
extern char *path_vol_inodes_cache; /* for namespace routines */ extern char *path_vol_inodes_cache; /* for namespace routines */
extern char *path_attributes; /* for attribute handling */ extern char *path_attributes; /* for attribute handling */
extern char *path_trustees; /* for trustee handling */
extern void nw_init_volumes(FILE *f); extern void nw_init_volumes(FILE *f);
extern void nw_setup_vol_opts(int act_gid, int act_uid, extern void nw_setup_vol_opts(int act_gid, int act_uid,
int act_umode_dir, int act_umode_file, int act_umode_dir, int act_umode_file,
int homepathlen, uint8 *homepath); uint8 *unxlogin);
extern void nw_setup_home_vol(int len, uint8 *fn);
extern int nw_get_volume_number(uint8 *volname, int namelen); extern int nw_get_volume_number(uint8 *volname, int namelen);
extern int nw_get_volume_name(int volnr, uint8 *volname); extern int nw_get_volume_name(int volnr, uint8 *volname, int size_volname);
extern int get_volume_umode_dir(int volnr); extern int get_volume_umode_dir(int volnr);
extern int get_volume_umode_file(int volnr); extern int get_volume_umode_file(int volnr);
@ -96,6 +120,8 @@ extern int get_volume_umode_file(int volnr);
extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu, int limit); extern int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu, int limit);
extern int get_volume_options(int volnr); extern int get_volume_options(int volnr);
extern int get_volume_inode(int volnr, struct stat *stb); extern int get_volume_inode(int volnr, struct stat *stb);
extern int get_volume_unixnamlen(int volnr);
extern int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota); extern int nw_set_vol_restrictions(uint8 volnr, int uid, uint32 quota);
extern int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse); extern int nw_get_vol_restrictions(uint8 volnr, int uid, uint32 *quota, uint32 *inuse);
@ -104,4 +130,12 @@ extern uint32 nw_vol_inode_to_handle(int volume, ino_t inode,
extern ino_t nw_vol_handle_to_inode(int volume, uint32 handle, extern ino_t nw_vol_handle_to_inode(int volume, uint32 handle,
DEV_NAMESPACE_MAP *dnm); DEV_NAMESPACE_MAP *dnm);
extern int vol_trustees_were_changed(int volume);
extern int get_volume_user_trustee(int volume, uint32 id,
int namespace,
int *sequence,
int *trustee, uint8 *path);
#endif #endif

182
tools.c
View File

@ -1,5 +1,5 @@
/* tools.c 08-Feb-98 */ /* tools.c 18-Apr-00 */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,22 +21,42 @@
#include <stdarg.h> #include <stdarg.h>
#include <syslog.h> #include <syslog.h>
#if 0
#ifndef LINUX #ifndef LINUX
extern int _sys_nerr;
extern char *_sys_errlist[];
#else
# ifndef __USE_GNU
# define _sys_nerr sys_nerr
# define _sys_errlist sys_errlist
# endif
#endif
#else
# ifndef __USE_GNU
# ifdef FREEBSD
# define _sys_nerr sys_nerr
# define _sys_errlist sys_errlist
# else
extern int _sys_nerr; extern int _sys_nerr;
extern char *_sys_errlist[]; extern char *_sys_errlist[];
# endif
# endif
#endif #endif
int nw_debug=0; int nw_debug=0;
uint32 debug_mask=0; /* special debug masks */ uint32 debug_mask=0; /* special debug masks */
static FILE *logfile=stderr; /* next are set and used by nwconn and nwbind processes */
int act_ncpsequence=0; /* for debugging */
int act_connection=0; /* which connection (nwconn, nwbind) */
time_t act_time=0L; /* actual time */
static FILE *logfile=NULL;
static int use_syslog=0; /* 1 = use syslog for all loggings static int use_syslog=0; /* 1 = use syslog for all loggings
* 2 = only for errors * 2 = only for errors
*/ */
static int in_module=0; /* in which process i am ? */ static int in_module=0; /* in which process i am ? */
static int connection=0; /* which connection (nwconn) */
static int my_pid = -1; static int my_pid = -1;
static void (*sigsegv_func)(int isig); static void (*sigsegv_func)(int isig);
static char *modnames[] = static char *modnames[] =
@ -54,14 +74,41 @@ static char *get_modstr(void)
return(modnames[in_module]); return(modnames[in_module]);
} }
static char *get_debstr(int with_time)
{
static char debuf[20];
if (with_time) {
time_t actualtime=time(NULL);
struct tm *ptm=localtime(&actualtime);
int l=strftime(debuf, sizeof(debuf)- 4, "%m.%d,%H:%M:%S ", ptm);
strmaxcpy(debuf+l, get_modstr(), 3);
} else {
sprintf(debuf, "%-8s" , get_modstr());
}
return(debuf);
}
char *xmalloc(uint size) char *xmalloc(uint size)
{ {
char *p = (size) ? (char *)malloc(size) : (char*)NULL; if (size) {
if (p == (char *)NULL && size){ char *p = (char *)malloc(size);
if (!p) {
int tries=0;
do {
sleep(1);
p = (char *)malloc(size);
} while (!p && tries++ < 10);
if (!p){
errorp(1, "xmalloc", "not enough core, need %d Bytes\n", size); errorp(1, "xmalloc", "not enough core, need %d Bytes\n", size);
exit(1); exit(1);
} else {
XDPRINTF((1, 0, "Warning:could not alloc %d Bytes for %d tries",
size, tries+1));
}
} }
return(p); return(p);
} else
return(NULL);
} }
char *xcmalloc(uint size) char *xcmalloc(uint size)
@ -139,7 +186,8 @@ static char *buffered=NULL;
} }
if (!(mode & 2)) { if (!(mode & 2)) {
char identstr[200]; char identstr[200];
sprintf(identstr, "%-8s %d", get_modstr(), connection); sprintf(identstr, "%s %d %3d", get_debstr(0),
act_connection, act_ncpsequence);
openlog(identstr, LOG_CONS, LOG_DAEMON); openlog(identstr, LOG_CONS, LOG_DAEMON);
syslog(LOG_DEBUG, buf); syslog(LOG_DEBUG, buf);
closelog(); closelog();
@ -151,7 +199,8 @@ static char *buffered=NULL;
xfree(buf); xfree(buf);
} else { } else {
if (!(mode & 1)) if (!(mode & 1))
fprintf(logfile, "%-8s %d:", get_modstr(), connection); fprintf(logfile, "%s %d %3d:", get_debstr(1),
act_connection, act_ncpsequence);
if (p) { if (p) {
va_start(ap, p); va_start(ap, p);
vfprintf(logfile, p, ap); vfprintf(logfile, p, ap);
@ -170,12 +219,14 @@ static char *buffered=NULL;
} }
void errorp(int mode, char *what, char *p, ...) void errorp(int mode, char *what, char *p, ...)
/* mode > 9 without errno printing */
/* mode == 1 || mode == 11 error = critical */
{ {
va_list ap; va_list ap;
int errnum = errno; int errnum = errno;
FILE *lologfile = logfile; FILE *lologfile = logfile;
char errbuf[200]; char errbuf[200];
char *errstr = errbuf; const char *errstr = errbuf;
if (mode > 9) { if (mode > 9) {
errnum = -1; errnum = -1;
mode -= 10; mode -= 10;
@ -196,7 +247,7 @@ void errorp(int mode, char *what, char *p, ...)
vsprintf(buf+l, p, ap); vsprintf(buf+l, p, ap);
va_end(ap); va_end(ap);
} }
sprintf(identstr, "%-8s %d", get_modstr(), connection); sprintf(identstr, "%s %d %3d", get_debstr(0), act_connection, act_ncpsequence);
openlog(identstr, LOG_CONS, LOG_DAEMON); openlog(identstr, LOG_CONS, LOG_DAEMON);
syslog(prio, buf); syslog(prio, buf);
closelog(); closelog();
@ -204,8 +255,11 @@ void errorp(int mode, char *what, char *p, ...)
lologfile=stderr; lologfile=stderr;
} }
while (1) { while (1) {
if (mode==1) fprintf(lologfile, "\n!! %-8s %d:PANIC !!\n", get_modstr(), connection); if (mode==1)
fprintf(lologfile, "%-8s %d:%s:%s\n", get_modstr(), connection, what, errstr); fprintf(lologfile, "\n!! %s %d %3d:PANIC !!\n",
get_debstr(1), act_connection, act_ncpsequence);
fprintf(lologfile, "%s %d %3d:%s:%s\n", get_debstr(1), act_connection,
act_ncpsequence, what, errstr);
if (p) { if (p) {
va_start(ap, p); va_start(ap, p);
vfprintf(lologfile, p, ap); vfprintf(lologfile, p, ap);
@ -295,7 +349,7 @@ static uint8 *path_spool=NULL;
char *get_div_pathes(char *buff, char *name, int what, char *p, ... ) char *get_div_pathes(char *buff, char *name, int what, char *p, ... )
{ {
char *wpath; char *wpath=NULL;
int len; int len;
uint8 locbuf[200]; uint8 locbuf[200];
switch (what) { switch (what) {
@ -349,7 +403,11 @@ int get_ini_int(int what)
static void sig_segv(int isig) static void sig_segv(int isig)
{ {
errorp(11, "!!! SIG_SEGV !!!", "at pid=%d", my_pid); errorp(11, "!!! SIG_SEGV !!!", "at pid=%d, ncp_sequence=%d", my_pid, act_ncpsequence);
exit(1);
#ifndef LINUX
exit(1);
#endif
#if 0 #if 0
(*sigsegv_func)(isig); (*sigsegv_func)(isig);
#endif #endif
@ -372,7 +430,9 @@ static void creat_pidfile(void)
{ {
char buf[300]; char buf[300];
char *pidfn=get_pidfilefn(buf); char *pidfn=get_pidfilefn(buf);
FILE *f=fopen(pidfn, "w"); FILE *f;
unlink(pidfn); /* security, mst:18-Apr-00 */
f = fopen(pidfn, "w");
if (f != NULL) { if (f != NULL) {
fprintf(f, "%d\n", getpid()); fprintf(f, "%d\n", getpid());
fclose(f); fclose(f);
@ -416,13 +476,14 @@ void init_tools(int module, int options)
{ {
uint8 buf[300]; uint8 buf[300];
char logfilename[300]; char logfilename[300];
FILE *f=open_nw_ini(); FILE *f;
int withlog=0; int withlog=0;
int dodaemon=0; int dodaemon=0;
int new_log=0; int new_log=0;
in_module = module; in_module = module;
logfile = stderr; /* preset */
f = open_nw_ini();
my_pid = getpid(); my_pid = getpid();
connection = (NWCONN == module) ? options : 0;
if (NWSERV == module || NWROUTED == module) { if (NWSERV == module || NWROUTED == module) {
int kill_pid=-1; int kill_pid=-1;
char *pidfn=get_pidfilefn((char*)buf); char *pidfn=get_pidfilefn((char*)buf);
@ -434,7 +495,7 @@ void init_tools(int module, int options)
kill_pid=-1; kill_pid=-1;
fclose(pf); fclose(pf);
} }
if (kill_pid < 0) unlink((char*)buf); if (kill_pid < 0) unlink(pidfn);
} }
if (kill_pid > -1) { if (kill_pid > -1) {
int sig; int sig;
@ -655,38 +716,59 @@ int name_match(uint8 *s, uint8 *p)
return ( (*s) ? 0 : 1); return ( (*s) ? 0 : 1);
} }
uint8 *station_fn=NULL; #ifndef LINUX
/* UnixWare needs fixed sprintf function :-( */
int find_station_match(int entry, ipxAddr_t *addr) int fixed_sprintf(char *buf, char *p, ...)
{ {
int matched = 0; va_list ap;
if (station_fn && *station_fn) { va_start(ap, p);
FILE *f=fopen((char*)station_fn, "r"); (void)vsprintf(buf, p, ap);
if (f) { va_end(ap);
uint8 buff[200]; return(strlen(buf));
uint8 addrstring[100]; }
int what; #endif
ipx_addr_to_adr((char*)addrstring, addr);
upstr(addrstring); /* to be compatible with new 'SAMBA trustee code' */
while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))){ int slprintf(char *buf, int bufsize, char *p, ...)
if (what == entry) { {
uint8 *p = buff + strlen((char*)buff); va_list ap;
while (p-- > buff && *p==32) *p='\0'; int len;
upstr(buff); va_start(ap, p);
if (name_match(addrstring, buff)) { len = vsnprintf(buf, bufsize+1, p, ap);
matched=1; va_end(ap);
break; if (len > bufsize || len < 0) {
buf[bufsize] = 0;
return(-1);
} }
} buf[len] = 0;
} return(len);
fclose(f); }
} else {
XDPRINTF((3, 0, "find_station_match, cannot open '%s'", #define MAX_TMP_STRINGS 3
station_fn)); static char *tmpstr[MAX_TMP_STRINGS]={NULL};
} static int tmpstrcounter=0;
}
XDPRINTF((3, 0, "find_station_match entry=%d, matched=%d, addr=%s", char *gettmpstr(char *qs, int len, int extralen)
entry, matched, visable_ipx_adr(addr))); {
return(matched); char *s;
if (tmpstr[tmpstrcounter])
free(tmpstr[tmpstrcounter]);
extralen += (len+1);
s = tmpstr[tmpstrcounter] = xmalloc(extralen);
if (len)
memcpy(s, qs, len);
s[len] = '\0';
if (++tmpstrcounter==MAX_TMP_STRINGS)
tmpstrcounter=0;
return(s);
}
int is_filelink(char *fn)
{
struct stat stb;
return( (lstat(fn, &stb) == -1)
? 0
: S_ISLNK(stb.st_mode) );
} }

23
tools.h
View File

@ -1,6 +1,6 @@
/* tools.h : 08-Jun-97 */ /* tools.h : 18-Apr-00 */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -66,11 +66,13 @@ extern char *hex_str(char *buf, uint8 *s, int len);
extern int name_match(uint8 *s, uint8 *p); extern int name_match(uint8 *s, uint8 *p);
extern uint8 *station_fn;
extern int find_station_match(int entry, ipxAddr_t *addr);
extern int nw_debug; extern int nw_debug;
extern uint32 debug_mask; extern uint32 debug_mask;
extern int act_ncpsequence; /* for debugging */
extern int act_connection; /* which connection (nwconn, nwbind) */
extern time_t act_time; /* actual time */
#include "debmask.h" #include "debmask.h"
#if DO_DEBUG #if DO_DEBUG
# define XDPRINTF(x) xdprintf x # define XDPRINTF(x) xdprintf x
@ -82,5 +84,16 @@ extern uint32 debug_mask;
# define MDEBUG(mask, x) /* */ # define MDEBUG(mask, x) /* */
#endif #endif
#ifndef LINUX
extern int fixed_sprintf(char *buf, char *p, ...);
#define sprintf fixed_sprintf
#endif
extern int slprintf(char *buf, int bufsize, char *p, ...);
extern char *gettmpstr(char *qs, int len, int extralen);
extern int is_filelink(char *fn);
#endif /* _TOOLS_H_ */ #endif /* _TOOLS_H_ */

33
tools.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
yesno()
{
echo ""
echo $@
while true; do
echo "please answer with (Y)es or (N)o and <Return>."
read X
case "$X" in
('y'|'Y')
return 0
;;
('n'|'N')
return 1
;;
*)
;;
esac
done
}
COMMAND=$1
shift
case "$COMMAND" in
'yesno')
if yesno $@ ; then exit 0; fi
;;
esac
exit 1

923
trustee.c Normal file
View File

@ -0,0 +1,923 @@
/* trustee.c 15-Apr-00 */
/* (C)opyright (C) 1998,2000 Martin Stover, Marburg, Germany
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Trusttee routines for mars_nwe */
#include "net.h"
#include <dirent.h>
#include "unxfile.h"
#include "nwvolume.h"
#include "connect.h"
#include "trustee.h"
/* right access routines depending on unix rights */
static int un_nw_rights(int voloptions, uint8 *unixname, struct stat *stb)
/* returns eff rights of file/dir depending on unix rights only */
/* therefore only root gets TRUSTEE_S by this routine */
{
int rights=0xff; /* first all, pconsole needs TRUSTEE_O */
int is_pipe_command=(voloptions & VOL_OPTION_IS_PIPE)
&& !S_ISFIFO(stb->st_mode);
if (act_uid || is_pipe_command || (voloptions & VOL_OPTION_READONLY)) {
int is_dir = S_ISDIR(stb->st_mode);
int acc = get_unix_eff_rights(stb);
int norights = TRUSTEE_A; /* no access control rights */
struct stat stbp;
uint8 *p = unixname+strlen(unixname);
memset(&stbp, 0, sizeof(struct stat));
if (p > unixname){ /* now we must get parent rights */
--p;
while (p>unixname && *p=='/') --p; /* remove trailing slash */
while (p>unixname && *p!='/') --p; /* search for slash */
while (p>unixname && *p=='/') --p; /* and remove it */
if (p > unixname) { /* found subdir */
*(p+1)='\0';
if (stat(unixname, &stbp) ||
(stbp.st_dev==stb->st_dev && stbp.st_ino==stb->st_ino)
|| !S_ISDIR(stbp.st_mode) ){
/* something wrong here, clear rights */
errorp(0,"un_nw_rights", "wrong path=%s", unixname);
memset(&stbp, 0, sizeof(struct stat));
}
*(p+1)='/';
} else {
if (stat("/.", &stbp))
memset(&stbp, 0, sizeof(struct stat));
}
}
if (!stbp.st_mode) {
XDPRINTF((1,0, "no rights to parentdir of %s", unixname));
norights=rights;
} else {
int accp=get_unix_eff_rights(&stbp);
if (!(accp & X_OK))
norights=rights;
else if (!(accp & W_OK)) {
norights |= TRUSTEE_E; /* no erase right */
norights |= TRUSTEE_M; /* no modify rights */
}
}
if (voloptions & VOL_OPTION_READONLY) {
norights |= TRUSTEE_E; /* no erase right */
norights |= TRUSTEE_M; /* no modify rights */
norights |= TRUSTEE_C; /* no creat rights */
} else if ((!acc||is_dir||is_pipe_command) && !(acc&X_OK)) {
norights = rights;
} else if (is_pipe_command) {
norights |= TRUSTEE_E; /* no erase right */
norights |= TRUSTEE_M; /* no modify rights */
norights |= TRUSTEE_C; /* no creat rights */
}
if (!(acc & 0x30)){ /* if not user and not in groups */
norights |= TRUSTEE_M; /* no modify rights */
}
if (!(acc & W_OK)) {
if (!(acc & 0x10) || (stb->st_uid == default_uid)){
norights |= TRUSTEE_M; /* no modify rights */
}
norights |= TRUSTEE_E; /* no erase */
norights |= TRUSTEE_C; /* no creat */
norights |= TRUSTEE_W; /* no write */
}
if (!(acc & R_OK)) {
norights |= TRUSTEE_R; /* No read rights for files */
if (is_dir)
norights |= TRUSTEE_F; /* no scan rights */
}
rights &= (~norights);
} else
rights |= TRUSTEE_S; /* Root always has all access rights */
return(rights);
}
#define MAX_TRUSTEES 100 /* max. trustee entries for one file/dir */
#define MAX_TRUSTEE_CACHE 50 /* max. trusttees in cache */
typedef struct {
int trustee;
uint32 id;
} IDS_TRUSTEE;
typedef struct {
int volume;
int dev;
int inode;
int idle; /* idle state */
int mode_flags; /*
* &0x01 is directory
* &0x02 is_root
* &0x04 is_symlink
* &0x08 dev changed, will be set by trustees scan
* &0x10 dev differs from volume's dev
* will be set by trustees scan
* is important to prevent trustee changes by
* normal user (not user 'root')
*/
int inherited_mask; /* for all users */
int eff_rights; /* for actual user */
/* trustees for this node */
int trustee_count;
IDS_TRUSTEE *trustees;
} FILE_TRUSTEE_NODE;
typedef struct {
int count;
FILE_TRUSTEE_NODE *tr[MAX_TRUSTEE_CACHE];
} TRUSTEE_CACHE;
static TRUSTEE_CACHE *tr_cache=NULL;
static void free_trustee_node(FILE_TRUSTEE_NODE *tn)
{
if (tn) {
xfree(tn->trustees);
xfree(tn);
}
}
void tru_free_cache(int volume)
/* free's cache for one volume or all volume's if volume == -1 */
{
if (tr_cache) {
int i=tr_cache->count;
while(i--) {
FILE_TRUSTEE_NODE *tr=tr_cache->tr[i];
if (tr && (volume == -1 || tr->volume == volume)){
free_trustee_node(tr);
tr_cache->tr[i]=NULL;
if (i+1 == tr_cache->count)
--tr_cache->count;
}
}
}
if (volume == -1)
xfree(tr_cache);
}
static void add_trustee_node(FILE_TRUSTEE_NODE *trn)
{
if (trn) {
int i;
int max_idle = 0;
int found_idle = -1;
int to_use = -1;
if (!tr_cache)
tr_cache=(TRUSTEE_CACHE*)xcmalloc(sizeof(TRUSTEE_CACHE));
for (i=0;i < tr_cache->count; i++) {
FILE_TRUSTEE_NODE *tr=tr_cache->tr[i];
if (!tr) {
if (to_use < 0) to_use=i;
} else {
if (tr->mode_flags&1) tr->idle++; /* dirs should not become idle so fast */
else tr->idle+=10; /* as files */
if (tr->idle > max_idle) {
found_idle=i;
max_idle=tr->idle;
}
}
}
if (to_use < 0) {
if (tr_cache->count < MAX_TRUSTEE_CACHE)
to_use=tr_cache->count++;
else {
to_use=found_idle;
free_trustee_node(tr_cache->tr[to_use]);
}
}
tr_cache->tr[to_use]=trn;
}
}
static FILE_TRUSTEE_NODE *find_trustee_node(int volume, int dev, int inode)
{
if (vol_trustees_were_changed(volume))
return(NULL);
if (tr_cache) {
int i=-1;
while (++i < tr_cache->count) {
FILE_TRUSTEE_NODE *tr=tr_cache->tr[i];
if (tr && tr->volume == volume && tr->dev == dev && tr->inode == inode){
tr->idle=0;
return(tr);
}
}
}
return(NULL);
}
static int find_id_trustee(FILE_TRUSTEE_NODE *tr, uint32 id)
{
int i=0;
IDS_TRUSTEE *ids=tr->trustees;
while (i++ < tr->trustee_count) {
if (ids->id == id)
return(ids->trustee);
ids++;
}
return(-1); /* not found */
}
static int grps_count=0;
static uint32 *grps_grps=NULL;
static int cmp_uint32(const void *e1, const void *e2)
{
if (*((uint32*)e1) < *((uint32*)e2)) return(-1);
if (*((uint32*)e1) > *((uint32*)e2)) return(1);
return(0);
}
static int grp_exist(uint32 grp_id)
/* returns 1 if grp_id exist */
{
return( (NULL == bsearch(&grp_id, grps_grps,
(size_t)grps_count, (size_t)sizeof(uint32), cmp_uint32))
? 0 : 1);
}
void tru_init_trustees(int count, uint32 *grps)
/* must be called after new loging */
{
tru_free_cache(-1);
xfree(grps_grps);
grps_count=count;
if (count) {
grps_grps=(uint32*)xmalloc(sizeof(uint32) * count);
memcpy(grps_grps, grps, sizeof(uint32) * count);
qsort(grps_grps, (size_t)grps_count, (size_t)sizeof(uint32), cmp_uint32);
}
}
static void creat_trustee_path(int volume, int dev, ino_t inode, uint8 *path)
/* is always called with uid = 0 */
{
char buf[256];
uint8 buf_uc[4];
char volname[100];
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1) return;
U32_TO_BE32(inode, buf_uc);
slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/n.%x", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
unlink(buf);
if (symlink(path, buf)) {
XDPRINTF((0,0,"creat_trustee_path buf=`%s`, path=`%s` failed", buf, path));
}
}
static int put_trustee_to_disk(int volume, int dev, ino_t inode, uint32 id, int trustee)
/* is always called with uid = 0 */
/* if id=0, it means inherited_mask */
{
char buf[256];
char btrustee[256];
int l;
uint8 buf_uc[4];
char volname[100];
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1) return(-0xff);
U32_TO_BE32(inode, buf_uc);
l=slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/t.%x", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
unx_xmkdir(buf, 0755);
slprintf(buf+l, sizeof(buf) -l -1, "/%x", (unsigned int) id);
unlink(buf);
l=slprintf(btrustee, sizeof(btrustee)-1, "%04x", (unsigned int) trustee);
return(symlink(btrustee, buf) ? -0xff : 0);
}
static int get_trustee_from_disk(int volume, int dev, ino_t inode, uint32 id, int *trustee)
/*
* if id=0, it means inherited_mask
* return 0 if 0, < 0 if error
*/
{
char buf[256];
char btrustee[256];
int l;
uint8 buf_uc[4];
char volname[100];
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1)
return(-0xff);
U32_TO_BE32(inode, buf_uc);
slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/t.%x/%x", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3],
(unsigned int)id);
l = readlink(buf, btrustee, 254);
if (l > 0) {
unsigned int utrustee=0;
btrustee[l]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
*trustee = (int)utrustee;
return(0);
}
}
return(-0xff);
}
static int del_trustee_from_disk(int volume, int dev, ino_t inode, uint32 id)
/* removes users id trustee */
{
char buf[256];
int result=-0xfe; /* no such trustee */
uint8 buf_uc[4];
char volname[100];
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1) return(result);
U32_TO_BE32(inode, buf_uc);
slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/t.%x/%x", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3],
(unsigned int)id);
seteuid(0);
if (!unlink(buf))
result=0;
reseteuid();
return(result);
}
unsigned int tru_vol_sernum(int volume, int mode)
/* mode == 0, reads sernum, else change sernum, returns new sernum */
{
char volname[100];
char buf[256];
char buf1[20];
int len;
unsigned int sernum=0;
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1) return(-1);
slprintf(buf, sizeof(buf)-1, "%s/%s/ts", path_trustees, volname);
len=readlink(buf, buf1, sizeof(buf1)-1);
if (len>0) {
buf1[len]='\0';
if (1!=sscanf(buf1,"%x", &sernum))
sernum=0;
}
if (mode) {
if (++sernum==MAX_U32) sernum=1;
seteuid(0);
unlink(buf);
slprintf(buf1, sizeof(buf1)-1, "%x", sernum);
if (symlink(buf1, buf))
errorp(0, "rw_trustee_sernum", "symlink %s %s failed", buf1, buf);
reseteuid();
tru_free_cache(volume);
}
return(sernum);
}
void tru_free_file_trustees_from_disk(int volume, int dev, ino_t inode)
/* is called if directory/file is removed */
{
char buf[256];
uint8 buf_uc[4];
int len;
char volname[100];
if (nw_get_volume_name(volume, volname, sizeof(volname) ) < 1) return;
U32_TO_BE32(inode, buf_uc);
len=slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2]);
slprintf(buf+len, sizeof(buf) - len -1, "t.%x", (int)buf_uc[3]);
seteuid(0);
unx_xrmdir(buf);
/* now we remove the name of the dir/file */
slprintf(buf+len, sizeof(buf) -len -1, "n.%x", (int)buf_uc[3]);
unlink(buf);
reseteuid();
}
int tru_del_trustee(int volume, uint8 *unixname, struct stat *stb, uint32 id)
{
int result=-0x85; /* we say no privileges */
int voloptions = get_volume_options(volume);
if ( (voloptions & VOL_OPTION_TRUSTEES) &&
( (tru_get_eff_rights(volume, unixname, stb) & TRUSTEE_A)
|| (act_id_flags&1)) ) {
result=del_trustee_from_disk(volume, stb->st_dev, stb->st_ino, id);
if (!result)
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
}
MDEBUG(D_TRUSTEES, {
xdprintf(1,0, "tru_del_trustee: id=%08lx, volume=%d, file=`%s`, result=-0x%x",
id, volume, unixname, -result);
})
return(result);
}
static FILE_TRUSTEE_NODE *create_trustee_node(int volume, int dev,
ino_t inode, int mode_flags)
/*
* mode_flags: &1=directory, &2=root, &4=symlink, &0x8 dev changes
* &0x10 dev differs from volumes dev.
*/
{
char buf[256];
int l;
uint8 buf_uc[4];
DIR *d;
char volname[100];
FILE_TRUSTEE_NODE *tr = (FILE_TRUSTEE_NODE*)xcmalloc(sizeof(FILE_TRUSTEE_NODE));
tr->volume = volume;
tr->dev = dev;
tr->inode = inode;
tr->mode_flags = mode_flags;
tr->inherited_mask = (mode_flags&0xe)
? 0 /* root dir or symlink no rights */
: MAX_TRUSTEE_MASK; /* default all allowed */
tr->eff_rights = -1; /* not yet set */
U32_TO_BE32(inode, buf_uc);
(void)nw_get_volume_name(volume, volname, sizeof(volname) );
l=slprintf(buf, sizeof(buf)-1, "%s/%s/%x/%x/%x/%x/t.%x", path_trustees, volname,
dev,
(int) buf_uc[0],
(int) buf_uc[1],
(int) buf_uc[2],
(int) buf_uc[3]);
if (NULL != (d= opendir(buf)) ) {
uint8 *p=buf+l;
struct dirent *dirbuff;
int trustee_count=0;
IDS_TRUSTEE trustees[MAX_TRUSTEES];
*p++ = '/';
while (trustee_count < MAX_TRUSTEES &&
(dirbuff = readdir(d)) != (struct dirent*)NULL){
if (dirbuff->d_ino && dirbuff->d_name[0] != '.') {
char btrustee[255];
int len;
unsigned int id;
if (1 == sscanf(dirbuff->d_name, "%x", &id)) {
len = (int)(p - (uint8*)buf);
strmaxcpy(p, dirbuff->d_name, sizeof(buf) - len -1);
len=readlink(buf, btrustee, 254);
if (len > 0) {
unsigned int utrustee=0;
btrustee[len]='\0';
if (1 == sscanf(btrustee, "%x", &utrustee)) {
if (id) {
trustees[trustee_count].id = (uint32) id;
trustees[trustee_count].trustee = (int) utrustee;
trustee_count++;
} else
tr->inherited_mask=(int)utrustee;
}
}
}
}
} /* while */
closedir(d);
tr->trustee_count=trustee_count;
if (trustee_count) {
tr->trustees=(IDS_TRUSTEE*)xcmalloc(sizeof(IDS_TRUSTEE)*trustee_count);
while (trustee_count--){
tr->trustees[trustee_count].id = trustees[trustee_count].id;
tr->trustees[trustee_count].trustee = trustees[trustee_count].trustee;
}
}
}
return(tr);
}
static FILE_TRUSTEE_NODE *find_creat_add_trustee_node(
int volume, uint8 *unixname, struct stat *stb)
{
FILE_TRUSTEE_NODE *tr=find_trustee_node(volume, stb->st_dev, stb->st_ino);
if (!tr) {
struct stat lstatbuf;
int mode_flags=S_ISDIR(stb->st_mode) ? 1:0;
if ( lstat(unixname, &lstatbuf)
|| (lstatbuf.st_dev != stb->st_dev)
|| (lstatbuf.st_ino != stb->st_ino)
|| S_ISLNK(lstatbuf.st_mode) ) {
mode_flags|=4;
}
tr=create_trustee_node(volume, stb->st_dev, stb->st_ino, mode_flags);
add_trustee_node(tr);
}
return(tr);
}
int tru_get_id_trustee(int volume, uint8 *unixname, struct stat *stb, uint32 id)
/* is called by vol_trustee_scan */
{
int voloptions=get_volume_options(volume);
if (voloptions&VOL_OPTION_TRUSTEES){
FILE_TRUSTEE_NODE *tr=find_creat_add_trustee_node(volume, unixname, stb);
return(find_id_trustee(tr, id));
}
return(-0x85);
}
static FILE_TRUSTEE_NODE *find_build_trustee_node(int volume, uint8 *unixname, struct stat *stb);
static int local_tru_add_trustee_set(int volume, uint8 *unixname,
struct stat *stb,
int count, NW_OIC *nwoic)
{
int voloptions = get_volume_options(volume);
int own_eff_rights;
int result=-0x85; /* we say no privileges */
if ( (voloptions & VOL_OPTION_TRUSTEES) &&
( ((own_eff_rights=tru_get_eff_rights(volume, unixname, stb)) & TRUSTEE_A)
|| (act_id_flags&1) )) {
/* FILE_TRUSTEE_NODE *tr=find_trustee_node(volume, stb->st_dev, stb->st_ino); */
/* mst:11-May-00 */
FILE_TRUSTEE_NODE *tr=find_build_trustee_node(volume, unixname, stb);
if (tr && (!(tr->mode_flags&0x18) || !act_uid)) {
int volumenamelen = get_volume_unixnamlen(volume);
uint8 ufnbuf[2];
uint8 *ufn;
seteuid(0);
while (count--) {
if (! ((own_eff_rights & TRUSTEE_S) || (act_id_flags&1)) ) {
/* only user with TRUSTEE_S are allowed to set TRUSTEE_S */
if (nwoic->trustee&TRUSTEE_S)
nwoic->trustee&=~TRUSTEE_S;
}
result=put_trustee_to_disk(volume, stb->st_dev, stb->st_ino, nwoic->id, nwoic->trustee);
MDEBUG(D_TRUSTEES, {
xdprintf(1,0, "tru_add_trustee_set: id=%08lx, trustee=0x%04x, volume=%d, file=`%s`, result=-0x%x",
nwoic->id, nwoic->trustee, volume, unixname, -result);
})
if (result){
reseteuid();
goto func_err;
}
nwoic++;
}
ufn=unixname+min(strlen(unixname), volumenamelen);
if (!*ufn) { /* is volume direct */
ufn=ufnbuf;
*ufn='.';
*(ufn+1)='\0';
}
creat_trustee_path(volume, stb->st_dev, stb->st_ino, ufn);
reseteuid();
#if 0 /* now in tru_add_trustee_set */
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
#endif
return(0);
}
}
func_err:
XDPRINTF((1,0, "user %08x tried to add trustees to %s, result=-0x%x",
act_obj_id, unixname, -result));
tru_free_cache(-1);
return(result); /* we say no privileges */
}
int tru_add_trustee_set(int volume, uint8 *unixname,
struct stat *stb,
int count, NW_OIC *nwoic)
{
int result = local_tru_add_trustee_set(volume, unixname, stb, count, nwoic);
if (!result) { /* mst: 13-Apr-00 */
int len = strlen(unixname);
int vollen = get_volume_unixnamlen(volume);
char *p = unixname+len;
char *volp = unixname+vollen;
seteuid(0);
while (--p > volp) {
if (*p == '/') {
struct stat statb;
*p='\0';
if (!stat(unixname, &statb)){
int i;
NW_OIC *poic=nwoic;
for (i=0; i < count; i++) {
int trustee = 0;
if (poic->id) {
get_trustee_from_disk(volume, statb.st_dev, statb.st_ino, poic->id, &trustee);
if ( !(trustee & (TRUSTEE_T|TRUSTEE_F)) ) {
trustee |= TRUSTEE_T;
put_trustee_to_disk(volume, statb.st_dev, statb.st_ino, poic->id, trustee);
}
}
poic++;
}
}
*p='/';
}
}
reseteuid();
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
}
return (result);
}
int tru_get_trustee_set(int volume, uint8 *unixname,
struct stat *stb,
int sequence,
int maxcount, uint32 *ids, int *trustees)
{
int voloptions = get_volume_options(volume);
if (voloptions & VOL_OPTION_TRUSTEES) {
int offset = sequence*maxcount;
int count = 0;
FILE_TRUSTEE_NODE *tr=find_creat_add_trustee_node(volume, unixname, stb);
while (offset < tr->trustee_count && count < maxcount) {
*ids=tr->trustees[offset].id;
ids++;
*trustees=tr->trustees[offset].trustee;
trustees++;
offset++;
count++;
}
if (count) return(count);
}
return(-0x9c); /* no more trustees */
}
int tru_set_inherited_mask(int volume, uint8 *unixname,
struct stat *stb, int new_mask)
/* sets inherited mask of directory */
{
int voloptions = get_volume_options(volume);
if ( (voloptions & VOL_OPTION_TRUSTEES) &&
( (tru_get_eff_rights(volume, unixname, stb) & TRUSTEE_A)
|| (act_id_flags&1)) ) {
FILE_TRUSTEE_NODE *tr=find_trustee_node(volume, stb->st_dev, stb->st_ino);
if (tr && (!(tr->mode_flags&0x1e) || !act_uid)) {
int result;
seteuid(0);
result=put_trustee_to_disk(volume, stb->st_dev, stb->st_ino, 0L, new_mask);
reseteuid();
if (!result)
tru_vol_sernum(volume, 1); /* trustee sernum needs updated */
return(result);
}
}
return(-0x85); /* we say no privileges */
}
int tru_get_inherited_mask(int volume, uint8 *unixname,
struct stat *stb)
/* returns inherited mask of directory */
{
int voloptions = get_volume_options(volume);
if (voloptions & VOL_OPTION_TRUSTEES){
FILE_TRUSTEE_NODE *tr=find_creat_add_trustee_node(volume, unixname, stb);
return(tr->inherited_mask);
}
return(0x01ff); /* default */
}
static int insert_ugid_trustee(IDS_TRUSTEE *ugid_trustees, int count,
uint32 id, int trustee)
/* return 1 if inserted, else 0 */
{
while (count--) {
if (ugid_trustees->id==id) {
ugid_trustees->trustee|=trustee;
return(0);
}
ugid_trustees++;
}
ugid_trustees->id=id;
ugid_trustees->trustee=trustee;
return(1);
}
static int build_trustee_rights(FILE_TRUSTEE_NODE *tr,
IDS_TRUSTEE *ugid_trustees, int count)
/* this routine must be called root to leaf */
{
if (tr) {
int i = tr->trustee_count;
IDS_TRUSTEE *trn = tr->trustees;
int k = count;
if (tr->mode_flags & (8|4|2)) {
/* dev changed or root volume or symlink */
if ( (tr->mode_flags&2) && (act_id_flags&1) ) {
/* root directory and supervisor equivalences */
/* get all trusttee rights */
if (insert_ugid_trustee(ugid_trustees, count,
act_obj_id, MAX_TRUSTEE_MASK))
count++;
} else {
/* trusteess will not be passed to childs */
while (k--) { /* first we set all to null */
(ugid_trustees+k)->trustee = 0;
}
}
/* inherited_mask will be 0 */
tr->inherited_mask=0;
} else {
while (k--) {
/* trusteess will be passed to childs but */
/* first we mask all with inherited_mask */
(ugid_trustees+k)->trustee &= tr->inherited_mask;
}
}
while (i--) { /* now we read all trustees for this node */
if (trn->id == act_obj_id || grp_exist(trn->id)){
if (insert_ugid_trustee(ugid_trustees, count,
trn->id, trn->trustee))
count++;
}
trn++;
} /* while */
/* now we build eff_rights for this node */
tr->eff_rights=0;
for (k=0; k < count; k++) {
tr->eff_rights |= (ugid_trustees+k)->trustee;
}
}
return(count);
}
static FILE_TRUSTEE_NODE *find_build_trustee_node(int volume, uint8 *unixname, struct stat *stb)
{
FILE_TRUSTEE_NODE *tr=find_creat_add_trustee_node(volume, unixname, stb);
if (tr->eff_rights < 0) { /* now we must rebuild eff rights */
int count=0;
IDS_TRUSTEE *ugid_trustees=
(IDS_TRUSTEE*)xcmalloc((grps_count+1)*sizeof(IDS_TRUSTEE));
struct stat stb1;
(void)get_volume_inode(volume, &stb1);
if (stb1.st_ino != stb->st_ino || stb1.st_dev != stb->st_dev) {
/* is not volumes root */
int volumenamelen = get_volume_unixnamlen(volume);
char *p = unixname+volumenamelen;
int last_dev = stb1.st_dev;
int volumes_dev = stb1.st_dev;
FILE_TRUSTEE_NODE *tr1=find_trustee_node(
volume, stb1.st_dev, stb1.st_ino);
if (!tr1) {
tr1=create_trustee_node(volume, stb1.st_dev, stb1.st_ino, 3);
add_trustee_node(tr1);
} else tr1->mode_flags|=3;
/* build trustees for unix volume */
count=build_trustee_rights(tr1, ugid_trustees, count);
while (*p=='/')++p;
while (NULL != (p=strchr(p, '/'))) {
*p = '\0';
if (!stat(unixname, &stb1)) {
if (stb1.st_ino != stb->st_ino || stb1.st_dev != stb->st_dev) {
int mode_flags=S_ISDIR(stb1.st_mode)?1:0;
tr1=find_trustee_node(volume, stb1.st_dev, stb1.st_ino);
if (last_dev != stb1.st_dev) {
last_dev = stb1.st_dev;
mode_flags |= 0x8;
}
if (volumes_dev != stb1.st_dev)
mode_flags|=0x10;
if (!tr1) {
struct stat lstatbuf;
if ( lstat(unixname, &lstatbuf)
|| (lstatbuf.st_dev != stb1.st_dev)
|| (lstatbuf.st_ino != stb1.st_ino)
|| S_ISLNK(lstatbuf.st_mode) ) {
mode_flags|=4;
}
tr1=create_trustee_node(volume, stb1.st_dev, stb1.st_ino,
mode_flags);
add_trustee_node(tr1);
} else
tr1->mode_flags|=mode_flags;
count=build_trustee_rights(tr1, ugid_trustees, count);
} else {
*p='/';
break;
}
} else {
errorp(10, "tru_get_eff_rights", "stat error `%s`", unixname);
*p='/';
xfree(ugid_trustees);
return(0);
}
*p='/';
while (*p=='/')++p;
} /* while */
if (last_dev != stb->st_dev)
tr->mode_flags|=0x8;
if (volumes_dev!=stb->st_dev)
tr->mode_flags|=0x10;
} else {
/* volumes directory */
tr->mode_flags|=(1|2);
}
count=build_trustee_rights(tr, ugid_trustees, count);
xfree(ugid_trustees);
} /* if eff_rights < 0 */
return(tr);
}
static int get_eff_rights_by_trustees(int volume, uint8 *unixname, struct stat *stb)
/* returns the eff. rights the actual user has as real trustees */
{
if ( (act_obj_id == 1) && (act_id_flags&1) ) /* supervisor */
return(MAX_TRUSTEE_MASK); /* all rights */
else {
FILE_TRUSTEE_NODE *tr = find_build_trustee_node(volume, unixname, stb);
return( (tr->eff_rights > -1) ? tr->eff_rights : 0);
}
}
int tru_get_eff_rights(int volume, uint8 *unixname, struct stat *stb)
/* returns the eff. rights the actual user has */
{
int voloptions = get_volume_options(volume);
int rights = 0;
int rights1 = 0;
if (voloptions & VOL_OPTION_TRUSTEES){
rights=(get_eff_rights_by_trustees(volume, unixname, stb) & MAX_TRUSTEE_MASK);
}
if (!(voloptions & VOL_OPTION_IGNUNXRIGHT)){
rights1 = un_nw_rights(voloptions, unixname, stb);
}
MDEBUG(D_TRUSTEES, {
xdprintf(1,0, "eff_rights=%04x,%04x for`%s`",
rights, rights1, unixname);
})
return(rights|rights1);
}
int tru_eff_rights_exists(int volume, uint8 *unixname, struct stat *stb,
int lookfor)
/*
* returns 0 if lookfor right exist,
* otherwise returns the current rights
*/
{
int voloptions = get_volume_options(volume);
int rights = 0;
int rights1 = 0;
int result = -1;
if (voloptions & VOL_OPTION_TRUSTEES){
/* we look for trustee rights first */
rights=get_eff_rights_by_trustees(volume, unixname, stb);
if ((rights & TRUSTEE_S)||((rights&lookfor)==lookfor))
result = 0;
else if ((lookfor == TRUSTEE_T) && (rights&TRUSTEE_F) ) /* mst: 13-Apr-00 */
result=0;
}
if (result && !(voloptions & VOL_OPTION_IGNUNXRIGHT)){
rights1 = un_nw_rights(voloptions, unixname, stb);
}
MDEBUG(D_TRUSTEES, {
xdprintf(1,0, "lookfor=%04x, eff_rights_exists ? = %04x(tru),%04x(unx) for`%s`",
lookfor, rights, rights1, unixname);
})
if (!result) return(0);
rights |= rights1;
if ((lookfor == TRUSTEE_T) && (rights&TRUSTEE_F) ) /* mst: 13-Apr-00 */
return(0);
return(((rights & TRUSTEE_S)||((rights&lookfor)==lookfor)) ? 0 : -1);
}

61
trustee.h Normal file
View File

@ -0,0 +1,61 @@
/* trustee.h 13-Apr-00 */
#ifndef _TRUSTEE_H_
#define _TRUSTEE_H_
/* some TRUSTEE defines */
#define TRUSTEE_R 0x01 /* file Read rights */
#define TRUSTEE_W 0x02 /* file Write rights */
#define TRUSTEE_O 0x04 /* file Open rights */
#define TRUSTEE_C 0x08 /* file/dir Creat rights */
#define TRUSTEE_E 0x10 /* file/dir Erase rights */
#define TRUSTEE_A 0x20 /* Access control,change trustees,inherited rights */
#define TRUSTEE_F 0x40 /* File scan rights */
#define TRUSTEE_M 0x80 /* Modify filename, attrib rights */
/* ......extended Trustees ................. */
#define TRUSTEE_S 0x100 /* Supervisor rights */
/* mars_nwe only, idea and patches from Christoph Scheeder */
#define TRUSTEE_T 0x200 /* See this dir/file only */
#define MAX_TRUSTEE_MASK 0x1FF
typedef struct {
uint32 id;
int trustee;
} NW_OIC;
extern void tru_free_cache(int volume);
extern void tru_init_trustees(int count, uint32 *grps);
extern unsigned int tru_vol_sernum(int volume, int mode);
extern void tru_free_file_trustees_from_disk(int volume,
int dev, ino_t inode);
extern int tru_del_trustee(int volume, uint8 *unixname,
struct stat *stb, uint32 id);
extern int tru_get_id_trustee(int volume, uint8 *unixname,
struct stat *stb, uint32 id);
extern int tru_add_trustee_set(int volume, uint8 *unixname,
struct stat *stb,
int count, NW_OIC *nwoic);
extern int tru_get_trustee_set(int volume, uint8 *unixname,
struct stat *stb,
int sequence,
int maxcount, uint32 *ids, int *trustees);
extern int tru_set_inherited_mask(int volume, uint8 *unixname,
struct stat *stb, int new_mask);
extern int tru_get_inherited_mask(int volume, uint8 *unixname,
struct stat *stb);
extern int tru_get_eff_rights(int volume, uint8 *unixname, struct stat *stb);
extern int tru_eff_rights_exists(int volume, uint8 *unixname, struct stat *stb,
int lookfor);
#endif

View File

@ -1,4 +1,4 @@
/* unxfile.c: 05-Feb-98*/ /* unxfile.c: 30-Apr-98*/
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
@ -72,7 +72,7 @@ int unx_xrmdir(char *unixname)
/* removes complete directory if possible */ /* removes complete directory if possible */
{ {
DIR *d = opendir(unixname); DIR *d = opendir(unixname);
if (NULL != (d = opendir(unixname))) { if (NULL != d) {
struct dirent *dirbuff; struct dirent *dirbuff;
int len = strlen(unixname); int len = strlen(unixname);
char *buf = xmalloc(len + 300); char *buf = xmalloc(len + 300);
@ -80,12 +80,17 @@ int unx_xrmdir(char *unixname)
memcpy(buf, unixname, len); memcpy(buf, unixname, len);
*p++ = '/'; *p++ = '/';
while ((dirbuff = readdir(d)) != (struct dirent*)NULL){ while ((dirbuff = readdir(d)) != (struct dirent*)NULL){
if (dirbuff->d_ino) { if (dirbuff->d_ino &&
strcpy(p, dirbuff->d_name); ( dirbuff->d_name[0] != '.'
if (unlink(buf) && unx_xrmdir(buf)) || (dirbuff->d_name[1] != '\0' &&
(dirbuff->d_name[1] != '.' || dirbuff->d_name[2] != '\0')))) {
strmaxcpy(p, dirbuff->d_name, 298);
if (unlink(buf) && unx_xrmdir(buf)) {
errorp(1, "unx_xrmdir", "cannot remove '%s'", buf);
break; break;
} }
} }
}
xfree(buf); xfree(buf);
closedir(d); closedir(d);
} }
@ -115,7 +120,7 @@ int unx_ftruncate(int fd, uint32 size)
flockd.l_whence = SEEK_SET; flockd.l_whence = SEEK_SET;
flockd.l_start = size; flockd.l_start = size;
flockd.l_len = 0; flockd.l_len = 0;
result = fcntl(fd, F_FREESP, &flockd); return(fcntl(fd, F_FREESP, &flockd));
#endif #endif
} }

View File

@ -1,4 +1,4 @@
/* unxfile.h: 05-Feb-98 */ /* unxfile.h: 23-Jul-98 */
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -24,5 +24,18 @@ extern int unx_xmkdir(char *unixname, int mode);
extern int unx_xrmdir(char *unixname); extern int unx_xrmdir(char *unixname);
extern int unx_ftruncate(int fd, uint32 size); extern int unx_ftruncate(int fd, uint32 size);
#ifdef FREEBSD
# define SEEKDIR(dh,to) {\
rewinddir(dh);\
while(TELLDIR(dh)!=(to)) \
if(readdir(dh)==NULL) break;\
}
# define TELLDIR(dh) ((dh)->dd_loc+(dh)->dd_seek)
#else
# define SEEKDIR(dh,to) seekdir((dh),(to))
# define TELLDIR(dh) telldir((dh))
#endif
#endif #endif

View File

@ -1,4 +1,4 @@
/* unxlog.c : 30-Apr-96 */ /* unxlog.c : 11-Jul-98 */
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -21,6 +21,7 @@
void write_utmp(int dologin, int connection, int pid, void write_utmp(int dologin, int connection, int pid,
ipxAddr_t *from_addr, uint8 *username) ipxAddr_t *from_addr, uint8 *username)
{ {
#ifndef FREEBSD
struct utmp loc_ut; struct utmp loc_ut;
struct utmp *ut; struct utmp *ut;
int fd; int fd;
@ -74,4 +75,5 @@ void write_utmp(int dologin, int connection, int pid,
write(fd, (char *)ut, sizeof(struct utmp)); write(fd, (char *)ut, sizeof(struct utmp));
close(fd); close(fd);
} }
#endif /* !FREEBSD */
} }