mars_nwe-0.99.pl19
This commit is contained in:
parent
5c18363271
commit
c1c64c1591
125
connect.h
125
connect.h
@ -1,29 +1,7 @@
|
||||
/* connect.h 01-Feb-98 */
|
||||
/* connect.h 04-Apr-00 */
|
||||
#ifndef _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 {
|
||||
uint8 path[256]; /* directory */
|
||||
uint8 fn[256]; /* file */
|
||||
@ -33,8 +11,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8 name[14]; /* filename in DOS format */
|
||||
uint8 attrib; /* Attribute */
|
||||
uint8 ext_attrib; /* File Execute Type */
|
||||
uint8 attrib[2]; /* LO-HI attrib, ext_attrib */
|
||||
uint8 size[4]; /* size of file */
|
||||
uint8 create_date[2];
|
||||
uint8 acces_date[2];
|
||||
@ -44,8 +21,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8 name[14]; /* dirname */
|
||||
uint8 attrib;
|
||||
uint8 ext_attrib;
|
||||
uint8 attrib[2]; /* LO-HI attrib, ext_attrib */
|
||||
uint8 create_date[2];
|
||||
uint8 create_time[2];
|
||||
uint8 owner_id[4];
|
||||
@ -63,7 +39,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8 subdir[4];
|
||||
uint8 attributes[4]; /* 0x20,0,0,0 File */
|
||||
uint8 attributes[4]; /* 0x20,0,0,0 LO-HI */
|
||||
uint8 uniqueid; /* 0 */
|
||||
uint8 flags; /* 0x18 */
|
||||
uint8 namespace; /* 0 */
|
||||
@ -81,7 +57,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8 subdir[4];
|
||||
uint8 attributes[4]; /* 0x10,0,0,0 DIR */
|
||||
uint8 attributes[4]; /* 0x10,0,0,0 LO-HI */
|
||||
uint8 uniqueid; /* 0 */
|
||||
uint8 flags; /* 0x14 or 0x1c */
|
||||
uint8 namespace; /* 0 */
|
||||
@ -106,11 +82,22 @@ typedef struct {
|
||||
} u;
|
||||
} 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 tells_server_version;
|
||||
extern int server_version_flags;
|
||||
extern int max_burst_send_size;
|
||||
extern int max_burst_recv_size;
|
||||
extern int default_uid;
|
||||
extern int default_gid;
|
||||
|
||||
extern int nw_init_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,
|
||||
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,
|
||||
int searchattrib, NW_FILE_INFO *f);
|
||||
|
||||
extern int nw_set_file_attributes(int dir_handle, uint8 *data, int len,
|
||||
int attrib, int newattrib);
|
||||
|
||||
extern int mv_file(int qdirhandle, uint8 *q, int qlen,
|
||||
int zdirhandle, uint8 *z, int zlen);
|
||||
extern int nw_mv_files(int searchattrib,
|
||||
int sourcedirhandle, uint8 *sourcedata, int qlen,
|
||||
int zdirhandle, uint8 *destdata, int destdatalen);
|
||||
|
||||
extern int mv_dir(int dir_handle, uint8 *q, int qlen,
|
||||
uint8 *z, int zlen);
|
||||
extern int mv_dir(int dir_handle, uint8 *sourcedata, int qlen,
|
||||
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);
|
||||
|
||||
@ -163,7 +155,8 @@ extern int nw_alloc_dir_handle(
|
||||
int driveletter, /* A .. Z normal */
|
||||
int is_temphandle, /* temp Handle 1 */
|
||||
/* spez. temp Handle 2 */
|
||||
int task); /* Prozess Task */
|
||||
int task, /* Prozess Task */
|
||||
int *eff_rights);
|
||||
|
||||
|
||||
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,
|
||||
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);
|
||||
|
||||
@ -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,
|
||||
struct stat *stb,
|
||||
int volume,
|
||||
uint8 *path);
|
||||
uint8 *path,
|
||||
char *unixname);
|
||||
|
||||
void get_dos_dir_attrib(NW_DOS_DIR_INFO *f,
|
||||
struct stat *stb,
|
||||
int volume,
|
||||
uint8 *path);
|
||||
uint8 *path,
|
||||
char *unixname);
|
||||
|
||||
|
||||
#define MAX_NW_DIRS 255
|
||||
extern int act_uid;
|
||||
extern int act_gid;
|
||||
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 entry31_flags; /* special flags, see examples nw.ini, entry 31 */
|
||||
|
||||
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,
|
||||
int size_unixname,
|
||||
int dirhandle,
|
||||
uint8 *data, int len);
|
||||
|
||||
@ -225,14 +223,15 @@ extern void set_guid(int gid, int uid);
|
||||
extern void reset_guid(void);
|
||||
extern void reseteuid(void);
|
||||
extern int in_act_groups(gid_t gid);
|
||||
extern void set_nw_user(int gid, int uid,
|
||||
uint32 obj_id, uint8 *objname,
|
||||
int homepathlen, uint8 *homepath);
|
||||
extern int get_unix_eff_rights(struct stat *stb);
|
||||
extern void set_nw_user(int gid, int uid,
|
||||
int id_flags,
|
||||
uint32 obj_id, uint8 *objname,
|
||||
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 int nw_scan_a_directory(uint8 *rdata,
|
||||
int dirhandle,
|
||||
uint8 *data,
|
||||
@ -243,18 +242,18 @@ extern int nw_scan_a_directory(uint8 *rdata,
|
||||
extern int nw_scan_a_root_dir(uint8 *rdata,
|
||||
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 void un_date_2_nw(time_t time, uint8 *d, int high_low);
|
||||
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 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,
|
||||
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
|
||||
|
13
dbmtool.c
13
dbmtool.c
@ -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
|
||||
*
|
||||
* 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, "\ti = import\n");
|
||||
fprintf(stderr, "\tr = repair\n");
|
||||
fprintf(stderr, "\tE = Export To DIR\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
init_tools(0, 0);
|
||||
nw_debug=5;
|
||||
if (argc < 2) return(usage(argv[0]));
|
||||
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] == 'r') if (!do_export_dbm(argv[2]))
|
||||
return(do_import_dbm(argv[2]));
|
||||
else return(1);
|
||||
else if (*argv[1] == 'r') {
|
||||
if (!do_export_dbm(argv[2]))
|
||||
return(do_import_dbm(argv[2]));
|
||||
else return(1);
|
||||
}
|
||||
if (*argv[1] == 'E') return(do_export_dbm_to_dir());
|
||||
else usage(argv[0]);
|
||||
return(0);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
#define D_FN_NAMES 8
|
||||
#define D_FN_SEARCH 0x10 /* file search */
|
||||
|
||||
#define D_ACCESS 0x20 /* access rights */
|
||||
#define D_TRUSTEES 0x40 /* trustees */
|
||||
|
||||
/* NWBIND */
|
||||
#define D_BIND_REQ 0x8000 /* all Requests */
|
||||
|
43
doc/BUGS.nl
Normal file
43
doc/BUGS.nl
Normal 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
|
135
doc/CHANGES
135
doc/CHANGES
@ -1,6 +1,8 @@
|
||||
Sorry, this is in German only.
|
||||
Sorry, beginning is in German only.
|
||||
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
|
||||
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
|
||||
@ -408,6 +410,131 @@ Erste 'oeffentliche' Version
|
||||
- archive bit ist bei Dateien nun default gesetzt.
|
||||
- archive bit wird nun bei Client Schreiboperationen gesetzt.
|
||||
<----- ^^^^^^^^^^ 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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
48
doc/CREDITS
48
doc/CREDITS
@ -16,6 +16,9 @@ Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
|
||||
Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
|
||||
many testings+notes
|
||||
|
||||
Valeri Bourak <bvn@kali.belpak.minsk.by>
|
||||
added some code
|
||||
|
||||
Arne de Bruijn <arne@knoware.nl>
|
||||
testings, exploring ncp mysterius (netx), notes
|
||||
|
||||
@ -26,17 +29,26 @@ Csoma Csaba <csoma@usa.net>
|
||||
testings+bugfixes
|
||||
|
||||
Przemyslaw Czerpak <przemyslaw.czerpak@students.mimuw.edu.pl>
|
||||
testings+bugfixes
|
||||
testings+bugfixes+more bugfixes (pcz:)
|
||||
|
||||
Ales Dryak <A.Dryak@sh.cvut.cz>
|
||||
his linware gave the kick
|
||||
|
||||
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>
|
||||
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>
|
||||
cyrillic filename patches
|
||||
|
||||
@ -61,9 +73,21 @@ James B. MacLean <macleajb@ednet.ns.ca>
|
||||
Louis Zammit Mangion <lzamm@phys.um.edu.mt>
|
||||
testings+bugfixes
|
||||
|
||||
Mendel Mobach <mendel@mobach.nl>
|
||||
some doku
|
||||
|
||||
Norbert Nemec <nobbi@cheerful.com>
|
||||
some patches
|
||||
|
||||
Matt Paley <mtpa@mail.nerc-bas.ac.uk>
|
||||
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>
|
||||
testing bindery code
|
||||
|
||||
@ -76,8 +100,13 @@ Mr. Charlie Root (alexey) <root@cs.imi.udmurtia.su>
|
||||
Andrew Sapozhnikov <sapa@hq.icb.chel.su>
|
||||
fixed findfirst/findnext bug,
|
||||
fixed directory access bug,
|
||||
added extend "Volume is home" feature.
|
||||
fixed "rename wildcard" bug.
|
||||
added extend "Volume is home" feature,
|
||||
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>
|
||||
added patch to let ATARI client work.
|
||||
@ -85,13 +114,20 @@ Hayo Schmidt <100305.1424@compuserve.com>
|
||||
Gregory Steuck <greg@nsu.ru>
|
||||
testings and errorreports
|
||||
|
||||
Neal Stephenson <neal@nstephenson.gw.yorku.ca>
|
||||
patch for glibc6
|
||||
|
||||
Morio Taneda <eb04@rz.uni-karlsruhe.de>
|
||||
testings, bugfixes
|
||||
|
||||
Erik Thiele <erik@escape.mos.unterland.de>
|
||||
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'
|
||||
|
||||
|
||||
Jukka Ukkonen <jau@iki.fi>
|
||||
small patches
|
||||
|
6
doc/FAQS
6
doc/FAQS
@ -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?
|
||||
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
|
||||
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:
|
||||
12,13
|
||||
What will happen if I do not put PASSWORD here? Will it take it from
|
||||
|
85
doc/FILESHARING
Normal file
85
doc/FILESHARING
Normal 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
|
||||
---------------------------------------------
|
||||
|
||||
|
||||
|
@ -330,9 +330,7 @@ ersten Start von "nwserv" angelegt. Der Volume-Name ist ueblicherweise
|
||||
"SYS".
|
||||
Beim Anlegen und Eintragen der Optionen fuer das Volume SYS unbedingt
|
||||
auf Gross- und Kleinschreibung achten, sonst sind diese Dateien
|
||||
nachher fuer den Client nicht Sichtbar. Alle weiteren Volumes sind
|
||||
Optional und koennen beliebige Verzeichnisse (ausser /) freigeben.
|
||||
Auf Verzeichniss "/" hat nur der root=Supervisor Zugriff. Volumes
|
||||
nachher fuer den Client nicht sichtbar. Volumes
|
||||
koennen mit NFS gemountete Verzeichnisse, CD-Roms, Floppys und
|
||||
beliebige unter Linux mountbare Filesystems sein. Die einzige
|
||||
Einschraenkung besteht in der Beschraenkung auf entweder alles gross
|
||||
|
@ -132,5 +132,5 @@ the mars_nwe-package.
|
||||
|
||||
good luck :-)
|
||||
|
||||
Martin Stover <mstover@stover.f.eunet.de>
|
||||
Martin Stover <mstover@compu-art.de>
|
||||
|
||||
|
133
doc/INSTALL.nl
Normal file
133
doc/INSTALL.nl
Normal 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>
|
13
doc/NEWS
13
doc/NEWS
@ -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 ---------
|
||||
- archive bit handling changed. (default set if file, unset if directory)
|
||||
- section 5: deleting of ipx devices/routes changed.
|
||||
|
15
doc/PIPE-FS
15
doc/PIPE-FS
@ -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.
|
||||
|
||||
In the examples dir exist the two programpairs comm<->unxcomm
|
||||
and sendm<->unxsendm as additional examples for using 'PIPE-filesystem'.
|
||||
With comm/unxcomm it is very easy to start simple Linux programs
|
||||
by your client.
|
||||
for examples: ps, lpq, lprm ...
|
||||
In the examples directory there are two pairs of programs,
|
||||
comm<->unxcomm und sendm<->unxsendm, that provide further examples
|
||||
of how to use the PIPE-filesystem.
|
||||
Using comm/unxcomm it is very easy to invoke simple Linux programs
|
||||
from the client, e.g. ps, lpq, lprm ..
|
||||
|
||||
I would appreciate hearing about further documented applications of
|
||||
the PIPE filesystem or suggestions for other ways of using it.
|
||||
If anyone has other documented applications of the PIPE-filesystem,
|
||||
or any suggestions about other ways it might be used, I'd be very glad
|
||||
to hear from them.
|
||||
|
||||
Martin
|
||||
|
@ -1,4 +1,7 @@
|
||||
/* PIPE- Filesystem */
|
||||
|
||||
1. Was sind PIPEs?
|
||||
|
||||
das 'PIPE Filesystem' entstand urspruenglich aus der Frage heraus:
|
||||
Wie kann ich ein Linux System oder Teile davon ueber/auf einen
|
||||
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
|
||||
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
|
||||
Shell Script, welches im PIPE-Filesystem hinterlegt wurde.
|
||||
|
||||
@ -29,7 +36,7 @@ case "$1" in
|
||||
# save directory /u3/mar
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
;;
|
||||
esac
|
||||
|
||||
Unter DOS kann nun diese 'Pipe Datei' mit dem Copy Befehl in eine
|
||||
@ -37,6 +44,8 @@ lokale Datei 'kopiert' werden ( -> Sichern ) bzw. es
|
||||
kann die lokale Datei auf diese 'Pipe Datei' kopiert werden.
|
||||
( -> Ruecksichern )
|
||||
|
||||
2.2 Drucken ueber Pipes
|
||||
|
||||
Ein einfaches Drucken kann z.B. mit folgendem Mini Script realisiert werden.
|
||||
Anstatt des Scriptes reicht in diesem Fall natuerlich auch ein link auf
|
||||
/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.
|
||||
|
||||
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
|
||||
die Programmpaare unxcomm<->comm und sendm<->unxsendm.
|
||||
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.
|
||||
|
||||
Martin
|
||||
|
||||
|
@ -68,7 +68,7 @@ nwbind:
|
||||
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
|
||||
linware ( lwared ), the NetWare-Emulator from
|
||||
|
74
doc/README.FREEBSD
Normal file
74
doc/README.FREEBSD
Normal 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.
|
||||
|
@ -68,7 +68,7 @@ der fehlenden bzw. fehlerhaften NCP-Calls wuerde ich mich freuen.
|
||||
|
||||
|
||||
Martin
|
||||
<mstover@stover.f.eunet.de>
|
||||
<mstover@compu-art.de>
|
||||
|
||||
PS: Den Anstoss, mars_nwe zu veroeffentlichen, gab die
|
||||
Veroeffentlichung von linware ( lwared ), dem Novell-Server-Emulator
|
||||
|
72
doc/TRUSTEES
Normal file
72
doc/TRUSTEES
Normal 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
30
doc/VRAGEN.NL
Normal 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.
|
||||
|
@ -1,16 +1,16 @@
|
||||
Begin3
|
||||
Title: mars_nwe
|
||||
Version: 0.99.pl6
|
||||
Entered-date: 09-Feb-98
|
||||
Description: Full netware-emulator (src), beta.
|
||||
Version: 0.99.pl19
|
||||
Entered-date: 25-Apr-00
|
||||
Description: Full netware 3.xx emulator (src), beta.
|
||||
Supports file-services, bindery-services,
|
||||
printing-services, routing-services.
|
||||
Keywords: novell, netware, server, ipx, ncp, tli
|
||||
Author: mstover@compu-art.de (Martin Stover)
|
||||
Maintained-by: mstover@compu-art.de (Martin Stover)
|
||||
Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl6.tgz
|
||||
250 kB
|
||||
Alternate-site: ftp://gwdg.de/pub/linux/misc/ncpfs/mars_nwe-0.99.pl6.tgz
|
||||
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx)
|
||||
Copying-policy: GNU
|
||||
Primary-site: http://www.compu-art.de/download/mars_nwe-0.99.pl19.tgz
|
||||
320 kB
|
||||
Alternate-site: ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/mars_nwe/mars_nwe-0.99.pl19.tgz
|
||||
Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), FreeBSD, UnixWare (2.xx)
|
||||
Copying-policy: GPL
|
||||
End
|
||||
|
110
emutli.c
110
emutli.c
@ -1,4 +1,4 @@
|
||||
/* emutli.c 07-Jul-97 */
|
||||
/* emutli.c 04-Apr-00 */
|
||||
/*
|
||||
* One short try to emulate TLI with SOCKETS.
|
||||
*/
|
||||
@ -20,24 +20,18 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "net.h"
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/sockios.h>
|
||||
#include "net.h"
|
||||
#include <linux/if.h>
|
||||
#include <linux/route.h>
|
||||
#include <linux/in.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef DO_IPX_SEND_TEST
|
||||
# define DO_IPX_SEND_TEST 2
|
||||
# define DO_IPX_SEND_TEST 0
|
||||
#endif
|
||||
|
||||
/* DO_IPX_SEND_TEST is only needed if the ipx sendmsg() bug is not patched
|
||||
@ -55,6 +49,9 @@
|
||||
*/
|
||||
|
||||
static int locipxdebug=0;
|
||||
#ifdef FREEBSD
|
||||
static struct ipx_addr fbsd_ipx;
|
||||
#endif
|
||||
|
||||
void set_locipxdebug(int debug)
|
||||
{
|
||||
@ -86,12 +83,31 @@ void set_emu_tli(void)
|
||||
{
|
||||
int i = get_ini_int(100);
|
||||
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 opt=1;
|
||||
#ifdef FREEBSD
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, 0);
|
||||
#else
|
||||
int sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
|
||||
#endif
|
||||
if (sock < 0) return(sock);
|
||||
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))
|
||||
ipx2sockadr(&ipxs, (ipxAddr_t*) (a_in->addr.buf));
|
||||
|
||||
|
||||
#ifndef FREEBSD
|
||||
ipxs.sipx_network = 0L; /* allways default net */
|
||||
|
||||
memset(ipxs.sipx_node, 0, IPX_NODE_SIZE); /* allways default node */
|
||||
/* 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) {
|
||||
errorp(0, "TLI-BIND", "socket Nr:0x%x", (int)GET_BE16(&(ipxs.sipx_port)));
|
||||
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 (getsockname(sock, (struct sockaddr*)&ipxs, &maxplen) == -1){
|
||||
errorp(0, "TLI-GETSOCKNAME", NULL);
|
||||
@ -180,15 +215,14 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
|
||||
p->revents=0;
|
||||
p++;
|
||||
}
|
||||
if (timeout > 1000) {
|
||||
time_out.tv_sec = timeout / 1000;
|
||||
time_out.tv_usec = 0;
|
||||
} else {
|
||||
time_out.tv_sec = 0;
|
||||
time_out.tv_usec = timeout*1000;
|
||||
}
|
||||
if (0 > (result = select(high_f+1, &readfs, NULL, NULL, &time_out)))
|
||||
|
||||
/* mst:04-Apr-00, patch from (Jukka Ukkonen) */
|
||||
time_out.tv_sec = timeout / 1000;
|
||||
time_out.tv_usec = (timeout % 1000) * 1000;
|
||||
if (0 > (result = select(high_f+1, &readfs, NULL, NULL,
|
||||
(timeout == -1) ? NULL : &time_out)))
|
||||
return(-1);
|
||||
|
||||
if (result) {
|
||||
int rest=result;
|
||||
k = (int)nfds;
|
||||
@ -204,6 +238,7 @@ int poll( struct pollfd *fds, unsigned long nfds, int timeout)
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
|
||||
{
|
||||
struct sockaddr_ipx ipxs;
|
||||
@ -211,6 +246,29 @@ inline int t_rcvudata(int fd, struct t_unitdata *ud, int *flags)
|
||||
int result;
|
||||
ipxs.sipx_family=AF_IPX;
|
||||
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,
|
||||
(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;
|
||||
ud->opt.len = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ud->udata.len=result;
|
||||
sock2ipxadr((ipxAddr_t*) (ud->addr.buf), &ipxs);
|
||||
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));
|
||||
ipxs.sipx_family=AF_IPX;
|
||||
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;
|
||||
#endif
|
||||
result = sendto(fd,(void *)ud->udata.buf,
|
||||
ud->udata.len, 0, (struct sockaddr *) &ipxs, sizeof(ipxs));
|
||||
|
||||
|
24
emutli.h
24
emutli.h
@ -1,4 +1,4 @@
|
||||
/* emutli.h 28-Apr-96 */
|
||||
/* emutli.h 18-Nov-99 */
|
||||
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -20,7 +20,27 @@
|
||||
#ifndef _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 short int uint16;
|
||||
|
117
emutli1.c
117
emutli1.c
@ -1,4 +1,4 @@
|
||||
/* emutli1.c 10-Apr-97 */
|
||||
/* emutli1.c 05-May-98 */
|
||||
/*
|
||||
* One short try to emulate TLI with SOCKETS.
|
||||
*/
|
||||
@ -34,13 +34,19 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/sockios.h>
|
||||
#if 0
|
||||
# include <linux/sockios.h>
|
||||
#endif
|
||||
#include "net.h"
|
||||
#include <linux/if.h>
|
||||
#include <linux/route.h>
|
||||
#include <linux/in.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#if 0
|
||||
# include <linux/if.h>
|
||||
# include <linux/route.h>
|
||||
# include <linux/in.h>
|
||||
#else
|
||||
# include <net/if.h>
|
||||
# include <net/route.h>
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
static int have_ipx_started=0;
|
||||
@ -154,7 +160,10 @@ static void del_special_net(int special, char *devname, int frame)
|
||||
if (frame < 0) continue;
|
||||
sipx->sipx_type = frame;
|
||||
if (flags & 1) { /* primary */
|
||||
strcpy(id.ifr_name, name);
|
||||
if (flags & 2){ /* primary == internal net */
|
||||
sipx->sipx_special = IPX_INTERNAL;
|
||||
} else
|
||||
strcpy(id.ifr_name, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -273,10 +282,49 @@ int get_frame_name(uint8 *framename, int frame)
|
||||
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 result=-1;
|
||||
int sock;
|
||||
uint32 primary_net=0L;
|
||||
#if INTERNAL_RIP_SAP
|
||||
# ifdef CONFIG_IPX_INTERN
|
||||
errorp(11, "!! configuration error !!",
|
||||
@ -293,36 +341,49 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug, int flags)
|
||||
exit(1);
|
||||
} else {
|
||||
ipx_config_data cfgdata;
|
||||
struct sockaddr_ipx ipxs;
|
||||
ioctl(sock, SIOCIPXCFGDATA, &cfgdata);
|
||||
org_auto_interfaces =
|
||||
auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces;
|
||||
set_sock_debug(sock);
|
||||
result=0;
|
||||
|
||||
/* build new internal net */
|
||||
if (network) {
|
||||
struct sockaddr_ipx ipxs;
|
||||
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));
|
||||
ipxs.sipx_port = htons(SOCK_NCP);
|
||||
ipxs.sipx_family = AF_IPX;
|
||||
if (bind(sock, (struct sockaddr*)&ipxs,
|
||||
sizeof(struct sockaddr_ipx))==-1) {
|
||||
if (errno == EEXIST || errno == EADDRINUSE) result = -1;
|
||||
}
|
||||
if (result) {
|
||||
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));
|
||||
ipxs.sipx_port = htons(SOCK_NCP);
|
||||
ipxs.sipx_family = AF_IPX;
|
||||
if (bind(sock, (struct sockaddr*)&ipxs,
|
||||
sizeof(struct sockaddr_ipx))==-1) {
|
||||
if (errno == EEXIST || errno == EADDRINUSE) {
|
||||
result = -1;
|
||||
errorp(1, "EMUTLI:init_ipx socket 0x451", NULL);
|
||||
exit(1);
|
||||
}
|
||||
del_internal_net();
|
||||
add_internal_net(network, node);
|
||||
} else {
|
||||
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++;
|
||||
}
|
||||
|
||||
if ((flags & 2) && !auto_interfaces) { /* set auto interfaces */
|
||||
auto_interfaces = 1;
|
||||
ioctl(sock, SIOCAIPXITFCRT, &auto_interfaces);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
}
|
||||
return(result);
|
||||
@ -341,8 +402,10 @@ void exit_ipx(int flags)
|
||||
ioctl(sock, SIOCAIPXITFCRT, &org_auto_interfaces);
|
||||
close(sock);
|
||||
}
|
||||
if (have_ipx_started && flags&4) {
|
||||
if (flags&4) {
|
||||
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 (wildmask) return(-99);
|
||||
have_ipx_started++;
|
||||
del_primary_net();
|
||||
add_primary_net(devname, frame, network);
|
||||
if (!ipx_inuse(0)) {
|
||||
del_primary_net();
|
||||
add_primary_net(devname, frame, network);
|
||||
}
|
||||
} else {
|
||||
if (!wildmask)
|
||||
return(add_device_net(devname, frame, network));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* emutli1.h 10-Apr-97 */
|
||||
/* emutli1.h 05-May-98 */
|
||||
|
||||
/* (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 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 void exit_ipx(int full);
|
||||
extern int init_dev(char *devname, int frame, uint32 network, int wildmask);
|
||||
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,
|
||||
uint32 route_net,
|
||||
uint8 *route_node);
|
||||
|
202
examples/comm.c
202
examples/comm.c
@ -1,17 +1,33 @@
|
||||
/*
|
||||
/* comm.c 22-Oct-98
|
||||
* 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 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"
|
||||
|
||||
#ifdef LINUX
|
||||
# define DEFAULT_COMM "/pipes/unxcomm"
|
||||
#else
|
||||
# ifdef DEFAULT_UNC
|
||||
# define DEFAULT_COMM DEFAULT_UNC
|
||||
# else
|
||||
# define DEFAULT_COMM "p:/unxcomm"
|
||||
# define DEFAULT_COMM "p:/unxcomm"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -19,6 +35,8 @@
|
||||
#include <stddef.h>
|
||||
#ifndef LINUX
|
||||
# include <io.h>
|
||||
#else
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
@ -28,32 +46,172 @@ static int usage(char *progname)
|
||||
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)
|
||||
{
|
||||
char *unxcomm=getenv(ENV_UNXCOMM);
|
||||
if (NULL == unxcomm) unxcomm=DEFAULT_COMM;
|
||||
if (argc > 1) {
|
||||
int fdout = open(unxcomm, O_RDWR);
|
||||
int fdin = dup(fdout);
|
||||
if (fdout > -1 && fdin > -1) {
|
||||
char **pp=argv+1;
|
||||
unsigned char b=32;
|
||||
int size;
|
||||
int buf[512];
|
||||
while(--argc) {
|
||||
write(fdout, *pp, strlen(*pp));
|
||||
++pp;
|
||||
write(fdout, &b, 1);
|
||||
char **pp=argv+1;
|
||||
int size;
|
||||
char buf[MAXARGLEN+1024];
|
||||
HANDLE fdin = loc_open(unxcomm, O_RDONLY|O_BINARY);
|
||||
int fdout = -1;
|
||||
#ifdef WIN32
|
||||
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);
|
||||
}
|
||||
}
|
||||
#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++;
|
||||
}
|
||||
b=0;
|
||||
write(fdout, &b, 1);
|
||||
close(fdout);
|
||||
|
||||
while (0 < (size = read(fdin, buf, sizeof(buf)))) {
|
||||
write(1, buf, size);
|
||||
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);
|
||||
}
|
||||
close(fdin);
|
||||
return(0);
|
||||
|
||||
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);
|
||||
|
||||
loc_lseek(fdin, 0, 0);
|
||||
memset(buf, 0, 512);
|
||||
|
||||
while (0 < (size = loc_read(fdin, buf, 512 /*sizeof(buf)*/))) {
|
||||
write(1, buf, size);
|
||||
loc_lseek(fdin, 0, 2);
|
||||
}
|
||||
|
||||
loc_close(fdin);
|
||||
return(0);
|
||||
}
|
||||
loc_close(fdin);
|
||||
} else
|
||||
fprintf(stderr, "Cannot open PIPECOMMAND '%s'\n", unxcomm);
|
||||
}
|
||||
|
Binary file not shown.
BIN
examples/comm32.exe
Normal file
BIN
examples/comm32.exe
Normal file
Binary file not shown.
@ -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 */
|
||||
|
||||
#define DO_DEBUG 1 /* compile in debug code */
|
||||
@ -14,7 +14,7 @@
|
||||
# define FILENAME_NW_INI "/etc/nwserv.conf"
|
||||
/* full name of ini (conf) file */
|
||||
# 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
|
||||
|
||||
#define PATHNAME_PIDFILES "/var/run" /* directory for 'pidfiles' */
|
||||
@ -77,9 +77,7 @@
|
||||
|
||||
#define PERSISTENT_SYMLINKS 0 /* change to '1' for persistent symlinks */
|
||||
/* main idea from Victor Khimenko */
|
||||
/* in 0.99.pl0 still NOT working !! */
|
||||
|
||||
#define NEW_ATTRIB_HANDLING 0 /* better (if working ;)) attrib handling */
|
||||
/* still NOT working !! */
|
||||
|
||||
/* <--------------- next is for linux only ----------------------------> */
|
||||
#define INTERNAL_RIP_SAP 1 /* use internal/own rip/sap routines */
|
||||
|
BIN
examples/e.pck
Normal file
BIN
examples/e.pck
Normal file
Binary file not shown.
1
examples/mk
Executable file
1
examples/mk
Executable file
@ -0,0 +1 @@
|
||||
make unxcomm && mv unxcomm /u3/pipes/.
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# mk.li 10-Jul-97
|
||||
# mk.li 15-Dec-99
|
||||
# please edit this file !
|
||||
|
||||
mk()
|
||||
@ -43,7 +43,8 @@ case $UNX in
|
||||
CPP="cc -E"
|
||||
# CFLAGS="-pipe -O2 -fomit-frame-pointer"
|
||||
# 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
|
||||
sparc)
|
||||
@ -59,7 +60,17 @@ if [ -f /usr/lib/libgdbm.a ] || [ -f /usr/lib/libgdbm.so ] ; then
|
||||
else
|
||||
NDBMLIB="-ldbm"
|
||||
fi
|
||||
|
||||
if [ -f /usr/lib/libcrypt.so ] ; then
|
||||
CRYPTLIB="-lcrypt"
|
||||
else
|
||||
CRYPTLIB=""
|
||||
fi
|
||||
|
||||
if [ -f /usr/include/sys/quota.h ] ; then
|
||||
HOSTCFLAGS="$HOSTCFLAGS -DQTAINSYS"
|
||||
fi
|
||||
|
||||
NSLLIB=""
|
||||
MAKE=make
|
||||
TMP=/tmp
|
||||
@ -80,6 +91,28 @@ fi
|
||||
TMP=/tmp
|
||||
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"
|
||||
;;
|
||||
esac
|
||||
@ -95,7 +128,9 @@ esac
|
||||
|
||||
export CC
|
||||
export CPP
|
||||
export CFLAGS
|
||||
if [ "X$CFLAGS" != "Xnative" ]; then
|
||||
export CFLAGS
|
||||
fi
|
||||
export HOSTCFLAGS
|
||||
export NDBMLIB
|
||||
export CRYPTLIB
|
||||
|
127
examples/nw.ini
127
examples/nw.ini
@ -2,10 +2,13 @@
|
||||
# This is the configuration-file for "mars_nwe", a free netware-emulator
|
||||
# for Linux.
|
||||
#
|
||||
# last changed: 08-Feb-98
|
||||
#
|
||||
# !! section 5 : deleting of ipx devices/routes changed in 0.99.pl6 !!
|
||||
# !! section 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
|
||||
# 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 4 : automatic creation of ipx-interfaces changed in 0.98.pl9 !!
|
||||
#
|
||||
# since version 0.98.pl11:
|
||||
# the most important options in config.h can now be altered in
|
||||
@ -97,15 +100,18 @@
|
||||
#
|
||||
# OPTIONS: none or some of the following characters (without a seperator)
|
||||
# - Placeholder.
|
||||
#
|
||||
# Next two options control DOS and OS/2 namespace.
|
||||
# i ignore case, handle mixing upper/lowercase filenames (slow)
|
||||
# should only be used if you really need it.
|
||||
# k use lowercase-filenames (if you don't set this,
|
||||
# and you don't set 'i' all files _must_ be upper-case)
|
||||
#
|
||||
# m removable volume (e.g. cd-roms) or volumes, which
|
||||
# should be remountable when mars_nwe is running.
|
||||
# r volume is read-only and always reports "0 byte free"
|
||||
# (this is intended for copies of CD-ROMs on harddisks)
|
||||
# n (n)o fixed inodes. This volume do not have fixed inodes.
|
||||
# e.g. DOS-Volumes, CD-ROMS. This flag is very important for
|
||||
# attrib and trustee handling.
|
||||
# o (lowercase o)
|
||||
# volume has only one filesystem/device/namespace
|
||||
# this is for filesystems with high inode > 0xFFFFFFF.
|
||||
@ -114,6 +120,17 @@
|
||||
# between several devices/namespaces for one volume.
|
||||
# p "PIPE"-filesystem. All files are pipe commands.
|
||||
# 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
|
||||
# O (uppercase o)
|
||||
@ -123,21 +140,21 @@
|
||||
#
|
||||
# UMASKDIR: default directory creat umask.
|
||||
# UMASKFILE: default file creat umask.
|
||||
# value are always octal, overwrite standard section 9 entries
|
||||
# for this specific volume.
|
||||
# values are always octal, they overwrite standard
|
||||
# section 9 values for this specific volume.
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
# Examples:
|
||||
# 1 SYS /var/local/nwe/SYS k
|
||||
# 1 CDROM /cdrom kmor
|
||||
# 1 SYS /var/local/nwe/SYS kt 711 600
|
||||
# 1 CDROM /cdrom kmnor
|
||||
# 1 HOME ~ k -1
|
||||
# 1 HOMETMP ~/tmp kiO
|
||||
# 1 PRIVAT ~/privat kO 700 600
|
||||
# 1 WORLD /var/world kiO 777 666
|
||||
# 1 FAXQ /var/spool/fax/faxqueue k
|
||||
|
||||
|
||||
1 SYS /u3/SYS/ k -1
|
||||
1 SYS /u3/SYS/ kt 711 600
|
||||
|
||||
|
||||
# =========================================================================
|
||||
@ -297,18 +314,24 @@
|
||||
# beyond the lifetime of the server or router.
|
||||
# If this flag is not set then all by nwserv/nwrouted added
|
||||
# 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.
|
||||
# The automatic kernel creating of ipx-devices sometimes
|
||||
# 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
|
||||
# beyond the lifetime of the server or router.
|
||||
# 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 also do complete ipx reinit when starting
|
||||
# mars_nwe.
|
||||
# This was the default prior mars_nwe 0.99.pl9 !
|
||||
#
|
||||
#
|
||||
#
|
||||
# other flags may follow.
|
||||
@ -412,6 +435,15 @@
|
||||
# in some volume info calls.
|
||||
# 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.
|
||||
# value will be interpreted as hex value.
|
||||
|
||||
@ -426,9 +458,9 @@
|
||||
# if -1 is specified for directories the st_mode of parent directory
|
||||
# will be used.
|
||||
# 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
|
||||
# =========================================================================
|
||||
@ -536,17 +568,19 @@
|
||||
# a '-' sign as password.
|
||||
# -------------------------------------------------------------------------
|
||||
# Syntax:
|
||||
# 13 NW_LOGIN LINUX_LOGIN [PASSWORD] [FLAGS]
|
||||
# 13 NW_LOGIN [LINUX_LOGIN] [PASSWORD] [FLAGS]
|
||||
#
|
||||
# FLAGS must be a hex value begin with 0x
|
||||
# the only FLAG value in the moment is 0x1 for 'fixed passwords'
|
||||
# which cannot be changed by user.
|
||||
# Example:
|
||||
# 13 MARTIN
|
||||
# 13 MARTIN martin
|
||||
# 13 DAREK martin
|
||||
# 13 COMMON common gast 0x1 # no password change by user.
|
||||
# 13 COMMON common 0x1 # syntax is allowed too.
|
||||
|
||||
13 GUEST nobody - 0x1
|
||||
|
||||
# Section 14: currently not used
|
||||
|
||||
@ -594,21 +628,45 @@
|
||||
15 0 top-secret
|
||||
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# 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:
|
||||
# SYS:LOGIN, SYS:MAIL, SYS:MAIL/XXX, SYS:PUBLIC, SYS:SYSTEM ...
|
||||
# (with the "right" permissions, of course) if you enable this.
|
||||
# should also be enabled when you use a new mars_nwe version.
|
||||
# Disabling this test only spares little time when starting mars_nwe.
|
||||
# some values:
|
||||
# 1 few important tests.
|
||||
# 2 also check/compress bindery.
|
||||
|
||||
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:
|
||||
# 21 LASER - lpr -Plaser
|
||||
# 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
|
||||
# -------------------------------------------------------------------------
|
||||
# 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:
|
||||
# 22 PS1 OCTOPUSS
|
||||
|
||||
22 PS_NWE LP_PS 1
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# Section 30: Burst mode values (optional)
|
||||
@ -675,6 +743,13 @@
|
||||
# 30 0x2000 0x2000
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# Section 31: not used yet
|
||||
# =========================================================================
|
||||
# Flags not used yet
|
||||
#
|
||||
31 0x0
|
||||
|
||||
# =========================================================================
|
||||
# Section 40ff: Some pathes (optional)
|
||||
#
|
||||
@ -688,9 +763,11 @@
|
||||
#
|
||||
#
|
||||
# 45 = path for bindery file's
|
||||
45 /etc
|
||||
# 46 = path for attribute handling and later trustees
|
||||
46 /var/lib/nwserv/attrib
|
||||
45 /var/nwserv/db
|
||||
# 46 = path for attribute handling
|
||||
46 /var/nwserv/attrib
|
||||
# 47 = path for trustee handling
|
||||
47 /var/nwserv/trustees
|
||||
# =========================================================================
|
||||
# Section 50: Conversion tables by Victor Khimenko <khim@mccme.ru>
|
||||
# Tables for DOS->Unix names translation & upper/lowercase translations
|
||||
|
@ -1,6 +1,7 @@
|
||||
# example for nwopt file.
|
||||
# !!!! NOT USED !!!!!
|
||||
#
|
||||
# last changed: 18-Nov-97
|
||||
# last changed: 10-May-98
|
||||
#
|
||||
# Syntax similar like nwserv.conf file.
|
||||
#
|
||||
|
@ -1,12 +1,21 @@
|
||||
/* unxcomm.c 08-Jun-97 */
|
||||
/* simple UNX program to work together with 'comm' */
|
||||
/* to demonstrate usage of pipefilesystem */
|
||||
/* unxcomm.c 22-Oct-98
|
||||
* simple UNX program to work together with 'comm'
|
||||
* 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 <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.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)
|
||||
/* routine returns **argv for use with execv routines */
|
||||
@ -51,8 +60,8 @@ int bl_read(int fd, void *buf, int size)
|
||||
int result;
|
||||
FD_ZERO(&fdin);
|
||||
FD_SET(fd, &fdin);
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 100; /* 100 msec should be enough */
|
||||
t.tv_sec = 1;
|
||||
t.tv_usec = 0;
|
||||
result = select(fd+1, &fdin, NULL, NULL, &t);
|
||||
if (result > 0)
|
||||
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 size=0;
|
||||
int l;
|
||||
int size=-1;
|
||||
int pid=getpid();
|
||||
char buf[MAXARGLEN+1024];
|
||||
char fifopath[257];
|
||||
char *p;
|
||||
|
||||
close(2);
|
||||
dup2(1,2);
|
||||
|
||||
while (0 < (l=bl_read(0, buf+size, MAXARGLEN-size)))
|
||||
size+=l;
|
||||
|
||||
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;
|
||||
}
|
||||
if (size && buf[size-1] == '\0') break;
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
perror("open fifo");
|
||||
size=-1;
|
||||
}
|
||||
unlink(fifopath);
|
||||
}
|
||||
if ( 0 < size) {
|
||||
char **argvv=build_argv(sizeof(buf), buf, size);
|
||||
if (argvv) {
|
||||
|
34
extpipe.c
34
extpipe.c
@ -1,4 +1,4 @@
|
||||
/* extpipe.c 08-Aug-97 */
|
||||
/* extpipe.c 03-Aug-98 */
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -19,7 +19,7 @@
|
||||
#include "net.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 */
|
||||
/* buf will contain the path component */
|
||||
{
|
||||
@ -43,7 +43,7 @@ static char **build_argv(char *buf, int bufsize, char *command)
|
||||
*(++pp)=p;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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 lpid=-1;
|
||||
int j=3;
|
||||
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);
|
||||
while (j--){
|
||||
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 (uid > -1) seteuid(uid);
|
||||
}
|
||||
execvp(buf, argv);
|
||||
if (flags&1)
|
||||
execvp(buf, argv);
|
||||
else
|
||||
execv(buf, argv);
|
||||
exit(1); /* Never reached I hope */
|
||||
}
|
||||
j=-1;
|
||||
@ -134,12 +137,18 @@ int ext_pclose(FILE_PIPE *fp)
|
||||
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
|
||||
void (*hupsave) (int) = signal(SIGHUP, SIG_IGN);
|
||||
int j = 3;
|
||||
int tries=5;
|
||||
while (j--) close(fp->fds[j]);
|
||||
if (fp->command_pid != waitpid(fp->command_pid, &status, 0)) {
|
||||
kill(fp->command_pid, SIGTERM);
|
||||
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);
|
||||
else if (!tries)
|
||||
kill(fp->command_pid, SIGKILL);
|
||||
sleep(1);
|
||||
}
|
||||
kill(fp->command_pid, SIGKILL);
|
||||
signal(SIGINT, intsave);
|
||||
signal(SIGQUIT, quitsave);
|
||||
signal(SIGHUP, hupsave);
|
||||
@ -147,13 +156,14 @@ int ext_pclose(FILE_PIPE *fp)
|
||||
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));
|
||||
void (*intsave) (int) = signal(SIGINT, SIG_IGN);
|
||||
void (*quitsave)(int) = signal(SIGQUIT, 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);
|
||||
fp=NULL;
|
||||
XDPRINTF((1, 0x10, "ext_popen failed:uid=%d, gid=%d,command='%s'",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* extpipe.h 08-Aug-97 */
|
||||
/* extpipe.h 31-Jul-98 */
|
||||
|
||||
#ifndef _EXTPIPE_H_
|
||||
#define _EXTPIPE_H_
|
||||
@ -11,6 +11,6 @@ typedef struct {
|
||||
} FILE_PIPE;
|
||||
|
||||
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
|
||||
|
233
ftrustee.c
Normal file
233
ftrustee.c
Normal 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
197
ipxif.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
58
makefile.unx
58
makefile.unx
@ -1,5 +1,5 @@
|
||||
#if 0
|
||||
#makefile.unx 04-Feb-98
|
||||
#makefile.unx 15-Apr-00
|
||||
#endif
|
||||
|
||||
VPATH=$(V_VPATH)
|
||||
@ -9,7 +9,7 @@ C=.c
|
||||
|
||||
V_H=0
|
||||
V_L=99
|
||||
P_L=6
|
||||
P_L=19
|
||||
|
||||
#define D_P_L 1
|
||||
DISTRIB=mars_nwe
|
||||
@ -79,6 +79,7 @@ PROG5=nwclient
|
||||
PROG6=nwbind
|
||||
PROG7=nwrouted
|
||||
PROG8=dbmtool
|
||||
PROG9=ftrustee
|
||||
|
||||
#include "config.h"
|
||||
#ifdef FILENAME_NW_INI
|
||||
@ -93,45 +94,55 @@ M_PATHNAME_PROGS=PATHNAME_PROGS
|
||||
M_PATHNAME_PROGS="."
|
||||
#endif
|
||||
|
||||
#ifndef INTERNAL_RIP_SAP
|
||||
#define INTERNAL_RIP_SAP 1
|
||||
#endif
|
||||
M_PATHNAME_BINDERY=PATHNAME_BINDERY
|
||||
|
||||
#ifdef LINUX
|
||||
EMUTLIOBJ=emutli$(O)
|
||||
EMUTLIOBJ1=emutli1$(O)
|
||||
# if INTERNAL_RIP_SAP
|
||||
NWROUTE_O=nwroute$(O)
|
||||
# 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)
|
||||
# if INTERNAL_RIP_SAP
|
||||
EMUTLIOBJ1=emutli1$(O)
|
||||
NWROUTE_O=nwroute$(O)
|
||||
# else
|
||||
EMUTLIOBJ1=
|
||||
NWROUTE_O=nwroute1$(O)
|
||||
NWROUTED=$(PROG7)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
NWROUTE_O=nwroute1$(O)
|
||||
NWROUTED=
|
||||
#endif
|
||||
|
||||
INSTALLPROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(NWROUTED)
|
||||
PROGS=$(INSTALLPROGS) $(PROG8)
|
||||
PROGS=$(INSTALLPROGS) $(PROG8) $(PROG9)
|
||||
|
||||
OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O)
|
||||
OBJ2= $(OBJ1) $(EMUTLIOBJ1) $(NWROUTE_O)
|
||||
OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(O) \
|
||||
nwqconn$(O) nameos2$(O) nwfname$(O) nwshare$(O) extpipe$(O) \
|
||||
nwattrib$(O)
|
||||
nwattrib$(O) trustee$(O)
|
||||
OBJ4= $(OBJ1)
|
||||
OBJ5= $(OBJ1)
|
||||
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O)
|
||||
OBJ7= $(OBJ1) $(EMUTLIOBJ1)
|
||||
OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) unxlog$(O) sema$(O) nwqueue$(O) unxfile$(O)
|
||||
OBJ7= $(OBJ1) emutli1$(O)
|
||||
OBJ8= $(OBJ6)
|
||||
OBJ9= tools$(O) nwfname$(O) unxfile$(O) nwvolume$(O) nwattrib$(O) trustee$(O)
|
||||
|
||||
OBJS= $(EMUTLIOBJ) net1$(O) tools$(O) \
|
||||
$(EMUTLIOBJ1) $(NWROUTE_O) \
|
||||
connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) unxfile$(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) \
|
||||
$(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) \
|
||||
unxfile$(O)
|
||||
@ -168,6 +179,9 @@ $(PROG7): $(PROG7)$(O) $(OBJ7)
|
||||
$(PROG8): $(PROG8)$(O) $(OBJ8)
|
||||
$(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
|
||||
$(HOBJ6): nwbind.h sema.h
|
||||
$(OBJS): net.h config.h
|
||||
@ -195,6 +209,19 @@ n_install:
|
||||
echo "remove old version in /sbin ?" ; \
|
||||
(cd /sbin && rm -i nwserv nwbind ncpserv nwconn nwclient nwrouted) ; \
|
||||
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 \
|
||||
echo ""; \
|
||||
echo "********************************************************"; \
|
||||
@ -246,6 +273,7 @@ make_dir:
|
||||
; ln -f \
|
||||
$(STERN).[ch] \
|
||||
makefile.unx \
|
||||
tools.sh \
|
||||
Makefile \
|
||||
COPYING \
|
||||
README \
|
||||
|
1181
namspace.c
1181
namspace.c
File diff suppressed because it is too large
Load Diff
@ -418,6 +418,10 @@ static void close_all(void)
|
||||
{
|
||||
int k=0;
|
||||
while (k++ < count_connections) clear_connection(k);
|
||||
kill_connections();
|
||||
k=0;
|
||||
while (k++ < count_connections) clear_connection(k);
|
||||
kill_connections();
|
||||
if (ncp_fd > -1) {
|
||||
t_unbind(ncp_fd);
|
||||
t_close(ncp_fd);
|
||||
|
30
net.h
30
net.h
@ -1,4 +1,4 @@
|
||||
/* net.h 02-Jun-97 */
|
||||
/* net.h 12-Jan-99 */
|
||||
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -19,10 +19,21 @@
|
||||
|
||||
#ifndef _M_NET_H_
|
||||
#define _M_NET_H_
|
||||
|
||||
#ifndef _XOPEN_SOURCE
|
||||
# define _XOPEN_SOURCE 1
|
||||
#endif
|
||||
#define _SVID_SOURCE 1
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h> /* moved 12-May-98 0.99.pl9 */
|
||||
|
||||
#include <signal.h>
|
||||
#ifdef __USE_BSD
|
||||
# undef signal
|
||||
# define signal sysv_signal
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#ifndef LINUX
|
||||
@ -31,9 +42,12 @@
|
||||
#endif
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/types.h>
|
||||
/* #include <sys/types.h> moved 12-May-98 0.99.pl9 */
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_ISLNK
|
||||
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <utmp.h>
|
||||
@ -50,7 +64,6 @@ extern int errno;
|
||||
/* # include "common.h" */
|
||||
/* # include "portable.h" , needed ??? */
|
||||
# include <sys/ipx_app.h>
|
||||
|
||||
#else
|
||||
# include <sys/ioctl.h>
|
||||
# include "emutli.h" /* TLI-EMULATION */
|
||||
@ -180,7 +193,7 @@ extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef PATHNAME_BINDERY
|
||||
# define PATHNAME_BINDERY "/etc" /* location of bindery files */
|
||||
# define PATHNAME_BINDERY "/var/nwserv/db" /* location of bindery files */
|
||||
#endif
|
||||
|
||||
#ifndef PATHNAME_PIDFILES
|
||||
@ -280,6 +293,11 @@ extern int errno;
|
||||
# ifndef INTERNAL_RIP_SAP
|
||||
# define INTERNAL_RIP_SAP 1
|
||||
# endif
|
||||
# ifdef FREEBSD
|
||||
/* FreeBSD has own rip/sap router */
|
||||
# undef INTERNAL_RIP_SAP
|
||||
# define INTERNAL_RIP_SAP 0
|
||||
# endif
|
||||
#else
|
||||
/* USL has rip/sap router builtin */
|
||||
# undef INTERNAL_RIP_SAP
|
||||
@ -370,7 +388,7 @@ typedef union {
|
||||
*/
|
||||
} diaresp;
|
||||
struct S_NCPRESPONSE { /* size = 8 */
|
||||
uint8 type[2]; /* 0x3333 */
|
||||
uint8 type[2]; /* 0x3333 or internal 0x3232 */
|
||||
uint8 sequence;
|
||||
uint8 connection; /* low connection */
|
||||
uint8 task;
|
||||
@ -379,7 +397,7 @@ typedef union {
|
||||
uint8 connect_status;
|
||||
} ncpresponse;
|
||||
struct S_NCPREQUEST { /* size = 7 */
|
||||
uint8 type[2]; /* 0x1111 od 0x2222 */
|
||||
uint8 type[2]; /* 0x1111 or 0x2222 or internal 0x1212 */
|
||||
uint8 sequence;
|
||||
uint8 connection; /* low connection */
|
||||
uint8 task;
|
||||
|
43
net1.c
43
net1.c
@ -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
|
||||
* 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);
|
||||
}
|
||||
#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
7
net1.h
@ -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
|
||||
* 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 uint8 *station_fn;
|
||||
extern int find_station_match(int entry, ipxAddr_t *addr);
|
||||
|
||||
#endif
|
||||
|
328
nwattrib.c
328
nwattrib.c
@ -1,4 +1,4 @@
|
||||
/* nwattrib.c 09-Feb-98 */
|
||||
/* nwattrib.c 10-May-98 */
|
||||
/* (C)opyright (C) 1998 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Attrib routines for mars_nwe */
|
||||
|
||||
#include "net.h"
|
||||
#include <dirent.h>
|
||||
#include "unxfile.h"
|
||||
#include "nwvolume.h"
|
||||
#include "connect.h"
|
||||
|
||||
#include "trustee.h"
|
||||
#include "nwattrib.h"
|
||||
|
||||
static void put_attr_to_disk(int dev, ino_t inode, uint32 attrib)
|
||||
@ -86,244 +88,154 @@ static int get_attr_from_disk(int dev, ino_t inode, uint32 *attrib)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
*attrib=0;
|
||||
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 */
|
||||
{
|
||||
uint32 attrib=0;
|
||||
int is_dir=S_ISDIR(stb->st_mode);
|
||||
uint32 attrib = S_ISDIR(stb->st_mode) ? FILE_ATTR_DIR
|
||||
: FILE_ATTR_A;
|
||||
|
||||
if (!is_dir && (voloptions & VOL_OPTION_IS_PIPE))
|
||||
return(FILE_ATTR_SHARE|FILE_ATTR_A);
|
||||
int voloptions = get_volume_options(volume);
|
||||
|
||||
if (voloptions & VOL_OPTION_READONLY)
|
||||
return((is_dir)?FILE_ATTR_DIR|FILE_ATTR_R:FILE_ATTR_R);
|
||||
|
||||
if (!get_attr_from_disk(stb->st_dev, stb->st_ino, &attrib)) {
|
||||
if (is_dir) attrib |= FILE_ATTR_DIR;
|
||||
else attrib &= (~FILE_ATTR_DIR);
|
||||
} else {
|
||||
if (is_dir)
|
||||
attrib = FILE_ATTR_DIR;
|
||||
else
|
||||
attrib = FILE_ATTR_A; /* default archive flag */
|
||||
if (voloptions & VOL_OPTION_IS_PIPE) {
|
||||
attrib |= (FILE_ATTR_DELETE_INH|FILE_ATTR_RENAME_INH);
|
||||
if (!S_ISDIR(stb->st_mode)){
|
||||
attrib|=FILE_ATTR_SHARE;
|
||||
}
|
||||
return(attrib);
|
||||
}
|
||||
|
||||
if (act_uid) {
|
||||
/* if not root */
|
||||
int acc=get_real_access(stb);
|
||||
if (!(acc & W_OK)) {
|
||||
attrib |= FILE_ATTR_R; /* RO */
|
||||
}
|
||||
if (!(acc & R_OK)) {
|
||||
attrib |= FILE_ATTR_H; /* We say hidden here */
|
||||
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 not root */
|
||||
int acc=get_unix_eff_rights(stb);
|
||||
if (!(acc & W_OK)) {
|
||||
attrib |= FILE_ATTR_R; /* RO */
|
||||
}
|
||||
if (!(acc & R_OK)) {
|
||||
attrib |= FILE_ATTR_H; /* We say hidden here */
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
if (voloptions & VOL_OPTION_READONLY)
|
||||
return(-0x8c); /* no modify rights */
|
||||
uint32 oldattrib,newattrib;
|
||||
int voloptions=get_volume_options(volume);
|
||||
if (voloptions & VOL_OPTION_IS_PIPE)
|
||||
return(0);
|
||||
|
||||
if (!(get_real_access(stb) & W_OK))
|
||||
return(0); /* we return with no error */
|
||||
if (tru_eff_rights_exists(volume, unixname, stb, TRUSTEE_M))
|
||||
return(-0x8c); /* no modify rights */
|
||||
|
||||
if (is_dir) attrib |= 0x10;
|
||||
else attrib &= ~0x10;
|
||||
put_attr_to_disk(stb->st_dev, stb->st_ino, attrib);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int set_nw_attrib_byte(struct stat *stb, int voloptions, int battrib)
|
||||
{
|
||||
int is_dir=S_ISDIR(stb->st_mode);
|
||||
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)
|
||||
/* only called for files */
|
||||
{
|
||||
uint32 attrib;
|
||||
if ( (!get_attr_from_disk(dev, inode, &attrib))
|
||||
&& !(attrib & FILE_ATTR_A)) {
|
||||
attrib|=FILE_ATTR_A;
|
||||
put_attr_to_disk(dev, inode, attrib);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 */
|
||||
}
|
||||
}
|
||||
*offset=l;
|
||||
closedir(d);
|
||||
}
|
||||
reseteuid();
|
||||
return(count);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
if ((!mode) || (newattrib != oldattrib) ) {
|
||||
if (!(voloptions & VOL_OPTION_ATTRIBUTES)) {
|
||||
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);
|
||||
}
|
||||
|
||||
int set_nw_trustee(int dev, ino_t inode, uint32 id, int trustee)
|
||||
int set_nw_attrib_dword(int volume, char *unixname, struct stat *stb, uint32 attrib)
|
||||
/* wattrib = ext_attrib, attrib */
|
||||
{
|
||||
return(0);
|
||||
|
||||
#if 0
|
||||
if (get_own_trustee(dev, inode, TRUSTEE_M) & (TRUSTEE_M | TRUSTEE_S)){
|
||||
|
||||
} else return(-0x8c); /* no modify privileges */
|
||||
#endif
|
||||
return(set_nw_attrib(volume,unixname,stb,attrib, 0));
|
||||
}
|
||||
|
||||
int set_nw_attrib_byte(int volume, char *unixname, struct stat *stb, int battrib)
|
||||
{
|
||||
return(set_nw_attrib(volume,unixname,stb,(uint32)battrib, 1));
|
||||
}
|
||||
|
||||
void free_nw_ext_inode(int dev, ino_t inode)
|
||||
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))
|
||||
&& !(attrib & FILE_ATTR_A)) {
|
||||
attrib|=FILE_ATTR_A;
|
||||
put_attr_to_disk(dev, inode, attrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void free_nw_ext_inode(int volume, char *unixname, int dev, ino_t inode)
|
||||
/* removes all attrib or trustees entries for files or dirs */
|
||||
/* must be called after deleting nw file or dir */
|
||||
{
|
||||
free_attr_from_disk(dev, inode);
|
||||
free_trustees_from_disk(dev, inode);
|
||||
int voloptions=get_volume_options(volume);
|
||||
if (voloptions & VOL_OPTION_ATTRIBUTES)
|
||||
free_attr_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);
|
||||
}
|
||||
}
|
||||
|
||||
|
25
nwattrib.h
25
nwattrib.h
@ -1,16 +1,27 @@
|
||||
/* nwattrib.h 01-Feb-98 */
|
||||
/* nwattrib.h 30-Apr-98 */
|
||||
|
||||
#ifndef _NWATTRIB_H_
|
||||
#define _NWATTRIB_H_
|
||||
|
||||
extern uint32 get_nw_attrib_dword(struct stat *stb, int voloptions);
|
||||
extern int set_nw_attrib_dword(struct stat *stb, int voloptions, uint32 attrib);
|
||||
extern int set_nw_attrib_byte (struct stat *stb, int voloptions, int battrib);
|
||||
extern void set_nw_archive_bit(int dev, ino_t inode);
|
||||
/* <-------------- 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
|
||||
|
||||
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
|
||||
|
||||
|
615
nwbind.c
615
nwbind.c
@ -1,9 +1,9 @@
|
||||
/* nwbind.c */
|
||||
#define REVISION_DATE "04-Feb-98"
|
||||
#define REVISION_DATE "25-Apr-00"
|
||||
/* 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
|
||||
* 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
|
||||
* 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 "nwdbm.h"
|
||||
#include "unxlog.h"
|
||||
@ -49,7 +58,7 @@ static void write_to_nwserv(int what, int connection, int mode,
|
||||
switch (what) {
|
||||
case 0x4444 : /* tell the wdog there's no need to look 0 */
|
||||
/* activate wdogs to free connection 1 */
|
||||
/* the connection ist closed 99 */
|
||||
/* the connection ist closed 99 */
|
||||
write(FD_NWSERV, &what, sizeof(int));
|
||||
write(FD_NWSERV, &connection, sizeof(int));
|
||||
write(FD_NWSERV, &mode, sizeof(int));
|
||||
@ -82,9 +91,236 @@ static int max_nw_vols=MAX_NW_VOLS;
|
||||
static int max_connections=MAX_CONNECTIONS;
|
||||
static CONNECTION *connections=NULL;
|
||||
static CONNECTION *act_c=(CONNECTION*)NULL;
|
||||
static int act_connection;
|
||||
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)
|
||||
{
|
||||
/* 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 */
|
||||
} else if (security == 2) {
|
||||
if ( act_c->object_id == obj_id
|
||||
|| act_c->object_id == 1 ) return(0); /* rights for the user */
|
||||
} else if (security == 3 && act_c->object_id == 1) return(0);
|
||||
|| (act_c->id_flags&1) ) return(0); /* rights for the user */
|
||||
} else if (security == 3 && (act_c->id_flags&1)) return(0);
|
||||
|
||||
switch (forwrite&0xf) {
|
||||
case 0 : acc_what = "read"; break;
|
||||
@ -145,6 +381,8 @@ int b_acc(uint32 obj_id, int security, int forwrite)
|
||||
return(errcode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void sent_down_message(void)
|
||||
{
|
||||
int k = -1;
|
||||
@ -152,12 +390,24 @@ static void sent_down_message(void)
|
||||
while (++k < max_connections) {
|
||||
CONNECTION *cn=&connections[k];
|
||||
if (cn->active) {
|
||||
#if 0
|
||||
strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58);
|
||||
#else
|
||||
strmaxcpy(cn->message, "MARS_NWE IS DIEING", 58);
|
||||
#endif
|
||||
nwserv_handle_msg(k+1);
|
||||
}
|
||||
} /* 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)
|
||||
{
|
||||
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->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)
|
||||
{
|
||||
uint8 pw_name[40];
|
||||
uint8 *p;
|
||||
int result;
|
||||
int i;
|
||||
act_c->object_id = obj_id; /* actuell Object ID */
|
||||
act_c->t_login = akttime; /* and login Time */
|
||||
|
||||
act_c->id_flags = 0;
|
||||
internal_act=1;
|
||||
if (HAVE_SU_RIGHTS(obj_id)) {
|
||||
act_c->id_flags|=1; /* supervisor equivalence */
|
||||
}
|
||||
get_guid((int*) responsedata,
|
||||
(int*) (responsedata+sizeof(int)),
|
||||
obj_id, pw_name);
|
||||
*((uint32*) (responsedata+2*sizeof(int))) = obj_id;
|
||||
|
||||
result = get_home_dir(responsedata + 3 * sizeof(int)+1, obj_id);
|
||||
*(responsedata + 3 * sizeof(int)) = (uint8) result;
|
||||
result = 3 * sizeof(int) + 1 + (int) *(responsedata+ 3 * sizeof(int));
|
||||
*((int*)(responsedata+2*sizeof(int))) = act_c->id_flags;
|
||||
*((uint32*) (responsedata+3*sizeof(int))) = obj_id;
|
||||
result=4*sizeof(int);
|
||||
p = responsedata + result;
|
||||
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,
|
||||
&(act_c->client_adr), pw_name);
|
||||
internal_act=0;
|
||||
@ -233,7 +500,7 @@ static void handle_fxx(int gelen, int func)
|
||||
uint8 connect_status= 0;
|
||||
int data_len = 0;
|
||||
|
||||
if (func==0x19) {
|
||||
if (func==0x18||func==19) {
|
||||
ufunc = 0;
|
||||
rdata = requestdata;
|
||||
} else if (func==0x20) {
|
||||
@ -324,17 +591,17 @@ static void handle_fxx(int gelen, int func)
|
||||
uint32 id = GET_BE32(rdata+1);
|
||||
internal_act=1;
|
||||
if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)),
|
||||
id, (char *) NULL) != 0) {
|
||||
completition = 0xff;
|
||||
id, (char *) NULL) != 0) {
|
||||
completition = 0xff;
|
||||
XDPRINTF((2, 0, "quota id-uid mapping failure %d 0x%x", ufunc, id));
|
||||
}
|
||||
internal_act=0;
|
||||
/* OK if supervisor or trying to read (0x29) own limits */
|
||||
if (act_c->object_id == 1 ||
|
||||
(act_c->object_id == id && ufunc == 0x29))
|
||||
((int *) responsedata)[2] = 0; /* OK */
|
||||
if ( (act_c->id_flags&1) ||
|
||||
(act_c->object_id == id && ufunc == 0x29))
|
||||
((int *) responsedata)[2] = 0; /* OK */
|
||||
else
|
||||
((int *) responsedata)[2] = 1; /* Fail */
|
||||
((int *) responsedata)[2] = 1; /* Fail */
|
||||
data_len = sizeof(int)*3;
|
||||
}
|
||||
break;
|
||||
@ -518,8 +785,12 @@ static void handle_fxx(int gelen, int func)
|
||||
memset(password, 0, 50);
|
||||
if (!result)
|
||||
data_len = build_login_response(responsedata, obj.id);
|
||||
else
|
||||
else {
|
||||
completition = (uint8) -result;
|
||||
if (result==-0xdf) { /* PaPr,mst:25-Apr-00 */
|
||||
data_len = build_login_response(responsedata, obj.id);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x15 : { /* Get Object Connection List (old) */
|
||||
@ -620,13 +891,17 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
if (result > -1)
|
||||
data_len = build_login_response(responsedata, obj.id);
|
||||
else
|
||||
else {
|
||||
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 = 0xdf means good login, but
|
||||
* login time has expired
|
||||
* perhaps I will integrate it later.
|
||||
* login time has expired, using grace logins
|
||||
*/
|
||||
}
|
||||
break;
|
||||
@ -686,7 +961,7 @@ static void handle_fxx(int gelen, int func)
|
||||
|
||||
case 0x34 : { /* rename OBJECT, only SU */
|
||||
int result=-0xff;
|
||||
if (1 == act_c->object_id) {
|
||||
if (act_c->id_flags&1) {
|
||||
uint8 *p = rdata;
|
||||
NETOBJ obj;
|
||||
uint8 newname[256];
|
||||
@ -774,7 +1049,7 @@ static void handle_fxx(int gelen, int func)
|
||||
case 0x38 : { /* change Bindery Objekt Security */
|
||||
/* only SU ! */
|
||||
int result= -0xff;
|
||||
if (1 == act_c->object_id) {
|
||||
if (act_c->id_flags&1) {
|
||||
uint8 *p = rdata;
|
||||
NETOBJ obj;
|
||||
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))) {
|
||||
XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword,
|
||||
newpassword));
|
||||
|
||||
internal_act = 1;
|
||||
if (act_c->object_id == 1 ||
|
||||
internal_act=1;
|
||||
if ((act_c->id_flags&1) ||
|
||||
(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)))){
|
||||
if ( (act_c->object_id != 1)
|
||||
if ( (!(act_c->id_flags&1))
|
||||
|| *newpassword
|
||||
|| !(password_scheme & PW_SCHEME_LOGIN))
|
||||
result=nw_set_passwd(obj.id, newpassword, 0);
|
||||
else result = -0xff;
|
||||
}
|
||||
internal_act = 0;
|
||||
internal_act=0;
|
||||
}
|
||||
if (result < 0) completition = (uint8) -result;
|
||||
memset(oldpassword, 0, 50);
|
||||
@ -1003,7 +1279,6 @@ static void handle_fxx(int gelen, int func)
|
||||
if (result) completition = (uint8) -result;
|
||||
} break;
|
||||
|
||||
|
||||
case 0x44 : { /* CLOSE BINDERY */
|
||||
;
|
||||
} break;
|
||||
@ -1025,8 +1300,8 @@ static void handle_fxx(int gelen, int func)
|
||||
*xdata = (uint8) 0;
|
||||
memset(xdata+1, 0xff, 4);
|
||||
} else {
|
||||
*xdata = (act_c->object_id == 1) ? (uint8) 0x33
|
||||
: (uint8) 0x22;
|
||||
*xdata = (act_c->id_flags&1) ? (uint8) 0x33
|
||||
: (uint8) 0x22;
|
||||
U32_TO_BE32(act_c->object_id, (xdata+1));
|
||||
}
|
||||
data_len = 5;
|
||||
@ -1035,19 +1310,10 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */
|
||||
/* TODO !!! */
|
||||
struct XDATA {
|
||||
uint8 nextsequence[2];
|
||||
uint8 id[4];
|
||||
uint8 access_mask;
|
||||
uint8 pathlen;
|
||||
uint8 path[1];
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
memset(xdata, 0, 8);
|
||||
data_len = 8;
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case 0x47 : /* SCAN BINDERY OBJECT TRUSTEE PATH */
|
||||
handled in nwconn
|
||||
#endif
|
||||
|
||||
case 0x48 : { /* GET BINDERY ACCES LEVEL from OBJECT ??? */
|
||||
struct XDATA {
|
||||
@ -1059,7 +1325,7 @@ static void handle_fxx(int gelen, int func)
|
||||
result = nw_get_obj(&obj);
|
||||
if (!result) {
|
||||
/* don't know whether this is ok ?? */
|
||||
if (act_c->object_id == 1) {
|
||||
if (act_c->id_flags&1) {
|
||||
xdata->acces_level = 0x33;
|
||||
} else if (act_c->object_id == obj.id) {
|
||||
xdata->acces_level = 0x22;
|
||||
@ -1072,7 +1338,7 @@ static void handle_fxx(int gelen, int func)
|
||||
break;
|
||||
|
||||
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 */
|
||||
/* not manager, then completition = 0xff */
|
||||
}
|
||||
@ -1091,8 +1357,8 @@ static void handle_fxx(int gelen, int func)
|
||||
internal_act = 0;
|
||||
}
|
||||
if (result < 0) completition = (uint8) -result;
|
||||
XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', result=%d",
|
||||
obj.name, result));
|
||||
XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', type=0x%x, result=%d",
|
||||
obj.name, obj.type, result));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1108,19 +1374,19 @@ static void handle_fxx(int gelen, int func)
|
||||
/* from Guntram Blohm */
|
||||
p += (*p+1); /* here is crypted password length */
|
||||
if (0 == (result = find_obj_id(&obj))) {
|
||||
internal_act=1;
|
||||
internal_act=1;
|
||||
if (obj.id != 1)
|
||||
result=test_allow_password_change(obj.id);
|
||||
if (!result)
|
||||
result=nw_keychange_passwd(obj.id, act_c->crypt_key,
|
||||
rdata, (int)*p, p+1, act_c->object_id);
|
||||
result=nw_keychange_passwd(obj.id, act_c->crypt_key,
|
||||
rdata, (int)*p, p+1, act_c->id_flags);
|
||||
if (!result) test_ins_unx_user(obj.id);
|
||||
internal_act = 0;
|
||||
}
|
||||
internal_act = 0;
|
||||
}
|
||||
|
||||
if (result< 0) completition = (uint8) -result;
|
||||
XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', result=0x%x",
|
||||
obj.name, result));
|
||||
XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', type=0x%x, result=0x%x",
|
||||
obj.name, obj.type, result));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1153,7 +1419,7 @@ static void handle_fxx(int gelen, int func)
|
||||
case 0x65 : { /* Destroy Queue */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
int result=-0xd3; /* no rights */
|
||||
if (1 == act_c->object_id)
|
||||
if (act_c->id_flags&1)
|
||||
result=nw_destroy_queue(q_id);
|
||||
if (result < 0)
|
||||
completition=(uint8)(-result);
|
||||
@ -1198,6 +1464,20 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
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 0x80 : { /* Remove Job from Queue NEW */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
@ -1241,13 +1521,15 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
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);
|
||||
int job_id = GET_BE16(rdata+4);
|
||||
/* added by nwconn */
|
||||
uint32 fhandle = GET_BE32(rdata+8);
|
||||
int result=nw_get_q_job_entry(q_id, job_id, fhandle,
|
||||
responsedata, 1);
|
||||
responsedata, ufunc==0x6c);
|
||||
if (result > -1)
|
||||
data_len=result;
|
||||
else completition=(uint8)-result;
|
||||
@ -1257,9 +1539,9 @@ static void handle_fxx(int gelen, int func)
|
||||
case 0x69: /* close file and start queue old ?? */
|
||||
case 0x7f: { /* close file and start queue */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint32 job_id = (ufunc==0x69)
|
||||
? GET_BE16(rdata+4)
|
||||
: GET_BE16(rdata+4);
|
||||
uint32 job_id = (ufunc==0x69)
|
||||
? GET_BE16(rdata+4)
|
||||
: GET_BE16(rdata+4);
|
||||
int result = nw_close_queue_job(q_id, job_id,
|
||||
responsedata);
|
||||
if (result > -1)
|
||||
@ -1299,9 +1581,9 @@ static void handle_fxx(int gelen, int func)
|
||||
case 0x87: /* Get Queue Job File Size */
|
||||
{
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint32 job_id = (ufunc==0x78)
|
||||
? GET_BE16(rdata+4)
|
||||
: GET_BE16(rdata+4);
|
||||
uint32 job_id = (ufunc==0x78)
|
||||
? GET_BE16(rdata+4)
|
||||
: GET_BE16(rdata+4);
|
||||
int result = nw_get_queue_job_file_size(q_id, job_id);
|
||||
if (result > -1) {
|
||||
uint8 *p=responsedata;
|
||||
@ -1337,7 +1619,18 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
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 */
|
||||
struct XDATA {
|
||||
uint8 id[4]; /* queue id */
|
||||
@ -1378,22 +1671,26 @@ static void handle_fxx(int gelen, int func)
|
||||
} break;
|
||||
|
||||
case 0x81 : { /* Get Queue Job List */
|
||||
NETOBJ obj;
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint32 offset = GET_BE32(rdata+4);
|
||||
#if 0
|
||||
struct XDATA {
|
||||
uint8 total_jobs[4];
|
||||
uint8 reply_numbers[4];
|
||||
uint8 job_list[4]; /* this is repeated */
|
||||
uint8 reply_numbers[4]; /* max. 125 replies */
|
||||
uint8 job_list[4]; /* this is repeated */
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
obj.id = GET_BE32(rdata);
|
||||
XDPRINTF((2, 0, "TODO:GET QUEUE JOB List of Q=0x%lx", obj.id));
|
||||
memset(xdata, 0, sizeof(struct XDATA));
|
||||
data_len=sizeof(struct XDATA);
|
||||
#endif
|
||||
int result=nw_get_queue_job_list(q_id, offset, responsedata);
|
||||
if (result > -1)
|
||||
data_len=result;
|
||||
else
|
||||
completition=(uint8)-result;
|
||||
}break;
|
||||
|
||||
case 0x72: /* finish servicing queue job (old)*/
|
||||
case 0x83: { /* finish servicing queue job */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint32 job_id = GET_BE16(rdata+4);
|
||||
uint32 job_id = GET_BE16(rdata+4);
|
||||
#if 0
|
||||
uint32 chargeinfo = GET_BE32(rdata+8);
|
||||
#endif
|
||||
@ -1408,7 +1705,7 @@ static void handle_fxx(int gelen, int func)
|
||||
case 0x73: /* abort servicing queue job (old) */
|
||||
case 0x84: { /* abort servicing queue job */
|
||||
uint32 q_id = GET_BE32(rdata);
|
||||
uint32 job_id = GET_BE16(rdata+4);
|
||||
uint32 job_id = GET_BE16(rdata+4);
|
||||
int result = nw_finish_abort_queue_job(1,
|
||||
act_c->object_id,
|
||||
act_connection,
|
||||
@ -1421,12 +1718,12 @@ static void handle_fxx(int gelen, int func)
|
||||
}
|
||||
}break;
|
||||
|
||||
|
||||
|
||||
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) */
|
||||
if (act_c->object_id != 1) completition=0xc6; /* no rights */
|
||||
if (!(act_c->id_flags&1))
|
||||
completition=0xc6; /* no rights */
|
||||
} break;
|
||||
|
||||
case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */
|
||||
@ -1438,15 +1735,8 @@ static void handle_fxx(int gelen, int func)
|
||||
int l;
|
||||
memset(responsedata, 0, 512);
|
||||
strcpy(responsedata, company);
|
||||
|
||||
l = 1 + sprintf(responsedata+k, revision,
|
||||
_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);
|
||||
k += (strlen(revision_date)+1);
|
||||
strcpy(responsedata+k, copyright);
|
||||
@ -1493,10 +1783,17 @@ static void handle_fxx(int gelen, int func)
|
||||
break;
|
||||
|
||||
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 */
|
||||
nwserv_down_server();
|
||||
} else completition = 0xff;
|
||||
} else {
|
||||
/* 16-May-99
|
||||
* correct completition code from Paolo Prandini
|
||||
*/
|
||||
completition = 0xc6; /* not authorized */
|
||||
}
|
||||
internal_act=0;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1508,9 +1805,14 @@ static void handle_fxx(int gelen, int func)
|
||||
default : completition = 0xfb; /* not known here */
|
||||
break;
|
||||
} /* 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 */
|
||||
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);
|
||||
act_c->object_id = 0; /* not LOGIN */
|
||||
act_c->id_flags = 0; /* no flags */
|
||||
} else if (0x20 == func) { /* Semaphore */
|
||||
int result = handle_func_0x20(act_c, rdata, ufunc, responsedata);
|
||||
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,
|
||||
&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));
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
{
|
||||
int func = (int) *p;
|
||||
@ -1673,6 +2048,7 @@ static void set_sig(void)
|
||||
{
|
||||
signal(SIGQUIT, sig_handler);
|
||||
signal(SIGHUP, sig_handler);
|
||||
signal(SIGUSR2, sig_handler);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
@ -1681,18 +2057,16 @@ static void set_sig(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int sock_nwbind;
|
||||
int i;
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage nwbind nwname address nwbindsock\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_tools(NWBIND, 0);
|
||||
|
||||
strmaxcpy(my_nwname, argv[1], 47);
|
||||
adr_to_ipx_addr(&my_addr, argv[2]);
|
||||
|
||||
sscanf(argv[3], "%x", &sock_nwbind);
|
||||
|
||||
internal_act = 1;
|
||||
if (nw_init_dbm(my_nwname, &my_addr) <0) {
|
||||
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 */
|
||||
if (max_nw_vols < 1)
|
||||
max_nw_vols = MAX_NW_VOLS;
|
||||
|
||||
#ifdef LINUX
|
||||
set_emu_tli();
|
||||
#endif
|
||||
@ -1718,7 +2091,6 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
XDPRINTF((1, 0, "USE_PERMANENT_OUT_SOCKET %s",
|
||||
(ipx_out_fd > -1) ? "enabled" : "disabled"));
|
||||
|
||||
ud.opt.len = sizeof(ipx_pack_typ);
|
||||
ud.opt.maxlen = sizeof(ipx_pack_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){
|
||||
time(&akttime);
|
||||
XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr)));
|
||||
act_ncpsequence = (int)ncprequest->sequence;
|
||||
|
||||
if ( ncprequest->type[0] == 0x22
|
||||
&& ncprequest->type[1] == 0x22) {
|
||||
act_connection = (int)ncprequest->connection
|
||||
@ -1757,8 +2131,46 @@ int main(int argc, char *argv[])
|
||||
visable_ipx_adr(&from_addr), act_connection));
|
||||
}
|
||||
} else {
|
||||
XDPRINTF((1, 0, "NWBIND-LOOP connection=%d is wrong",
|
||||
act_connection));
|
||||
XDPRINTF((1, 0, "NWBIND-LOOP connection=%d,adr=%s is wrong",
|
||||
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
|
||||
&& ncprequest->type[1] == 0xee
|
||||
@ -1776,13 +2188,16 @@ int main(int argc, char *argv[])
|
||||
/* here I update some Bindery stuff from nwserv.conf */
|
||||
reinit_nwbind();
|
||||
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 */
|
||||
got_sig=max_connections+1;
|
||||
while (--got_sig)
|
||||
open_clear_connection(got_sig, 0, NULL);
|
||||
i=max_connections+1;
|
||||
while (--i)
|
||||
open_clear_connection(i, 0, NULL);
|
||||
|
||||
if (ncp_fd > -1) {
|
||||
t_unbind(ncp_fd);
|
||||
|
25
nwbind.h
25
nwbind.h
@ -1,9 +1,9 @@
|
||||
/* nwbind.h 07-Aug-97 */
|
||||
/* nwbind.h 23-Apr-98 */
|
||||
|
||||
#ifndef _NWBIND_H_
|
||||
#define _NWBIND_H_
|
||||
|
||||
#define MAX_SEMA_CONN 10 /* 10 Semaphore pre connection */
|
||||
#define MAX_SEMA_CONN 10 /* 10 Semaphore / connection */
|
||||
|
||||
|
||||
typedef struct {
|
||||
@ -11,16 +11,37 @@ typedef struct {
|
||||
int opencount; /* times open */
|
||||
} 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 {
|
||||
ipxAddr_t client_adr; /* address remote client */
|
||||
uint32 object_id; /* logged object */
|
||||
/* 0 = not logged in */
|
||||
int id_flags; /* &1 == supervisor (equivalence) */
|
||||
/* flags are also availible in */
|
||||
/* connection based routines */
|
||||
|
||||
uint8 crypt_key[8]; /* password generation */
|
||||
time_t t_login; /* login time */
|
||||
uint8 message[60]; /* saved BCastmessage */
|
||||
int active; /* 0=closed, 1= active */
|
||||
int send_to_sock; /* this is the receiving sock */
|
||||
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 */
|
||||
SEMA_CONN semas[MAX_SEMA_CONN];
|
||||
} CONNECTION;
|
||||
|
3
nwconn.h
3
nwconn.h
@ -1,7 +1,6 @@
|
||||
/* nwconn.h 19-Nov-97 */
|
||||
/* nwconn.h 13-May-98 */
|
||||
#ifndef _NWCONN_H_
|
||||
#define _NWCONN_H_
|
||||
extern int act_connection;
|
||||
extern int act_pid;
|
||||
extern void nwconn_set_program_title(char *s);
|
||||
#endif
|
||||
|
77
nwdbm.h
77
nwdbm.h
@ -1,5 +1,5 @@
|
||||
/* nwdbm.h 01-Oct-97 */
|
||||
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
|
||||
/* nwdbm.h 25-Apr-00 */
|
||||
/* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -78,12 +78,71 @@ extern uint8 *sys_sysname; /* Name of first Volume, normally SYS */
|
||||
|
||||
extern uint32 network_serial_nmbr;
|
||||
extern uint16 network_appl_nmbr;
|
||||
extern int entry8_flags;
|
||||
|
||||
#define PW_SCHEME_CHANGE_PW 1
|
||||
#define PW_SCHEME_LOGIN 2
|
||||
#define PW_SCHEME_GET_KEY_FAIL 4
|
||||
#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 !!!! */
|
||||
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,
|
||||
uint8 *member_name, int member_namlen);
|
||||
|
||||
|
||||
extern int nw_add_obj_to_set(int object_type,
|
||||
uint8 *object_name, int object_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,
|
||||
int prop_flags, int prop_security);
|
||||
|
||||
|
||||
extern uint32 nw_new_obj_prop(uint32 wanted_id,
|
||||
char *objname, int objtype, int objflags, int objsecurity,
|
||||
char *propname, int propflags, int propsecurity,
|
||||
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_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_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,
|
||||
uint8 *cryptkey, uint8 *oldpass,
|
||||
int cryptedlen, uint8 *newpass,
|
||||
uint32 act_id);
|
||||
int id_flags);
|
||||
|
||||
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_import_dbm(char *path);
|
||||
extern int do_export_dbm_to_dir(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
16
nwfile.h
16
nwfile.h
@ -1,4 +1,4 @@
|
||||
/* nwfile.h 09-Feb-98 */
|
||||
/* nwfile.h 10-Nov-99 */
|
||||
#ifndef _NWFILE_H_
|
||||
#define _NWFILE_H_
|
||||
#include "extpipe.h"
|
||||
@ -18,6 +18,9 @@ typedef struct {
|
||||
int st_dev; /* device */
|
||||
int st_ino; /* inode */
|
||||
char fname[256]; /* UNIX filename */
|
||||
int volume; /* Volume */
|
||||
int inuse; /* used for multiple open of filehandle */
|
||||
int access; /* open access */
|
||||
} FILE_HANDLE;
|
||||
|
||||
/* 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_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 uint8 *file_get_unix_name(int fhandle);
|
||||
@ -50,12 +53,17 @@ extern int nw_server_copy(int qfhandle, uint32 qoffset,
|
||||
int zfhandle, uint32 zoffset,
|
||||
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 FILE_HANDLE *fd_2_fh(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
|
||||
|
79
nwqconn.c
79
nwqconn.c
@ -1,4 +1,4 @@
|
||||
/* nwqconn.c 24-Sep-97 */
|
||||
/* nwqconn.c 15-Sep-99 */
|
||||
/* (C)opyright (C) 1997 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -24,16 +24,23 @@
|
||||
#include "connect.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 {
|
||||
uint32 queue_id;
|
||||
int job_id;
|
||||
int fhandle;
|
||||
int task;
|
||||
struct S_INT_QUEUE_JOB *next;
|
||||
} INT_QUEUE_JOB;
|
||||
|
||||
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));
|
||||
if (!queue_jobs) {
|
||||
@ -46,6 +53,7 @@ static INT_QUEUE_JOB *new_queue_job(uint32 queue_id, int job_id)
|
||||
p->next=NULL;
|
||||
p->queue_id=queue_id;
|
||||
p->job_id=job_id;
|
||||
p->task=task;
|
||||
return(p);
|
||||
}
|
||||
|
||||
@ -90,11 +98,13 @@ static int open_creat_queue_file(int mode, uint8
|
||||
*/
|
||||
{
|
||||
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) {
|
||||
char unixname[300];
|
||||
|
||||
result=conn_get_kpl_unxname(unixname, result, file_name, file_name_len);
|
||||
int dirhandle=result;
|
||||
result=conn_get_kpl_unxname(unixname, sizeof(unixname),
|
||||
dirhandle, file_name, file_name_len);
|
||||
if (result > -1) {
|
||||
struct stat stbuff;
|
||||
if (mode == 0) { /* creat */
|
||||
@ -104,12 +114,14 @@ static int open_creat_queue_file(int mode, uint8
|
||||
chmod(unixname, 0600);
|
||||
} else if (mode == 1) { /* open ro */
|
||||
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 */
|
||||
result=file_creat_open(result, (uint8*)unixname,
|
||||
&stbuff, 0x6, 0x6, 4|8, 0);
|
||||
} else result=-1;
|
||||
}
|
||||
nw_free_dir_handle(dirhandle, 1);
|
||||
}
|
||||
if (result < 0) {
|
||||
uint8 dn[300];
|
||||
@ -123,7 +135,8 @@ static int open_creat_queue_file(int mode, uint8
|
||||
return(result);
|
||||
}
|
||||
|
||||
int creat_queue_job(uint32 q_id,
|
||||
int creat_queue_job(int task,
|
||||
uint32 q_id,
|
||||
uint8 *queue_job,
|
||||
uint8 *responsedata,
|
||||
uint8 old_call)
|
||||
@ -138,7 +151,7 @@ int creat_queue_job(uint32 q_id,
|
||||
if (old_call) {
|
||||
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
|
||||
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),
|
||||
dirname+1, *dirname);
|
||||
if (result > -1) {
|
||||
@ -150,7 +163,7 @@ int creat_queue_job(uint32 q_id,
|
||||
} else {
|
||||
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
|
||||
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),
|
||||
dirname+1, *dirname);
|
||||
if (result > -1) {
|
||||
@ -172,10 +185,10 @@ int close_queue_job(uint32 q_id, int job_id)
|
||||
int result = -0xff;
|
||||
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
|
||||
if (jo) {
|
||||
nw_close_file(jo->fhandle, 0);
|
||||
nw_close_file(jo->fhandle, 0, jo->task);
|
||||
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));
|
||||
return(result);
|
||||
}
|
||||
@ -186,7 +199,6 @@ int close_queue_job2(uint32 q_id, int job_id,
|
||||
{
|
||||
int result = -0xff;
|
||||
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 (prc_len) {
|
||||
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);
|
||||
} else
|
||||
strmaxcpy((uint8*)printcommand, prc, prc_len);
|
||||
nw_close_file(jo->fhandle, 1);
|
||||
nw_close_file(jo->fhandle, 1, jo->task);
|
||||
jo->fhandle = 0L;
|
||||
if (NULL == (f = fopen(unixname, "r"))) {
|
||||
/* 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) {
|
||||
int is_ok = 0;
|
||||
FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid());
|
||||
FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid(), 1);
|
||||
if (fp) {
|
||||
int k;
|
||||
is_ok++;
|
||||
@ -244,14 +256,16 @@ int close_queue_job2(uint32 q_id, int job_id,
|
||||
}
|
||||
} else {
|
||||
result=0;
|
||||
nw_close_file(jo->fhandle, 1);
|
||||
nw_close_file(jo->fhandle, 1, jo->task);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
int service_queue_job(uint32 q_id,
|
||||
int service_queue_job(int task,
|
||||
uint32 q_id,
|
||||
uint8 *queue_job,
|
||||
uint8 *responsedata,
|
||||
uint8 old_call)
|
||||
@ -266,7 +280,7 @@ int service_queue_job(uint32 q_id,
|
||||
if (old_call) {
|
||||
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata; /* before 3.11 */
|
||||
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,
|
||||
job->job_file_name+1, *(job->job_file_name),
|
||||
dirname+1, *dirname);
|
||||
@ -279,7 +293,7 @@ int service_queue_job(uint32 q_id,
|
||||
} else {
|
||||
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
|
||||
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,
|
||||
job->job_file_name+1, *(job->job_file_name),
|
||||
dirname+1, *dirname);
|
||||
@ -300,7 +314,7 @@ int finish_abort_queue_job(uint32 q_id, int job_id)
|
||||
int result = -0xff;
|
||||
INT_QUEUE_JOB *jo=find_queue_job(q_id, job_id);
|
||||
if (jo) {
|
||||
nw_close_file(jo->fhandle, 0);
|
||||
nw_close_file(jo->fhandle, 0, jo->task);
|
||||
free_queue_job(q_id, job_id);
|
||||
result=0;
|
||||
}
|
||||
@ -328,3 +342,30 @@ void free_queue_jobs(void)
|
||||
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)) ;;
|
||||
}
|
||||
|
||||
|
10
nwqconn.h
10
nwqconn.h
@ -1,8 +1,9 @@
|
||||
/* nwqconn.h 26-Aug-97 */
|
||||
/* nwqconn.h 14-Apr-98 */
|
||||
#ifndef _NWQCONN_H_
|
||||
#define _NWQCONN_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 *responsedata,
|
||||
uint8 old_call);
|
||||
@ -12,7 +13,8 @@ extern int close_queue_job2(uint32 q_id, int job_id,
|
||||
uint8 *client_area,
|
||||
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 *responsedata,
|
||||
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 void free_queue_jobs(void);
|
||||
|
||||
extern void free_connection_task_jobs(int task);
|
||||
#endif
|
||||
|
241
nwqueue.c
241
nwqueue.c
@ -1,4 +1,4 @@
|
||||
/* nwqueue.c 08-Oct-97 */
|
||||
/* nwqueue.c 04-Jun-98 */
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* 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;
|
||||
uint32 server_id;
|
||||
uint8 job_description[50];
|
||||
uint8 client_area[152];
|
||||
time_t file_entry_time; /* for filenamehandling */
|
||||
uint8 client_area[152]; /* must be int aligned */
|
||||
struct S_INT_QUEUE_JOB *next;
|
||||
} INT_QUEUE_JOB;
|
||||
|
||||
@ -73,6 +73,8 @@ typedef struct S_NWE_QUEUE {
|
||||
|
||||
NWE_QUEUE *nwe_queues=NULL;
|
||||
|
||||
static int entry18_flags;
|
||||
|
||||
static NWE_QUEUE *new_queue(uint32 id)
|
||||
{
|
||||
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) {
|
||||
que->queue_jobs=p;
|
||||
p->job_position=1;
|
||||
que->last_job_id=1;
|
||||
if (++(que->last_job_id)>999) que->last_job_id=1;
|
||||
} else {
|
||||
int flag;
|
||||
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_id=0;
|
||||
qj->job_control_flags &= ~0x20;
|
||||
|
||||
|
||||
add_queue_job(q, qj);
|
||||
qj=(INT_QUEUE_JOB*)xmalloc(sizeof(INT_QUEUE_JOB));
|
||||
|
||||
}
|
||||
xfree(qj);
|
||||
}
|
||||
@ -371,7 +376,11 @@ static int fill_q_job_entry(INT_QUEUE_JOB *jo,
|
||||
{
|
||||
memset(job->record_in_use, 0xff, 2);
|
||||
memset(job->record_previous, 0, 4);
|
||||
memset(job->record_next, 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);
|
||||
|
||||
U32_TO_32(jo->client_connection, job->client_connection);
|
||||
U32_TO_32(jo->client_task, job->client_task);
|
||||
@ -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,
|
||||
uint8 *responsedata)
|
||||
{
|
||||
int result=-0xd8; /* queue not active */
|
||||
NWE_QUEUE *que=find_queue(q_id);
|
||||
if (que) {
|
||||
INT_QUEUE_JOB *jo=find_queue_job(que, job_id);
|
||||
if (jo) {
|
||||
int result=sizeof(jo->client_area);
|
||||
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;
|
||||
memcpy(responsedata, jo->client_area, result);
|
||||
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
|
||||
*(responsedata+result)=0;
|
||||
++result;
|
||||
return(result);
|
||||
}
|
||||
return(-0xff);
|
||||
} else
|
||||
result=-0xff;
|
||||
}
|
||||
return(-0xd8); /* queue not active */
|
||||
XDPRINTF(((result<0) ? 1 : 5, 0, "nw_close_queue_job, q=%lx, job=%d, result=%d",
|
||||
q_id, job_id, result));
|
||||
return(result);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
uint8 *responsedata, int old_call)
|
||||
{
|
||||
@ -534,22 +559,71 @@ int nw_get_queue_job_list_old(uint32 q_id, uint8 *responsedata)
|
||||
return(result);
|
||||
}
|
||||
|
||||
int nw_get_queue_job_list(uint32 q_id, uint32 offset, uint8 *responsedata)
|
||||
{
|
||||
int result = -0xff;
|
||||
NWE_QUEUE *q = find_queue(q_id);
|
||||
if (q) {
|
||||
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;
|
||||
uint8 buf[300];
|
||||
build_unix_queue_file(buf, q, qj);
|
||||
if (!stat(buf, &stb))
|
||||
return(stb.st_size);
|
||||
}
|
||||
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) {
|
||||
struct stat stb;
|
||||
uint8 buf[300];
|
||||
build_unix_queue_file(buf, q, qj);
|
||||
if (!stat(buf, &stb))
|
||||
return(stb.st_size);
|
||||
return(0);
|
||||
}
|
||||
if (qj)
|
||||
return(get_qj_file_size(q, qj));
|
||||
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)
|
||||
{
|
||||
struct stat stb;
|
||||
@ -582,6 +656,35 @@ int nw_remove_job_from_queue(uint32 user_id, uint32 q_id, int job_id)
|
||||
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 ------------------- */
|
||||
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 */
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@ -647,53 +752,64 @@ int nw_service_queue_job(uint32 user_id, int connection, int task,
|
||||
if (q && q->qserver
|
||||
&& q->qserver->user_id == user_id
|
||||
&& q->qserver->connection == connection) {
|
||||
uint8 *fulldirname = (old_call) ? responsedata+sizeof(QUEUE_JOB_OLD)
|
||||
: responsedata+sizeof(QUEUE_JOB);
|
||||
int len = nw_get_q_dirname(q_id, fulldirname+1);
|
||||
if ( !(q->status & 4) ) { /* not stopped printing */
|
||||
uint8 *fulldirname = (old_call) ? responsedata+sizeof(QUEUE_JOB_OLD)
|
||||
: responsedata+sizeof(QUEUE_JOB);
|
||||
int len = nw_get_q_dirname(q_id, fulldirname+1);
|
||||
|
||||
if (len > 0) {
|
||||
INT_QUEUE_JOB *qj=q->queue_jobs;
|
||||
INT_QUEUE_JOB *fqj=NULL;
|
||||
time_t acttime=time(NULL);
|
||||
*fulldirname=(uint8) len++;
|
||||
*(fulldirname+len)=0; /* for testprints only */
|
||||
while(qj) {
|
||||
if ( (!qj->server_id)
|
||||
&& !(qj->job_control_flags&0x20) /* not actual queued */
|
||||
&& qj->execute_time <= acttime
|
||||
&& (qj->target_id == MAX_U32 || qj->target_id == user_id)
|
||||
&& (qj->job_typ == MAX_U16 || job_typ==MAX_U16
|
||||
|| qj->job_typ == job_typ)) {
|
||||
|
||||
fqj=qj;
|
||||
break;
|
||||
} else {
|
||||
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->execute_time > acttime) ? "execute time not reached" : ""));
|
||||
if (len > 0) {
|
||||
INT_QUEUE_JOB *qj=q->queue_jobs;
|
||||
INT_QUEUE_JOB *fqj=NULL;
|
||||
time_t acttime=time(NULL);
|
||||
*fulldirname=(uint8) len++;
|
||||
*(fulldirname+len)=0; /* for testprints only */
|
||||
while(qj) {
|
||||
if ( (!qj->server_id)
|
||||
&& !(qj->job_control_flags&0x20) /* not actual queued */
|
||||
&& qj->execute_time <= acttime
|
||||
&& (qj->target_id == MAX_U32 || qj->target_id == user_id)
|
||||
&& (qj->job_typ == MAX_U16 || job_typ==MAX_U16
|
||||
|| qj->job_typ == job_typ)) {
|
||||
if (get_qj_file_size(q, qj) > 0) {
|
||||
fqj=qj;
|
||||
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 {
|
||||
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->execute_time > acttime) ? "execute time not reached" : ""));
|
||||
}
|
||||
qj=qj->next;
|
||||
}
|
||||
qj=qj->next;
|
||||
}
|
||||
if (fqj) {
|
||||
fqj->server_id = user_id;
|
||||
fqj->server_station = connection;
|
||||
fqj->server_task = task;
|
||||
if (old_call) {
|
||||
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata;
|
||||
result=fill_q_job_entry_old(fqj, job, 1);
|
||||
if (fqj) {
|
||||
fqj->server_id = user_id;
|
||||
fqj->server_station = connection;
|
||||
fqj->server_task = task;
|
||||
if (old_call) {
|
||||
QUEUE_JOB_OLD *job=(QUEUE_JOB_OLD*)responsedata;
|
||||
result=fill_q_job_entry_old(fqj, job, 1);
|
||||
} else {
|
||||
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
|
||||
result=fill_q_job_entry(fqj, job, 1);
|
||||
}
|
||||
result+=len;
|
||||
XDPRINTF((3, 0, "nw service queue job dirname=`%s`", fulldirname+1));
|
||||
} else {
|
||||
QUEUE_JOB *job=(QUEUE_JOB*)responsedata;
|
||||
result=fill_q_job_entry(fqj, job, 1);
|
||||
XDPRINTF((3, 0, "No queue job found for q_id=0x%x, user_id=0x%x,job_typ=0x%x",
|
||||
q_id, user_id, job_typ));
|
||||
}
|
||||
result+=len;
|
||||
XDPRINTF((3, 0, "nw service queue job dirname=`%s`", fulldirname+1));
|
||||
} else {
|
||||
XDPRINTF((3, 0, "No queue job found for q_id=0x%x, user_id=0x%x,job_typ=0x%x",
|
||||
q_id, user_id, job_typ));
|
||||
XDPRINTF((1, 0, "Could not get queuedir of q_id=0x%x", q_id));
|
||||
}
|
||||
} else {
|
||||
XDPRINTF((1, 0, "Could not get queuedir of q_id=0x%x", q_id));
|
||||
}
|
||||
} /* if */
|
||||
} else {
|
||||
XDPRINTF((1, 0, "Could not find qserver q_id=0x%x, user_id=0x%x, connect=%d",
|
||||
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;
|
||||
upstr(q_directory);
|
||||
} else {
|
||||
strcpy(q_directory, "SYS:SYSTEM");
|
||||
xstrcpy(q_directory, "SYS:SYSTEM");
|
||||
path_len=10;
|
||||
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;
|
||||
uint8 buf[300];
|
||||
int result;
|
||||
uint8 *wild="*";
|
||||
uint32 last_obj_id=MAX_U32;
|
||||
entry18_flags=entry18_flags_p;
|
||||
exit_queues();
|
||||
strmaxcpy(buf, sys_unixname, sys_unixnamlen);
|
||||
XDPRINTF((3,0, "init_queues:unixname='%s'", buf));
|
||||
obj.type = 3; /* queue */
|
||||
strcpy(obj.name, wild);
|
||||
xstrcpy(obj.name, wild);
|
||||
|
||||
result = scan_for_obj(&obj, last_obj_id, 1);
|
||||
while (!result) {
|
||||
@ -898,7 +1015,7 @@ void init_queues(void)
|
||||
r_w_queue_jobs(que, 0);
|
||||
}
|
||||
last_obj_id=obj.id;
|
||||
strcpy(obj.name, wild);
|
||||
xstrcpy(obj.name, wild);
|
||||
result = scan_for_obj(&obj, last_obj_id, 1);
|
||||
}
|
||||
}
|
||||
|
11
nwqueue.h
11
nwqueue.h
@ -1,4 +1,4 @@
|
||||
/* nwqueue.h 08-Oct-97 */
|
||||
/* nwqueue.h 14-Apr-98 */
|
||||
#ifndef _NWQUEUE_H_
|
||||
#define _NWQUEUE_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,
|
||||
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,
|
||||
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(uint32 q_id, uint32 offset, uint8 *responsedata);
|
||||
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 void nw_close_connection_jobs(int connection, int task);
|
||||
|
||||
|
||||
/* ------------------ for queue servers ------------------- */
|
||||
extern int nw_attach_server_to_queue(uint32 user_id,
|
||||
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 void exit_queues(void);
|
||||
extern void init_queues(void);
|
||||
extern void init_queues(int entry18_flags_p);
|
||||
#endif
|
||||
|
45
nwroute.c
45
nwroute.c
@ -1,5 +1,5 @@
|
||||
/* nwroute.c 08-Feb-98 */
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
/* nwroute.c 18-Apr-00 */
|
||||
/* (C)opyright (C) 1993,2000 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -50,7 +50,7 @@ static NW_SERVERS **nw_servers=NULL;
|
||||
#define NEEDS_UPDATE_RIP_NET 8
|
||||
#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 */
|
||||
uint8 *rnode, /* routernode */
|
||||
uint16 hops,
|
||||
@ -77,7 +77,8 @@ static void insert_delete_net(uint32 destnet,
|
||||
if (!do_delete) return; /* don't alter device */
|
||||
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;
|
||||
@ -94,7 +95,7 @@ static void insert_delete_net(uint32 destnet,
|
||||
int new_max_nw = max_nw_routes+5;
|
||||
NW_ROUTES **new_nwr
|
||||
=(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*));
|
||||
xfree(nw_routes);
|
||||
nw_routes=new_nwr;
|
||||
@ -109,14 +110,13 @@ static void insert_delete_net(uint32 destnet,
|
||||
nr->ticks = 0xffff;
|
||||
nr->hops = 0xffff;
|
||||
} else if (do_delete) {
|
||||
|
||||
nr=nw_routes[k];
|
||||
if (nr->rnet == rnet && IPXCMPNODE(nr->rnode, rnode) ) {
|
||||
/* only delete the routes, which we have inserted */
|
||||
XDPRINTF((2,0,"ROUTE DEL NET=0x%x over Router NET 0x%x",
|
||||
nr->net, rnet));
|
||||
ipx_route_del(nr->net);
|
||||
|
||||
ipx_route_del(nr->net);
|
||||
if (nd_dev != NULL) { /* this is net to our device */
|
||||
/* I must delete and setup new, because there is */
|
||||
/* no direct way to delete this route from interface :( */
|
||||
@ -135,7 +135,7 @@ static void insert_delete_net(uint32 destnet,
|
||||
|
||||
ticks+=ndticks;
|
||||
if (ticks <= nr->ticks) {
|
||||
if (ticks == nr->ticks && hops >= nr->hops) return;
|
||||
if (ticks == nr->ticks && hops > nr->hops) return;
|
||||
nr->hops = hops;
|
||||
nr->ticks = ticks;
|
||||
nr->rnet = rnet;
|
||||
@ -475,7 +475,7 @@ void handle_rip(int fd, int ipx_pack_typ,
|
||||
|
||||
if (is_response) {
|
||||
insert_delete_net(net, GET_BE32(from_addr->net),
|
||||
from_addr->node, hops, ticks, (hops > 15) ? 1 : 0);
|
||||
from_addr->node, hops, ticks, (hops > 15) ? 1 : 0);
|
||||
} else { /* rip request */
|
||||
build_rip_buff(net);
|
||||
if (net == MAX_U32) break;
|
||||
@ -607,6 +607,10 @@ static FILE *open_route_info_fn(int force, FILE *ff, int section)
|
||||
} else {
|
||||
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");
|
||||
if (section == 1) {
|
||||
if (NULL != f)
|
||||
@ -699,12 +703,13 @@ static int look_for_interfaces(void);
|
||||
|
||||
|
||||
void send_sap_rip_broadcast(int mode)
|
||||
/* mode=0, standard broadcast */
|
||||
/* mode=1, first trie */
|
||||
/* mode=2, shutdown */
|
||||
/* mode=3, update routes */
|
||||
/* mode=4, resend to net */
|
||||
/* mode=5, force update routes */
|
||||
/* mode=0, standard broadcast */
|
||||
/* mode=1, first trie */
|
||||
/* mode=2, sap shutdown */
|
||||
/* mode=3, update routes */
|
||||
/* mode=4, resend to net */
|
||||
/* mode=5, force update routes */
|
||||
/* mode=22, rip shutdown */
|
||||
{
|
||||
static int flipflop=1;
|
||||
int force_print_routes=(mode == 1) ? 1 : 0;
|
||||
@ -720,16 +725,20 @@ static int flipflop=1;
|
||||
send_rip_broadcast(1);
|
||||
send_sap_broadcast(1);
|
||||
}
|
||||
} else if (mode == 22) {
|
||||
send_rip_broadcast(2);
|
||||
} else if (mode == 2) {
|
||||
send_sap_broadcast(2);
|
||||
} else {
|
||||
send_rip_broadcast(mode);
|
||||
send_sap_broadcast(mode);
|
||||
}
|
||||
} else {
|
||||
if (flipflop) {
|
||||
send_rip_broadcast(mode);
|
||||
send_rip_broadcast(0);
|
||||
flipflop=0;
|
||||
} else {
|
||||
send_sap_broadcast(mode);
|
||||
send_sap_broadcast(0);
|
||||
flipflop=1;
|
||||
}
|
||||
}
|
||||
@ -948,8 +957,8 @@ static int look_for_interfaces(void)
|
||||
for (j=0; j < anz_routes; j++){
|
||||
NW_ROUTES *nr=nw_routes[j];
|
||||
if (nr && nr->rnet == nd->net) {
|
||||
XDPRINTF((1,0,"Route to net=0x%x removed", nr->net)); /* !! */
|
||||
nr->net = 0L; /* remove route */
|
||||
XDPRINTF((1,0,"Route to net=0x%x removed", nr->net));
|
||||
}
|
||||
}
|
||||
if (nd->wildmask & 1)
|
||||
|
22
nwroute1.c
22
nwroute1.c
@ -123,8 +123,8 @@ void get_servers(void)
|
||||
SQP sqp;
|
||||
ipxAddr_t wild;
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
#ifdef xxxLINUX
|
||||
U32_TO_BE32(internal_net, wild.net);
|
||||
#ifdef FREEBSD
|
||||
U32_TO_BE32(internal_net, wild.net); /* ask ONLY IPXrouted */
|
||||
memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE);
|
||||
#else
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
@ -150,11 +150,9 @@ void send_sap_rip_broadcast(int mode)
|
||||
IPX_DATA ipx_data;
|
||||
ipxAddr_t wild;
|
||||
memset(&wild, 0, sizeof(ipxAddr_t));
|
||||
#ifdef xxxLINUX
|
||||
U32_TO_BE32(internal_net, wild.net);
|
||||
memcpy(wild.node, my_server_adr.node, IPX_NODE_SIZE);
|
||||
#else
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE);
|
||||
memset(wild.node, 0xFF, IPX_NODE_SIZE); /* broadcast */
|
||||
#ifdef FREEBSD
|
||||
U32_TO_BE32(internal_net, wild.net); /* there is no default net */
|
||||
#endif
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
memset(&ipx_data, 0, sizeof(ipx_data.sip));
|
||||
@ -169,6 +167,16 @@ void send_sap_rip_broadcast(int mode)
|
||||
sizeof(ipx_data.sip),
|
||||
(char *)&(ipx_data.sip),
|
||||
&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 == 1) {
|
||||
U16_TO_BE16(SOCK_SAP, wild.sock);
|
||||
|
174
nwserv.c
174
nwserv.c
@ -1,4 +1,4 @@
|
||||
/* nwserv.c 08-Feb-98 */
|
||||
/* nwserv.c 19-May-98 */
|
||||
/* MAIN Prog for NWSERV + NWROUTED */
|
||||
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
@ -93,14 +93,7 @@ static uint16 sock_nummern [NEEDED_SOCKETS];
|
||||
|
||||
int sockfd [NEEDED_SOCKETS];
|
||||
static struct pollfd polls[NEEDED_POLLS];
|
||||
#if 0
|
||||
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 pid_ncpserv = -1;
|
||||
static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */
|
||||
@ -353,25 +346,6 @@ static int start_nwbind(char *nwname)
|
||||
}
|
||||
|
||||
#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 =============================== */
|
||||
#ifndef _WDOG_TESTING_
|
||||
@ -509,23 +483,6 @@ static void send_bcasts(int conn)
|
||||
#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,
|
||||
int ipx_pack_typ,
|
||||
int data_len,
|
||||
@ -579,7 +536,6 @@ static void handle_sap(int fd,
|
||||
XDPRINTF((2,0, "SERVER %s IS GOING DOWN", name));
|
||||
insert_delete_server(name, type, NULL, NULL, 16, 1, 0);
|
||||
} else {
|
||||
get_server_data((char*)name, ad, from_addr);
|
||||
insert_delete_server(name, type, ad, from_addr, hops, 0, 0);
|
||||
if (type == 4) flag=1;
|
||||
}
|
||||
@ -635,10 +591,21 @@ static void handle_sap(int fd,
|
||||
static void response_ipx_diag(int fd, int ipx_pack_typ,
|
||||
ipxAddr_t *to_addr)
|
||||
{
|
||||
IPX_DATA ipxdata;
|
||||
DIAGRESP *dia = &ipxdata.diaresp;
|
||||
uint8 *p = (uint8*) (dia+1);
|
||||
int datalen = sizeof(DIAGRESP); /* erstmal */
|
||||
IPX_DATA ipxdata;
|
||||
DIAGRESP *dia = &ipxdata.diaresp;
|
||||
uint8 *p = (uint8*) (dia+1);
|
||||
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->minorversion = 1;
|
||||
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 */
|
||||
*p++ = 6; /* Fileserver/Bridge (internal) */
|
||||
datalen++;
|
||||
*p++ = 1; /* Anz. Networks */
|
||||
net_count = p++;
|
||||
*net_count = 0;
|
||||
datalen++;
|
||||
*p++ = 0; /* LAN BOARD */
|
||||
datalen++;
|
||||
memcpy(p, my_server_adr.net, IPX_NET_SIZE);
|
||||
p += IPX_NET_SIZE;
|
||||
datalen += IPX_NET_SIZE;
|
||||
memcpy(p, my_server_adr.node, IPX_NODE_SIZE);
|
||||
datalen += IPX_NODE_SIZE;
|
||||
/* --- Code by Valeri Bourak ----- */
|
||||
if (internal_net) {
|
||||
(*net_count)++;
|
||||
*p++ = 1; /* virtual board */
|
||||
datalen++;
|
||||
U32_TO_BE32(internal_net, p);
|
||||
p += IPX_NET_SIZE;
|
||||
datalen += IPX_NET_SIZE;
|
||||
memcpy(p, my_server_adr.node, IPX_NODE_SIZE);
|
||||
p += 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,
|
||||
datalen,
|
||||
(char*)&ipxdata,
|
||||
@ -701,8 +694,6 @@ static void handle_extern_call(int fd,
|
||||
memcpy(&auth_addr, from_addr, sizeof(ipxAddr_t));
|
||||
is_auth=0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -963,11 +954,6 @@ static void get_ini(int full)
|
||||
max_connections=MAX_CONNECTIONS;
|
||||
}
|
||||
break;
|
||||
|
||||
case 104 : /* nwclient */
|
||||
if (client_mode && atoi(inhalt))
|
||||
client_mode++;
|
||||
break;
|
||||
#endif
|
||||
case 210 : server_goes_down_secs=atoi(inhalt);
|
||||
if (server_goes_down_secs < 1 ||
|
||||
@ -1005,9 +991,6 @@ static void get_ini(int full)
|
||||
} /* while */
|
||||
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)
|
||||
print_route_tac = 0;
|
||||
if (!print_route_tac) xfree(pr_route_info_fn);
|
||||
@ -1091,9 +1074,16 @@ static void close_all(void)
|
||||
t_close(ipx_out_fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (j--) {
|
||||
t_unbind(sockfd[j]);
|
||||
t_close(sockfd[j]);
|
||||
#ifdef RIP_SLOT
|
||||
if ( j != RIP_SLOT ) {
|
||||
#endif
|
||||
t_unbind(sockfd[j]);
|
||||
t_close(sockfd[j]);
|
||||
#ifdef RIP_SLOT
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pid_ncpserv > 0) {
|
||||
@ -1121,15 +1111,25 @@ static void close_all(void)
|
||||
#ifdef LINUX
|
||||
# if INTERNAL_RIP_SAP
|
||||
#if 1
|
||||
if (!(ipx_flags&1)) {
|
||||
for (j=0; j<count_net_devices;j++) {
|
||||
NW_NET_DEVICE *nd=net_devices[j];
|
||||
if (nd->is_up==1) { /* only no auto interfaces */
|
||||
XDPRINTF((1, 0, "Close Device=%s, frame=%d",
|
||||
nd->devname, nd->frame));
|
||||
exit_dev(nd->devname, nd->frame);
|
||||
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)) {
|
||||
for (j=0; j<count_net_devices;j++) {
|
||||
NW_NET_DEVICE *nd=net_devices[j];
|
||||
if (nd->is_up==1) { /* only no auto interfaces */
|
||||
XDPRINTF((1, 0, "Close Device=%s, frame=%d",
|
||||
nd->devname, nd->frame));
|
||||
exit_dev(nd->devname, nd->frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
XDPRINTF((1, 0, "Not sending rip hangup, because ipxinuse"));
|
||||
}
|
||||
#endif
|
||||
exit_ipx(ipx_flags);
|
||||
@ -1238,7 +1238,7 @@ static int server_is_down=0;
|
||||
|
||||
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, "or:\t%s -a device frame netnum\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);
|
||||
#endif
|
||||
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-d: delete interface.\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-k: stop main process, wait for it.\n");
|
||||
fprintf(stderr, "\t-kq: don't wait till stop of main process\n");
|
||||
#endif
|
||||
#if !IN_NWROUTED
|
||||
fprintf(stderr, "\t y: start testclient code.\n");
|
||||
#endif
|
||||
@ -1267,12 +1269,16 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "You must have root permission !\n");
|
||||
exit(1);
|
||||
}
|
||||
#ifdef FREEBSD
|
||||
set_emu_tli();
|
||||
#endif
|
||||
tzset();
|
||||
while (++j < argc) {
|
||||
char *a=argv[j];
|
||||
if (*a == '-') {
|
||||
while (*(++a)) {
|
||||
switch (*a) {
|
||||
#ifdef LINUX
|
||||
case 'a' :
|
||||
case 'd' :
|
||||
if ( (*a == 'a' && argc - j == 4)
|
||||
@ -1297,23 +1303,24 @@ int main(int argc, char **argv)
|
||||
else if (!strcmp(buf, "TOKEN"))
|
||||
frame=IPX_FRAME_TR_8022;
|
||||
# endif
|
||||
|
||||
if (*a == 'a' && frame > -1) {
|
||||
char dummy;
|
||||
if (sscanf(argv[j+3], "%ld%c", &netnum, &dummy) != 1)
|
||||
sscanf(argv[j+3], "%lx", &netnum);
|
||||
}
|
||||
#if IN_NWROUTED || INTERNAL_RIP_SAP
|
||||
if (netnum > 0)
|
||||
result=add_device_net(argv[j+1], frame, netnum);
|
||||
else if ( *a == 'd') {
|
||||
exit_dev(argv[j+1], frame);
|
||||
result=0;
|
||||
} else
|
||||
#endif
|
||||
return(usage(argv[0]));
|
||||
return((result<0) ? 1 : 0);
|
||||
} else
|
||||
return(usage(argv[0]));
|
||||
|
||||
#endif
|
||||
case 'h' : init_mode = 1; break;
|
||||
case 'k' : init_mode = 2; break;
|
||||
case 'u' : init_mode = 3; break;
|
||||
@ -1326,13 +1333,7 @@ int main(int argc, char **argv)
|
||||
default : return(usage(argv[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !IN_NWROUTED
|
||||
else if (*a == 'y')
|
||||
client_mode=1;
|
||||
/* in client mode the testprog 'nwclient' will be startet. */
|
||||
#endif
|
||||
else
|
||||
} else
|
||||
return(usage(argv[0]));
|
||||
}
|
||||
#if !DO_TESTING
|
||||
@ -1555,7 +1556,6 @@ int main(int argc, char **argv)
|
||||
} else {
|
||||
#if !IN_NWROUTED
|
||||
if (call_wdog) send_wdogs(1);
|
||||
if (client_mode && difftime > 5) get_servers(); /* Here more often */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
4
nwserv.h
4
nwserv.h
@ -70,9 +70,9 @@ extern NW_NET_DEVICE **net_devices;
|
||||
|
||||
#if INTERNAL_RIP_SAP
|
||||
# define RIP_SLOT (SAP_SLOT +1)
|
||||
# define ROUTE_SLOT (RIP_SLOT +1)
|
||||
# define DIAG_SLOT (ROUTE_SLOT +1)
|
||||
# if 0
|
||||
# define ROUTE_SLOT (RIP_SLOT +1)
|
||||
# define DIAG_SLOT (ROUTE_SLOT +1)
|
||||
# define ECHO_SLOT (DIAG_SLOT +1)
|
||||
# define ERR_SLOT (ECHO_SLOT +1)
|
||||
# endif
|
||||
|
757
nwshare.c
757
nwshare.c
@ -1,6 +1,5 @@
|
||||
/* nwshare.c 21-Jul-97 */
|
||||
|
||||
/* (C)opyright (C) 1993,1997 Martin Stover, Marburg, Germany
|
||||
/* nwshare.c, 13-Apr-00 */
|
||||
/* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -26,59 +25,216 @@
|
||||
#include "unxfile.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 {
|
||||
int fd_r;
|
||||
int fd_wr;
|
||||
int in_use;
|
||||
typedef struct _tagShareLock {
|
||||
int l_start;
|
||||
int l_len;
|
||||
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;
|
||||
} SH_OP_DEV;
|
||||
|
||||
static SH_OP_DEV sh_op_devs[MAX_SH_OP_DEV];
|
||||
static int count_sh_op_dev=0;
|
||||
int fd_sm; /* semaphor for locking operation */
|
||||
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)
|
||||
/* sh_mode
|
||||
* 0 : remove share
|
||||
* 1 : add_ro_r_share
|
||||
* 4 : add_ro_w_share
|
||||
*
|
||||
* 2 : add_wr_r_share
|
||||
* 8 : add_wr_w_share
|
||||
* ----
|
||||
* 0x10 : test
|
||||
static char *path_share_lock_files=NULL;
|
||||
|
||||
int share_file(int dev, int inode, int open_mode, int action)
|
||||
/* open_mode is the same as 'access' in file_creat_open():
|
||||
* 0x001 = open for read
|
||||
* 0x002 = open for write
|
||||
* 0x004 = deny read
|
||||
* 0x008 = deny write
|
||||
|
||||
********* 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;
|
||||
int fr = -1;
|
||||
int fo = -1;
|
||||
int result = -1;
|
||||
SH_OP_DEV *sod;
|
||||
ShareDev *sd = NULL, **psd;
|
||||
ShareINode *si = NULL, **psi;
|
||||
int result = 0, act_mode = 0;
|
||||
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--) {
|
||||
sod=&(sh_op_devs[k]);
|
||||
if (sod->fd_r < 0) {
|
||||
fr=k;
|
||||
} else if (sod->dev == dev) {
|
||||
fo=k;
|
||||
if (open_mode==0) {
|
||||
XDPRINTF((1, 0, "Wrong openmode in share_file %s", tbuf));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!sh_mode) && fo==-1) {
|
||||
XDPRINTF((1, 0, "Could not found share to remove"));
|
||||
if (action==0 && !si) {
|
||||
XDPRINTF((1, 0, "Could not find share inode to remove %s", tbuf));
|
||||
if (!sd->first_inode) {
|
||||
*psd = sd->next;
|
||||
xfree( sd );
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (fo==-1 && fr==-1) {
|
||||
if (count_sh_op_dev < MAX_SH_OP_DEV)
|
||||
fr=count_sh_op_dev++;
|
||||
else {
|
||||
XDPRINTF((1, 0, "Too much 'share devs'"));
|
||||
if (!si) {
|
||||
/* new inode */
|
||||
si = (ShareINode*) xcmalloc( sizeof(ShareINode) );
|
||||
if (!si) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -87,79 +243,470 @@ int share_file(int dev, int inode, int sh_mode)
|
||||
flockd.l_start = inode;
|
||||
flockd.l_len = 1;
|
||||
|
||||
if (!sh_mode) {
|
||||
sod=&(sh_op_devs[fo]);
|
||||
flockd.l_type = F_UNLCK;
|
||||
(void)fcntl(sod->fd_r, F_SETLK, &flockd);
|
||||
(void)fcntl(sod->fd_wr, F_SETLK, &flockd);
|
||||
if (--sod->in_use < 1) {
|
||||
close(sod->fd_r);
|
||||
close(sod->fd_wr);
|
||||
sod->fd_r = -1;
|
||||
sod->fd_wr = -1;
|
||||
sod->dev = -1;
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
flockd.l_type = F_WRLCK;
|
||||
fcntl(sd->fd_sm, F_SETLKW, &flockd); /* set semaphor */
|
||||
|
||||
l=sprintf(buff, "%s/%x.r", path_share_lock_files, dev);
|
||||
seteuid(0);
|
||||
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;
|
||||
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 ++;
|
||||
}
|
||||
reseteuid();
|
||||
|
||||
if (sod->fd_r < 0) {
|
||||
XDPRINTF((1, 0, "Cannot open sharefile=`%s`", buff));
|
||||
return(-1);
|
||||
if (open_mode & 0x04) { /* deny read */
|
||||
if (!si->dr) {
|
||||
flockd.l_type = F_RDLCK;
|
||||
fcntl(sd->fd_dr, F_SETLK, &flockd);
|
||||
}
|
||||
si->dr ++;
|
||||
}
|
||||
sod->dev = dev;
|
||||
} else
|
||||
sod=&(sh_op_devs[fo]);
|
||||
|
||||
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 (open_mode & 0x02) { /* write */
|
||||
if (!si->ow) {
|
||||
flockd.l_type = F_RDLCK;
|
||||
fcntl(sd->fd_ow, F_SETLK, &flockd);
|
||||
}
|
||||
si->ow ++;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
XDPRINTF((3, 0, "Cannot lock share sh_mode=%d", sh_mode));
|
||||
} else {
|
||||
sod->in_use++;
|
||||
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 { /* 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;
|
||||
}
|
||||
} else if (action==0) { /* REMOVE */
|
||||
flockd.l_type = F_UNLCK;
|
||||
if (open_mode & 0x01) /* read */
|
||||
if (si->or && !(--si->or))
|
||||
fcntl(sd->fd_or, F_SETLK, &flockd);
|
||||
if (open_mode & 0x04) /* deny read */
|
||||
if (si->dr && !(--si->dr))
|
||||
fcntl(sd->fd_dr, F_SETLK, &flockd);
|
||||
if (open_mode & 0x02) /* write */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
flockd.l_type = F_UNLCK;
|
||||
fcntl(sd->fd_sm, F_SETLK, &flockd); /* realise semaphor */
|
||||
|
||||
if (!si->or && !si->ow && !si->dr && !si->dw
|
||||
#if 0
|
||||
&& !si->cm
|
||||
#endif
|
||||
&& !si->fl ) {
|
||||
/* release inode */
|
||||
while (si->first_lock) {
|
||||
ShareLock *p = si->first_lock;
|
||||
si->first_lock = p->next;
|
||||
xfree( p );
|
||||
}
|
||||
*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
|
||||
result = -1;
|
||||
} else {
|
||||
/* lock or test */
|
||||
if (sl && (l_start < sl->l_start + sl->l_len || !sl->l_len)
|
||||
&& (sl->exclusive || lock_flag == 1) )
|
||||
result = -1; /* collision */
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
15
nwshare.h
15
nwshare.h
@ -1,8 +1,17 @@
|
||||
/* nwshare.h: 20-Jul-97*/
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
/* nwshare.h: 25-Sep-99*/
|
||||
/* (C)opyright (C) 1993-1999 Martin Stover, Marburg, Germany
|
||||
*/
|
||||
|
||||
#ifndef _NWSHARE_H_
|
||||
#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
|
||||
|
359
nwvolume.c
359
nwvolume.c
@ -1,5 +1,5 @@
|
||||
/* nwvolume.c 01-Feb-98 */
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
/* nwvolume.c 09-Oct-99 */
|
||||
/* (C)opyright (C) 1993-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
|
||||
@ -20,7 +20,14 @@
|
||||
|
||||
#include <dirent.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
|
||||
#include <sys/statvfs.h>
|
||||
@ -30,8 +37,12 @@
|
||||
#include <utime.h>
|
||||
|
||||
#include "nwfname.h"
|
||||
#include "nwattrib.h"
|
||||
#include "trustee.h"
|
||||
#include "nwvolume.h"
|
||||
|
||||
#define VOLOPTIONS_DEFAULT VOL_OPTION_ATTRIBUTES
|
||||
|
||||
NW_VOL *nw_volumes=NULL;
|
||||
int used_nw_volumes=0;
|
||||
int loaded_namespaces=0;
|
||||
@ -39,9 +50,45 @@ uint8 *home_dir=NULL;
|
||||
int home_dir_len=0;
|
||||
char *path_vol_inodes_cache=NULL;
|
||||
char *path_attributes=NULL;
|
||||
char *path_trustees=NULL;
|
||||
|
||||
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)
|
||||
{
|
||||
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));
|
||||
return;
|
||||
}
|
||||
vol->dev = statb.st_dev;
|
||||
vol->inode = statb.st_ino;
|
||||
dnm.dev = statb.st_dev;
|
||||
dnm.namespace = 0; /* NAMESPACE DOS */
|
||||
(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)
|
||||
xfree(nw_volumes[k].dev_namespace_maps[i]);
|
||||
nw_volumes[k].maps_count = 0;
|
||||
free_vol_trustee(&nw_volumes[k]);
|
||||
}
|
||||
}
|
||||
rewind(f);
|
||||
used_nw_volumes = 0;
|
||||
loaded_namespaces = 0;
|
||||
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)))) {
|
||||
if ( what == 1 && used_nw_volumes < max_nw_vols && strlen((char*)buff) > 3){
|
||||
uint8 sysname[256];
|
||||
@ -97,14 +148,14 @@ void nw_init_volumes(FILE *f)
|
||||
sysname, unixname, optionstr, umode_dirstr, umode_filestr);
|
||||
if (founds > 1) {
|
||||
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;
|
||||
up_fn(sysname);
|
||||
new_str(vol->sysname, sysname);
|
||||
len = strlen((char*)unixname);
|
||||
if (unixname[0] == '~' && (unixname[1]=='\0' || unixname[1]=='/')) {
|
||||
vol->options |= VOL_OPTION_IS_HOME;
|
||||
vol->options |= VOL_OPTION_REMOUNT;
|
||||
if (len > 2) { /* tail is present */
|
||||
if (unixname[len-1] != '/') {
|
||||
unixname[len++] = '/';
|
||||
@ -135,6 +186,10 @@ void nw_init_volumes(FILE *f)
|
||||
|= VOL_OPTION_DOWNSHIFT;
|
||||
break;
|
||||
|
||||
case 'n' : vol->options
|
||||
|= VOL_OPTION_NO_INODES;
|
||||
break;
|
||||
|
||||
case 'm' : vol->options
|
||||
|= VOL_OPTION_REMOUNT;
|
||||
break;
|
||||
@ -151,6 +206,15 @@ void nw_init_volumes(FILE *f)
|
||||
|= VOL_OPTION_READONLY;
|
||||
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
|
||||
|= 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->high_inode = 0xfffffff;
|
||||
}
|
||||
|
||||
if (vol->unixnamlen)
|
||||
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 */
|
||||
new_str(path_vol_inodes_cache, buff);
|
||||
} else if (what==46) { /* path for attribute handling */
|
||||
new_str(path_attributes, buff);
|
||||
} else if (what==47) { /* path for trustees handling */
|
||||
new_str(path_trustees, buff);
|
||||
}
|
||||
} /* 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;
|
||||
uint8 unixname[258];
|
||||
uint8 fullname[258];
|
||||
|
||||
unixname[0] = '\0';
|
||||
xfree(home_dir);
|
||||
home_dir_len=0;
|
||||
if (len > 0) {
|
||||
strmaxcpy(unixname, fn, len);
|
||||
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 {
|
||||
strcpy(fullname, unixname);
|
||||
/* concatenation $HOME/ and add/on/ */
|
||||
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]));
|
||||
struct passwd *pw;
|
||||
int len=0;
|
||||
endpwent();
|
||||
if (unxlogin && *unxlogin && NULL != (pw=getpwnam(unxlogin))) {
|
||||
len=strlen(pw->pw_dir);
|
||||
if (!len) {
|
||||
*homedir++ = '/';
|
||||
*homedir = '\0';
|
||||
len =1;
|
||||
} else {
|
||||
if (len > 255) len=255;
|
||||
strmaxcpy(homedir, pw->pw_dir, len);
|
||||
}
|
||||
} else {
|
||||
*homedir='\0';
|
||||
}
|
||||
endpwent();
|
||||
return(len);
|
||||
}
|
||||
|
||||
void nw_setup_vol_opts(int act_gid, int act_uid,
|
||||
int act_umode_dir, int act_umode_file,
|
||||
int homepathlen, uint8 *homepath)
|
||||
|
||||
uint8 *unxlogin)
|
||||
/* set's homevolume and volume's umodes */
|
||||
{
|
||||
int k=used_nw_volumes;
|
||||
uint8 unixname[258];
|
||||
uint8 fullname[258];
|
||||
|
||||
uint8 homepath[258];
|
||||
int homepathlen=get_unx_home_dir(homepath, unxlogin);
|
||||
unixname[0] = '\0';
|
||||
xfree(home_dir);
|
||||
home_dir_len=0;
|
||||
@ -263,26 +321,30 @@ void nw_setup_vol_opts(int act_gid, int act_uid,
|
||||
home_dir_len=homepathlen;
|
||||
}
|
||||
|
||||
while (k--) { /* now set all HOME volumes */
|
||||
while (k--) {
|
||||
uint8 *fname;
|
||||
int flen;
|
||||
if (nw_volumes[k].options & VOL_OPTION_IS_HOME) {
|
||||
/* now set HOME volumes */
|
||||
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 = homepathlen;
|
||||
#if 0 /* removed in 0.99.pl14, 03-Nov-98 */
|
||||
nw_volumes[k].umode_dir = 0;
|
||||
nw_volumes[k].umode_file = 0;
|
||||
#endif
|
||||
if (homepathlen > 0 && nw_volumes[k].addonlen) {
|
||||
if (homepathlen + nw_volumes[k].addonlen > 256) {
|
||||
flen = 0;
|
||||
fname = "";
|
||||
} else {
|
||||
strcpy(fullname, unixname);
|
||||
xstrcpy(fullname, unixname);
|
||||
/* 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;
|
||||
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)
|
||||
nw_volumes[k].umode_file=act_umode_file;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -387,13 +447,13 @@ int nw_get_volume_number(uint8 *volname, int namelen)
|
||||
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 */
|
||||
{
|
||||
int result = -0x98; /* Volume not exist */;
|
||||
if (volnr > -1 && volnr < used_nw_volumes) {
|
||||
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);
|
||||
} else result= strlen((char*)nw_volumes[volnr].sysname);
|
||||
} else {
|
||||
@ -413,14 +473,28 @@ int nw_get_volume_name(int volnr, uint8 *volname)
|
||||
|
||||
int get_volume_umode_dir(int volnr)
|
||||
{
|
||||
return( (volnr > -1 && volnr < used_nw_volumes) ?
|
||||
nw_volumes[volnr].umode_dir : 0);
|
||||
if (volnr > -1 && volnr < used_nw_volumes) {
|
||||
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)
|
||||
{
|
||||
return( (volnr > -1 && volnr < used_nw_volumes) ?
|
||||
nw_volumes[volnr].umode_file : 0);
|
||||
if (volnr > -1 && volnr < used_nw_volumes) {
|
||||
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 */
|
||||
@ -468,12 +542,16 @@ fsd.f_bsize = 1024;
|
||||
fsp->fsu_ffree = fsd.f_ffree;
|
||||
|
||||
if (limit) {
|
||||
if (fsp->fsu_blocks > 4000000)
|
||||
if (fsp->fsu_blocks > 4000000) {
|
||||
fsp->fsu_blocks = 4000000;
|
||||
if (fsp->fsu_bfree > 4000000)
|
||||
}
|
||||
if (fsp->fsu_bfree > 4000000) {
|
||||
fsp->fsu_bfree = 4000000;
|
||||
}
|
||||
if (fsp->fsu_bavail > 4000000) {
|
||||
fsp->fsu_bavail = 4000000;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -507,6 +585,10 @@ int get_volume_inode(int volnr, struct stat *stb)
|
||||
/* returns inode if OK, else errocode < 0 */
|
||||
{
|
||||
int result = -0x98; /* Volume not exist */;
|
||||
if (stb) {
|
||||
stb->st_mode=0;
|
||||
stb->st_ino=0;
|
||||
}
|
||||
if (volnr > -1 && volnr < used_nw_volumes) {
|
||||
struct stat statb;
|
||||
if (!stb) stb=&statb;
|
||||
@ -518,6 +600,137 @@ int get_volume_inode(int volnr, struct stat *stb)
|
||||
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
|
||||
|
||||
@ -561,11 +774,17 @@ const char *find_device_file(const char *path)
|
||||
return(mount_device);
|
||||
}
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef LINUX
|
||||
# include <linux/quota.h>
|
||||
# ifndef QTAINSYS
|
||||
# include <linux/quota.h>
|
||||
# else
|
||||
# ifdef _GNU_SOURCE_
|
||||
# include <asm/types.h>
|
||||
# endif
|
||||
# include <sys/quota.h>
|
||||
# endif
|
||||
|
||||
# if defined(__alpha__)
|
||||
# include <errno.h>
|
||||
# include <syscall.h>
|
||||
|
64
nwvolume.h
64
nwvolume.h
@ -1,5 +1,5 @@
|
||||
/* nwvolume.h 01-Feb-98 */
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
/* nwvolume.h 09-Oct-99 */
|
||||
/* (C)opyright (C) 1993-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
|
||||
@ -31,12 +31,22 @@ typedef struct {
|
||||
* without loosing too many places.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8 *path;
|
||||
uint8 len;
|
||||
int trustee;
|
||||
} VOLUME_TRUSTEE;
|
||||
|
||||
typedef struct {
|
||||
uint8 *sysname; /* VOL_NAME */
|
||||
uint8 *unixname; /* UNIX-DIR with ending '/' */
|
||||
int unixnamlen; /* len of unixname */
|
||||
/* next 2 fields added by Andrew Sapozhnikov */
|
||||
/* for Extend "Volume is home" feature */
|
||||
|
||||
int dev; /* dev and inode of volume root */
|
||||
int inode;
|
||||
|
||||
uint8 *homeaddon; /* tail for $HOME-relative volumes */
|
||||
int addonlen; /* len of tail part of unixname */
|
||||
DEV_NAMESPACE_MAP *dev_namespace_maps[MAX_DEV_NAMESPACE_MAPS];
|
||||
@ -48,21 +58,34 @@ typedef struct {
|
||||
|
||||
int umode_dir; /* umask/umode for creating dirs */
|
||||
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;
|
||||
|
||||
/* vol options */
|
||||
#define VOL_OPTION_DOWNSHIFT 0x0001 /* downshift */
|
||||
#define VOL_OPTION_IS_PIPE 0x0002 /* Volume contains pipes */
|
||||
#define VOL_OPTION_REMOUNT 0x0004 /* Volume can be remounted (cdroms) */
|
||||
#define VOL_OPTION_IS_HOME 0x0008 /* Volume is USERS HOME */
|
||||
#define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */
|
||||
#define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */
|
||||
#define VOL_OPTION_IGNCASE 0x0040 /* Do ignore up/downshift */
|
||||
#define VOL_OPTION_DOWNSHIFT 0x0001 /* downshift */
|
||||
#define VOL_OPTION_IS_PIPE 0x0002 /* Volume contains pipes */
|
||||
#define VOL_OPTION_REMOUNT 0x0004 /* Volume can be remounted (cdroms) */
|
||||
#define VOL_OPTION_IS_HOME 0x0008 /* Volume is USERS HOME */
|
||||
#define VOL_OPTION_ONE_DEV 0x0010 /* Volume has only one filesys */
|
||||
#define VOL_OPTION_READONLY 0x0020 /* Volume is readonly */
|
||||
#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 */
|
||||
#define VOL_NAMESPACE_DOS 0x1000
|
||||
#define VOL_NAMESPACE_OS2 0x2000
|
||||
#define VOL_NAMESPACE_NFS 0x4000
|
||||
#define VOL_NAMESPACE_DOS 0x1000
|
||||
#define VOL_NAMESPACE_OS2 0x2000
|
||||
#define VOL_NAMESPACE_NFS 0x4000
|
||||
|
||||
/* stolen from GNU-fileutils */
|
||||
/* Space usage statistics for a filesystem. Blocks are 512-byte. */
|
||||
@ -81,14 +104,15 @@ extern uint8 *home_dir;
|
||||
extern int home_dir_len;
|
||||
extern char *path_vol_inodes_cache; /* for namespace routines */
|
||||
extern char *path_attributes; /* for attribute handling */
|
||||
extern char *path_trustees; /* for trustee handling */
|
||||
|
||||
extern void nw_init_volumes(FILE *f);
|
||||
extern void nw_setup_vol_opts(int act_gid, int act_uid,
|
||||
int act_umode_dir, int act_umode_file,
|
||||
int homepathlen, uint8 *homepath);
|
||||
extern void nw_setup_home_vol(int len, uint8 *fn);
|
||||
uint8 *unxlogin);
|
||||
|
||||
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_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 get_volume_options(int volnr);
|
||||
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_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,
|
||||
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
|
||||
|
192
tools.c
192
tools.c
@ -1,5 +1,5 @@
|
||||
/* tools.c 08-Feb-98 */
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
/* tools.c 18-Apr-00 */
|
||||
/* (C)opyright (C) 1993-2000 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -21,22 +21,42 @@
|
||||
#include <stdarg.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#if 0
|
||||
#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 char *_sys_errlist[];
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
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
|
||||
* 2 = only for errors
|
||||
*/
|
||||
|
||||
static int in_module=0; /* in which process i am ? */
|
||||
static int connection=0; /* which connection (nwconn) */
|
||||
static int my_pid = -1;
|
||||
static void (*sigsegv_func)(int isig);
|
||||
static char *modnames[] =
|
||||
@ -54,14 +74,41 @@ static char *get_modstr(void)
|
||||
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 *p = (size) ? (char *)malloc(size) : (char*)NULL;
|
||||
if (p == (char *)NULL && size){
|
||||
errorp(1, "xmalloc", "not enough core, need %d Bytes\n", size);
|
||||
exit(1);
|
||||
}
|
||||
return(p);
|
||||
if (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);
|
||||
exit(1);
|
||||
} else {
|
||||
XDPRINTF((1, 0, "Warning:could not alloc %d Bytes for %d tries",
|
||||
size, tries+1));
|
||||
}
|
||||
}
|
||||
return(p);
|
||||
} else
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
char *xcmalloc(uint size)
|
||||
@ -139,7 +186,8 @@ static char *buffered=NULL;
|
||||
}
|
||||
if (!(mode & 2)) {
|
||||
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);
|
||||
syslog(LOG_DEBUG, buf);
|
||||
closelog();
|
||||
@ -151,7 +199,8 @@ static char *buffered=NULL;
|
||||
xfree(buf);
|
||||
} else {
|
||||
if (!(mode & 1))
|
||||
fprintf(logfile, "%-8s %d:", get_modstr(), connection);
|
||||
fprintf(logfile, "%s %d %3d:", get_debstr(1),
|
||||
act_connection, act_ncpsequence);
|
||||
if (p) {
|
||||
va_start(ap, p);
|
||||
vfprintf(logfile, p, ap);
|
||||
@ -170,12 +219,14 @@ static char *buffered=NULL;
|
||||
}
|
||||
|
||||
void errorp(int mode, char *what, char *p, ...)
|
||||
/* mode > 9 without errno printing */
|
||||
/* mode == 1 || mode == 11 error = critical */
|
||||
{
|
||||
va_list ap;
|
||||
int errnum = errno;
|
||||
FILE *lologfile = logfile;
|
||||
char errbuf[200];
|
||||
char *errstr = errbuf;
|
||||
const char *errstr = errbuf;
|
||||
if (mode > 9) {
|
||||
errnum = -1;
|
||||
mode -= 10;
|
||||
@ -196,7 +247,7 @@ void errorp(int mode, char *what, char *p, ...)
|
||||
vsprintf(buf+l, p, 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);
|
||||
syslog(prio, buf);
|
||||
closelog();
|
||||
@ -204,8 +255,11 @@ void errorp(int mode, char *what, char *p, ...)
|
||||
lologfile=stderr;
|
||||
}
|
||||
while (1) {
|
||||
if (mode==1) fprintf(lologfile, "\n!! %-8s %d:PANIC !!\n", get_modstr(), connection);
|
||||
fprintf(lologfile, "%-8s %d:%s:%s\n", get_modstr(), connection, what, errstr);
|
||||
if (mode==1)
|
||||
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) {
|
||||
va_start(ap, p);
|
||||
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 *wpath;
|
||||
char *wpath=NULL;
|
||||
int len;
|
||||
uint8 locbuf[200];
|
||||
switch (what) {
|
||||
@ -349,7 +403,11 @@ int get_ini_int(int what)
|
||||
|
||||
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
|
||||
(*sigsegv_func)(isig);
|
||||
#endif
|
||||
@ -372,7 +430,9 @@ static void creat_pidfile(void)
|
||||
{
|
||||
char buf[300];
|
||||
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) {
|
||||
fprintf(f, "%d\n", getpid());
|
||||
fclose(f);
|
||||
@ -416,13 +476,14 @@ void init_tools(int module, int options)
|
||||
{
|
||||
uint8 buf[300];
|
||||
char logfilename[300];
|
||||
FILE *f=open_nw_ini();
|
||||
FILE *f;
|
||||
int withlog=0;
|
||||
int dodaemon=0;
|
||||
int new_log=0;
|
||||
in_module = module;
|
||||
logfile = stderr; /* preset */
|
||||
f = open_nw_ini();
|
||||
my_pid = getpid();
|
||||
connection = (NWCONN == module) ? options : 0;
|
||||
if (NWSERV == module || NWROUTED == module) {
|
||||
int kill_pid=-1;
|
||||
char *pidfn=get_pidfilefn((char*)buf);
|
||||
@ -434,7 +495,7 @@ void init_tools(int module, int options)
|
||||
kill_pid=-1;
|
||||
fclose(pf);
|
||||
}
|
||||
if (kill_pid < 0) unlink((char*)buf);
|
||||
if (kill_pid < 0) unlink(pidfn);
|
||||
}
|
||||
if (kill_pid > -1) {
|
||||
int sig;
|
||||
@ -655,38 +716,59 @@ int name_match(uint8 *s, uint8 *p)
|
||||
return ( (*s) ? 0 : 1);
|
||||
}
|
||||
|
||||
uint8 *station_fn=NULL;
|
||||
|
||||
int find_station_match(int entry, ipxAddr_t *addr)
|
||||
#ifndef LINUX
|
||||
/* UnixWare needs fixed sprintf function :-( */
|
||||
int fixed_sprintf(char *buf, char *p, ...)
|
||||
{
|
||||
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));
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, p);
|
||||
(void)vsprintf(buf, p, ap);
|
||||
va_end(ap);
|
||||
return(strlen(buf));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* to be compatible with new 'SAMBA trustee code' */
|
||||
int slprintf(char *buf, int bufsize, char *p, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
va_start(ap, p);
|
||||
len = vsnprintf(buf, bufsize+1, p, ap);
|
||||
va_end(ap);
|
||||
if (len > bufsize || len < 0) {
|
||||
buf[bufsize] = 0;
|
||||
return(-1);
|
||||
}
|
||||
XDPRINTF((3, 0, "find_station_match entry=%d, matched=%d, addr=%s",
|
||||
entry, matched, visable_ipx_adr(addr)));
|
||||
return(matched);
|
||||
buf[len] = 0;
|
||||
return(len);
|
||||
}
|
||||
|
||||
#define MAX_TMP_STRINGS 3
|
||||
static char *tmpstr[MAX_TMP_STRINGS]={NULL};
|
||||
static int tmpstrcounter=0;
|
||||
|
||||
char *gettmpstr(char *qs, int len, int extralen)
|
||||
{
|
||||
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
23
tools.h
@ -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
|
||||
* 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 uint8 *station_fn;
|
||||
extern int find_station_match(int entry, ipxAddr_t *addr);
|
||||
|
||||
extern int nw_debug;
|
||||
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"
|
||||
#if DO_DEBUG
|
||||
# define XDPRINTF(x) xdprintf x
|
||||
@ -82,5 +84,16 @@ extern uint32 debug_mask;
|
||||
# define MDEBUG(mask, x) /* */
|
||||
#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_ */
|
||||
|
||||
|
33
tools.sh
Executable file
33
tools.sh
Executable 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
923
trustee.c
Normal 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
61
trustee.h
Normal 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
|
17
unxfile.c
17
unxfile.c
@ -1,4 +1,4 @@
|
||||
/* unxfile.c: 05-Feb-98*/
|
||||
/* unxfile.c: 30-Apr-98*/
|
||||
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
*
|
||||
@ -72,7 +72,7 @@ int unx_xrmdir(char *unixname)
|
||||
/* removes complete directory if possible */
|
||||
{
|
||||
DIR *d = opendir(unixname);
|
||||
if (NULL != (d = opendir(unixname))) {
|
||||
if (NULL != d) {
|
||||
struct dirent *dirbuff;
|
||||
int len = strlen(unixname);
|
||||
char *buf = xmalloc(len + 300);
|
||||
@ -80,10 +80,15 @@ int unx_xrmdir(char *unixname)
|
||||
memcpy(buf, unixname, len);
|
||||
*p++ = '/';
|
||||
while ((dirbuff = readdir(d)) != (struct dirent*)NULL){
|
||||
if (dirbuff->d_ino) {
|
||||
strcpy(p, dirbuff->d_name);
|
||||
if (unlink(buf) && unx_xrmdir(buf))
|
||||
if (dirbuff->d_ino &&
|
||||
( dirbuff->d_name[0] != '.'
|
||||
|| (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
xfree(buf);
|
||||
@ -115,7 +120,7 @@ int unx_ftruncate(int fd, uint32 size)
|
||||
flockd.l_whence = SEEK_SET;
|
||||
flockd.l_start = size;
|
||||
flockd.l_len = 0;
|
||||
result = fcntl(fd, F_FREESP, &flockd);
|
||||
return(fcntl(fd, F_FREESP, &flockd));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
15
unxfile.h
15
unxfile.h
@ -1,4 +1,4 @@
|
||||
/* unxfile.h: 05-Feb-98 */
|
||||
/* unxfile.h: 23-Jul-98 */
|
||||
/* (C)opyright (C) 1993,1998 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* 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_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
|
||||
|
||||
|
4
unxlog.c
4
unxlog.c
@ -1,4 +1,4 @@
|
||||
/* unxlog.c : 30-Apr-96 */
|
||||
/* unxlog.c : 11-Jul-98 */
|
||||
/* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany
|
||||
*
|
||||
* 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,
|
||||
ipxAddr_t *from_addr, uint8 *username)
|
||||
{
|
||||
#ifndef FREEBSD
|
||||
struct utmp loc_ut;
|
||||
struct utmp *ut;
|
||||
int fd;
|
||||
@ -74,4 +75,5 @@ void write_utmp(int dologin, int connection, int pid,
|
||||
write(fd, (char *)ut, sizeof(struct utmp));
|
||||
close(fd);
|
||||
}
|
||||
#endif /* !FREEBSD */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user