diff --git a/connect.c b/connect.c index 92c0a45..d111599 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 09-Aug-96 */ +/* connect.c 04-Oct-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -30,6 +30,8 @@ static int default_uid=-1; static int default_gid=-1; +static int default_umode_dir=0775; +static int default_umode_file=0664; #include "nwvolume.h" #include "nwfile.h" @@ -39,6 +41,12 @@ NW_DIR dirs[MAX_NW_DIRS]; int used_dirs=0; int act_uid=-1; int act_gid=-1; +int act_obj_id=0L; /* not login */ +int entry8_flags=0; /* special login/logout/flags */ +int act_umode_dir=0; +int act_umode_file=0; + +static gid_t *act_grouplist=NULL; /* first element is counter !! */ static int connect_is_init = 0; @@ -167,12 +175,15 @@ void set_default_guid(void) seteuid(0); setgroups(0, NULL); if (setegid(default_gid) < 0 || seteuid(default_uid) < 0) { - errorp(1, "set_default_guid, !! Abort !!", + 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; + act_umode_dir = default_umode_dir; + act_umode_file = default_umode_file; + xfree(act_grouplist); } void set_guid(int gid, int uid) @@ -182,7 +193,7 @@ void set_guid(int gid, int uid) || setegid(gid) || seteuid(uid) ) { set_default_guid(); - } else { + } else if (act_gid != gid || act_uid != uid) { struct passwd *pw = getpwuid(uid); if (NULL != pw) { seteuid(0); @@ -190,12 +201,98 @@ void set_guid(int gid, int uid) } act_gid = gid; act_uid = uid; - if (seteuid(uid)) set_default_guid(); + + act_umode_dir = default_umode_dir; + act_umode_file = default_umode_file; + + 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 set_act_obj_id(uint32 obj_id) +{ + act_obj_id=obj_id; + XDPRINTF((5, 0, "actual obj_id is set to 0x%x", obj_id)); +} + +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_real_access(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) ; + 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); +} + +uint32 get_file_owner(struct stat *stb) +/* returns nwuser creator of file */ +{ + uint32 owner=1L; /* default Supervisor */ + if (act_obj_id && stb && (stb->st_uid == act_uid)) + owner=act_obj_id; + XDPRINTF((5, 0, "get_file_owner owner=0x%x", owner)); + return(owner); +} + static char *conn_get_nwpath_name(NW_PATH *p) /* for debugging */ { @@ -670,20 +767,37 @@ static int nw_path_ok(NW_PATH *nwpath) int j = 0; NW_DIR *d=&(dirs[0]); struct stat stbuff; - int result = -0x9c; /* wrong path */ + int result=0; - while (j++ < (int)used_dirs){ - if (d->inode && d->volume == nwpath->volume - && !strcmp((char*)nwpath->path, (char*)d->path)){ - return(d->inode); + if ((!act_obj_id) && !(entry8_flags & 1)) { + if (nwpath->volume) + result = -0x9c; /* wrong path, only volume 0 is OK */ + else { + char *p=nwpath->path; + char pp[10]; + while (*p=='/') ++p; + strmaxcpy(pp, p, 6); + upstr(pp); + p=pp+5; + if (memcmp(pp, "LOGIN", 5) || (*p!='\0' && *p!='/') ) + result=-0x9c; } - d++; - } /* while */ - if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff) - && (stbuff.st_mode & S_IFMT) == S_IFDIR) result=stbuff.st_ino; - else { - XDPRINTF((4,0, "NW_PATH_OK failed:`%s`", conn_get_nwpath_name(nwpath))); } + + if (!result) { + while (j++ < (int)used_dirs){ + if (d->inode && d->volume == nwpath->volume + && !strcmp((char*)nwpath->path, (char*)d->path)){ + return(d->inode); + } + d++; + } /* while */ + if (!stat(build_unix_name(nwpath, 1 | 2 ), &stbuff) + && (stbuff.st_mode & S_IFMT) == S_IFDIR) + return(stbuff.st_ino); + result = -0x9c; /* wrong path */ + } + XDPRINTF((4,0x10, "NW_PATH_OK failed:`%s`", conn_get_nwpath_name(nwpath))); return(result); } @@ -739,13 +853,15 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ else state++; } else if (state == 14) completition= -0x9c; /* something wrong */ else if (state == 20){ + if (ppp > nwpath->path) + ppp=nwpath->path; if (w == '/') state = 30; else if (w != '.') completition= -0x9c; /* something wrong */ } if (state == 30 || !*p) { /* now action */ uint8 *xpath=a; int len = (int)(p-a); - if (len && state == 30) --len; /* '/' stoert hier */ + if (len && state == 30) --len; /* '/' don not need it here */ a = p; if (len) { if (*xpath == '.') { @@ -773,7 +889,6 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ } } } - if (!completition) { if (nwpath->volume > -1 && nwpath->volume < used_nw_volumes){ NW_VOL *v = &nw_volumes[nwpath->volume]; @@ -822,6 +937,27 @@ int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, return(completition); } +int conn_get_kpl_unxname(char *unixname, + int dirhandle, + uint8 *data, int len) +/* + * gives you the unixname of dirhandle + path + * returns volumenumber, or < 0 if error + */ +{ + NW_PATH nwpath; + int completition = build_path(&nwpath, data, len, 0); + if (!completition) + completition = build_verz_name(&nwpath, dirhandle); + if (completition > -1) { + if (unixname) + strcpy(unixname, build_unix_name(&nwpath, 0)); + completition=nwpath.volume; + } + XDPRINTF((5, 0, "conn_get_kpl_unxname: completition=0x%x", completition)); + return(completition); +} + void un_date_2_nw(time_t time, uint8 *d, int high_low) { struct tm *s_tm=localtime(&time); @@ -887,27 +1023,13 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode) /* UNIX access -> NW access */ attrib = 0x20; if (act_uid) { - if (act_uid == stb->st_uid) { - if (!(stb->st_mode & S_IWUSR)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IRUSR)) { - attrib |= 0x2; /* Hidden */ - } - } else if (act_gid == stb->st_gid) { - if (!(stb->st_mode & S_IWGRP)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IRGRP)) { - attrib |= 0x2; /* Hidden */ - } - } else { - if (!(stb->st_mode & S_IWOTH)) { - attrib |= 0x1; /* RO */ - } - if (!(stb->st_mode & S_IROTH)) { - attrib |= 0x2; /* Hidden */ - } + /* if not root */ + int acc=get_real_access(stb); + if (!(acc & W_OK)) { + attrib |= 0x1; /* RO */ + } + if (!(acc & R_OK)) { + attrib |= 0x2; /* We say hidden here */ } } /* only shared if gid == gid && x Flag */ @@ -916,7 +1038,6 @@ static int un_nw_attrib(struct stat *stb, int attrib, int mode) return(attrib); } else { /* NW access -> UNIX access */ - int mode = S_IRUSR | S_IRGRP; if (attrib & 0x2) /* hidden */ stb->st_mode &= ~mode; @@ -971,8 +1092,7 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, d->ext_attrib = 0xff; /* effektive rights ?? */ un_date_2_nw(stb->st_mtime, d->create_date, 1); un_time_2_nw(stb->st_mtime, d->create_time, 1); - - U32_TO_BE32(1L, d->owner_id); + U32_TO_BE32(get_file_owner(stb), d->owner_id); d->access_right_mask = 0; d->reserved = 0; U16_TO_BE16(0, d->next_search); @@ -1079,7 +1199,10 @@ int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode) return(mode ? -0x84 : -0x8a); if (mode) { XDPRINTF((5,0,"MKDIR dirname:%s:", unname)); - if (!mkdir(unname, 0777)) return(0); + if (!mkdir(unname, 0777)) { + chmod(unname, act_umode_dir); + return(0); + } completition = -0x84; /* No Create Priv.*/ /* -0x9f Direktory Aktive */ } else { /* rmdir */ int j = -1; @@ -1235,7 +1358,7 @@ void nw_exit_connect(void) } int nw_init_connect(void) -/* Cann be called when ever you want */ +/* May be called when ever you want */ { uint8 *login = (uint8*) "LOGIN/"; NW_PATH nwlogin; @@ -1252,8 +1375,10 @@ int nw_init_connect(void) nwlogin.volume = 0; while (k--) { - if (connect_is_init) xfree(d->path); - else d->path = NULL; + if (connect_is_init) + xfree(d->path); + else + d->path = NULL; d->volume = 0; d->inode = 0; d->is_temp = 0; @@ -1266,10 +1391,19 @@ int nw_init_connect(void) if (connect_is_init) { k = 0; while (k++ < anz_dirhandles) free_dir_handle(k); - } else connect_is_init++; + } else + connect_is_init++; while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { - if (what == 10) { /* GID */ + if (what == 8) { /* entry8_flags */ + entry8_flags = hextoi((char*)buff); + } else if (what == 9) { /* GID */ + int umode_dir, umode_file; + if (2 == sscanf((char*)buff, "%o %o", &umode_dir, &umode_file)) { + default_umode_dir = umode_dir; + default_umode_file = umode_file; + } + } else if (what == 10) { /* GID */ default_gid = atoi((char*)buff); } else if (what == 11) { /* UID */ default_uid = atoi((char*)buff); @@ -1308,7 +1442,8 @@ int nw_free_handles(int task) * are deleted. I hope this is right. !?? */ { - if (task == -1) return(nw_init_connect()); + if (task == -1) + return(nw_init_connect()); else { NW_DIR *d = &(dirs[0]); int k = used_dirs; @@ -1336,7 +1471,7 @@ int xinsert_new_dir(int volume, uint8 *path, int inode, int drive, int is_temp, int timedhandle = 0; #endif /* first look, whether drive is allready in use */ - for (j = 0; j < (int)used_dirs; j++) { + for (j = (used_dirs) ? 1 : 0; j < (int)used_dirs; j++) { NW_DIR *d = &(dirs[j]); if (!d->inode) freehandle = j+1; @@ -1367,7 +1502,7 @@ int insert_new_dir(NW_PATH *nwpath, int inode, int drive, int is_temp, int task) } -int nw_search(uint8 *info, +int nw_search(uint8 *info, uint32 *fileowner, int dirhandle, int searchsequence, int search_attrib, uint8 *data, int len) @@ -1389,6 +1524,7 @@ int nw_search(uint8 *info, get_file_attrib((NW_FILE_INFO*)info, &stbuff, &nwpath); } + if (fileowner) *fileowner = get_file_owner(&stbuff); return(searchsequence); } else return(-0xff); /* not found */ } else return(completition); /* wrong path */ @@ -1632,7 +1768,7 @@ static int s_nw_scan_dir_info(int dir_handle, U16_TO_BE16(aktsequenz, subnr); upstr(dirname); strncpy((char*)subname, (char*)dirname, 16); - U32_TO_BE32(1L, owner); /* erstmal */ + U32_TO_BE32(get_file_owner(&stbuff), owner); un_date_2_nw(stbuff.st_mtime, subdatetime, 1); un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1); return(0xff); @@ -1645,7 +1781,7 @@ static int s_nw_scan_dir_info(int dir_handle, if (!stat(dh->unixname, &stbuff)) { U16_TO_BE16(1, subnr); memset(subname, 0, 16); - U32_TO_BE32(1L, owner); + U32_TO_BE32(get_file_owner(&stbuff), owner); un_date_2_nw(stbuff.st_mtime, subdatetime, 1); un_time_2_nw(stbuff.st_mtime, subdatetime+2, 1); return(0xff); @@ -1703,7 +1839,8 @@ void get_dos_file_attrib(NW_DOS_FILE_INFO *f, f->attributes[0] = (uint8) un_nw_attrib(stb, 0, 0); un_date_2_nw(stb->st_mtime, f->created.date, 0); un_time_2_nw(stb->st_mtime, f->created.time, 0); - U32_TO_BE32(1, f->created.id); + + U32_TO_BE32(get_file_owner(stb), f->created.id); memcpy(&(f->updated), &(f->created), sizeof(NW_DOS_FILE_INFO)); un_date_2_nw(stb->st_atime, f->last_access_date, 0); U32_TO_32(stb->st_size, f->size); @@ -1722,7 +1859,7 @@ void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, f->attributes[0] = 0x10; /* Dir */ un_date_2_nw(stb->st_mtime, f->created.date,0); un_time_2_nw(stb->st_mtime, f->created.time,0); - U32_TO_BE32(1, f->created.id); + U32_TO_BE32(get_file_owner(stb), f->created.id); un_date_2_nw(stb->st_mtime, f->modify_date, 0); un_time_2_nw(stb->st_mtime, f->modify_time, 0); U32_TO_BE32(MAX_U32, f->max_space); diff --git a/connect.h b/connect.h index db3ed93..4e7639f 100644 --- a/connect.h +++ b/connect.h @@ -1,4 +1,4 @@ -/* connect.h 28-Jul-96 */ +/* connect.h 29-Sep-96 */ #ifndef _CONNECT_H_ #define _CONNECT_H_ typedef struct { @@ -129,7 +129,7 @@ extern int mv_dir(int dir_handle, uint8 *q, int qlen, extern int nw_mk_rd_dir(int dir_handle, uint8 *data, int len, int mode); -extern int nw_search(uint8 *info, +extern int nw_search(uint8 *info, uint32 *fileowner, int dirhandle, int searchsequence, int search_attrib, uint8 *data, int len); @@ -197,12 +197,25 @@ extern NW_DIR dirs[MAX_NW_DIRS]; extern int used_dirs; extern int act_uid; extern int act_gid; +extern int act_obj_id; /* not login == 0 */ +extern int act_umode_dir; +extern int act_umode_file; + +extern int entry8_flags; /* special login/logout/flags */ extern int conn_get_kpl_path(NW_PATH *nwpath, int dirhandle, uint8 *data, int len, int only_dir) ; +extern int conn_get_kpl_unxname(char *unixname, + int dirhandle, + uint8 *data, int len); -extern void set_default_guid(void); -extern void set_guid(int gid, int uid); +extern void set_default_guid(void); +extern void set_guid(int gid, int uid); +extern void reset_guid(void); +extern void set_act_obj_id(uint32 obj_id); +extern int in_act_groups(gid_t gid); +extern int get_real_access(struct stat *stb); +extern uint32 get_file_owner(struct stat *stb); extern int nw_scan_a_directory(uint8 *rdata, diff --git a/doc/CHANGES b/doc/CHANGES index 31b159d..78418eb 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,6 +1,6 @@ Sorry, this is in German only. User important notes are in the NEWS file. -Aenderungen in mars_nwe bis zum : 09-Sep-96 +Aenderungen in mars_nwe bis zum : 04-Oct-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -184,4 +184,39 @@ Erste 'oeffentliche' Version - einfache dbm export/import Routinen eingebaut. - Bug in dos_mangling routine beseitigt. <----- ^^^^^^^^^^ pl3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- nwserv.stations erweitert um 'station connect restrictions'. +- Datei Access um 'supplementary groups' erweitert. + Open File ruft gegebenfalls setegid() auf. +- Als File-Creator wird nun der aktuelle mars_nwer User zurueckgegeben, + falls st_uid == uid aktueller User. +- call 0x3d in 0x3b (commit file) umbenannt. +- segmentation violation in build_verz_name (connect.c) korrigiert. + Konnte auftreten wenn volume Schalter '-i' gesetzt war. (James MacLean) +- Eintrag 8 als Flag Eintrag verwendet. +- Standardmaessig kann im ausgelogtem Zustand jetzt nur noch auf + das Login Verzeichnis zugegriffen werden. +- Eintrag 9 als default umask_dir und umask_file Eintrag verwendet. +- Ueberpruefung/Anlegen des printqueue Verzeichnisses beim Start eingebaut. +- Es kann nun abhaengig von den Rechten des Queueverzeichnisses gedruckt + werden. +- SYS:MAIL/xx Verzeichnisse werden nun beim Start generell 0733 angelegt + bzw. bestehende werden auf 0733 abgeaendert. +- Unix Verzeichnis fuer SYS Volume wird nun beim ersten Start + automatisch angelegt. +- BUG in nwdbm.c, der in pl2 hineingeruscht war, beseitigt. + Wichtige User Properties wurden beim Start nicht in die + Bindery eingetragen -> capture access error usw. + Louis Zammit Mangion hatte diesen Fehler gefunden. +- 0x16,0x26 liefert nun immer aktuellen User als Trustee-Owner zurueck. + Sollte spaeter noch verbessert werden. +- delete BinderyObject loescht nun auch die Referenzen in SET Properties auf + dieses Object. +- dummy fuer 0x56,ufunc=4 eingebaut. +- dirhandle 1 wird nach Freigabe nicht wieder verwendet. + Dadurch wurde Problem beseitigt, dass z.B. FILER.EXE nach + dem Start als Current Directory nicht das aktuelle besitzt. + Eine Packet-Analyse eines realen Novell Servers zeigte gleiche + Sonderbehandlung von handle 1. +- Login Restrictions. (station restrictions) eingebaut. +<----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/CREDITS b/doc/CREDITS index 9dae0b2..045a724 100644 --- a/doc/CREDITS +++ b/doc/CREDITS @@ -28,6 +28,9 @@ Volker Lendecke James B. MacLean many testings+notes +Louis Zammit Mangion + testings+bugfixes + Jiri A. Randus testing bindery code diff --git a/doc/INSTALL b/doc/INSTALL index 780441c..bfd369e 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -107,8 +107,9 @@ the mars_nwe-package. At least the volume "SYS" must be defined in the configuration-file "nwserv.conf". Create the associated directory if it does not already exists and place the programs "login.exe" and "slist.exe" - into the "LOGIN" directory. You also can use the free mars_dosutils - with a poor version of these programms. + into the "LOGIN" or "login" directory. + You also can use the free mars_dosutils with a poor version of + these programms. (7) Fire it up diff --git a/doc/NEWS b/doc/NEWS index 5dd7c3c..4077389 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,11 @@ # in this files are some notes for user of mars_nwe. +------04-Oct-96--- 0.98.pl4 ---------- +- new sections 8 + 9 in nw.ini (nwserv.conf). + Section 8: special login/logout/security flags. + Section 9: Standard creat mode for creating directories and files. +- file access now works with supplementary groups. +- simple station connect restrictions with nwserv.stations. +- and real bindery station login restrictions. (SYSCON) ------24-Aug-96--- 0.98.pl2 ---------- - 'PIPE' filesystem scheme changed. Now the first read or write calls the 'pipe program' and not the open or creat call. diff --git a/doc/README b/doc/README index a797124..c21ae1f 100644 --- a/doc/README +++ b/doc/README @@ -16,7 +16,7 @@ to write a small TLI->SOCKET emulation (see the modul Unfortunately I had no complete description of the NCP-calls, so that the handling of many calls is based on experiments. :-( -WARNING: this code still has many BUG's! +WARNING: this code still has BUG's! BINDERY: These are the *.pag and *.dir files. @@ -42,7 +42,7 @@ Short description of the programs from this package: nwserv: the main program. Initiates all subsystems and - starts 'ncpserv'. + starts 'ncpserv' and 'nwbind'. Sends broadcasts, wdogs, sap and rip packets. If nwserv is started with the parameter 'y', then the simple test client 'nwclient', only for debugging, is started. diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index 065a46c..354db6a 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.98.pl3 -Entered-date: 10-Sep-96 +Version: 0.98.pl4 +Entered-date: 04-Oct-96 Description: Full netware-emulator (src), beta. Supports file-services, bindery-services, printing-services, routing-services. @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@stover.f.eunet.de (Martin Stover) Maintained-by: mstover@stover.f.eunet.de (Martin Stover) Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs - 200kB mars_nwe-0.98.pl3.tgz + 200kB mars_nwe-0.98.pl4.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Platforms: Linux (1.2.xx, 1.3.xx, 2.xx), UnixWare (2.xx) Copying-policy: GNU diff --git a/examples/nw.ini b/examples/nw.ini index 06221d6..c6338e1 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -2,7 +2,7 @@ # This is the configuration-file for "mars_nwe", a free netware-emulator # for Linux. # -# last change: 17-Jul-96 +# last change: 04-Oct-96 # This file specifies which Linux-resources (printers, users, directories) # should be accessible to the DOS-clients via "mars_nwe". Furthermore @@ -46,7 +46,11 @@ # # Please note that at least the volume "SYS" must be defined and it must # contain the following sub-directories: LOGIN, PUBLIC, SYSTEM, MAIL. -# See the installation-instructions in the doc-directory for more infos. +# See the installation-instructions in the doc-directory for more infos +# and the info to section 16 (tests on startup) in this file. +# +# !! NOTE !! +# First defined volume should always named 'SYS'. # # # ------------------------------------------------------------------------- @@ -62,13 +66,16 @@ # # 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) +# 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) -# o volume has only one filesystem/device/namespace +# o (lowercase o) +# volume has only one filesystem/device/namespace # this is for filesystems with high inode > 0xFFFFFFF. # because for namespace services mars_nwe normally use the # first 4 bit of 32 bit inode for distinguish @@ -221,8 +228,8 @@ # ========================================================================= # Section 5: Saving of ipx-routes (required) # -# This entry controls if the information regarding the ipx-routes should be -# saved beyond the lifetime of the server. +# This entry controls if the information regarding the ipx-routes and +# devices should be saved beyond the lifetime of the server. # # ------------------------------------------------------------------------- # Syntax: @@ -276,9 +283,9 @@ # # ------------------------------------------------------------------------- # Syntax: -# 7 FLAG +# 7 Value # -# FLAG: +# Value: # 0 enforce encryption of _all_ passwords by the DOS-client # (default) # 1 as "0", but allow the non-encrypted version of the @@ -286,7 +293,7 @@ # 7 allow all non-encrypted stuff but no empty nwe passwords. # 8 allow all non-encrypted stuff and also allow empty # nwe-passwords. -# 9 use all non-encryted calls + "get crypt key" will allways fail +# 9 use all non-encryted calls + "get crypt key" will always fail # so the login program will use the old unencryted calls. # this will *not* work with all clients !! (OS2/client) # ------------------------------------------------------------------------- @@ -294,8 +301,26 @@ 7 0 -# Section 8: currently not used -# Section 9: currently not used +# Section 8: special login/logout/security flags. +# ========================================================================= +# Flags +# 0x1 allow changing dir/accessing other files than login/* +# when not logged in, if the client supports it. +# ( this was standard till mars_nwe-0.98.pl4 ) +# +# other flags may follow. +# value will be interpreted as hex value. + +8 0x0 + +# Section 9: Standard creat mode for creating directories and files. +# ========================================================================= +# +# mkdir mode (creat mode directories), creat mode files +# values are always interpreted as octal values ! +# 9 0755 0664 +# +9 0755 0664 # Section 10: UID and GID with minimal rights # ========================================================================= @@ -365,7 +390,7 @@ # will be encrypted and permanent stored in the # bindery-files, so it (the password or the whole section, at # your option) can be deleted after the first start of - "nwserv". +# "nwserv". # # Make sure this file is not world-readable as long # as the password stands here. @@ -453,9 +478,11 @@ # Section 16: Tests on startup # # If you want some sanity checks at startup, set this flag to 1. -# "mars_nwe" will try to create missing directories (with the "right" -# permissions, of course) if you enable this. -# +# "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. 16 1 @@ -476,9 +503,14 @@ # # QUEUE_NAME: the name of the print queue on client-side (to make it # perfectly clear: _not_ the Linux-queue) -# QUEUE_DIR: spooling directory for the print-jobs; this directory must -# exist before printing (_not_ the spooling-directories of -# the Linux-lpd) +# QUEUE_DIR: spooling directory for the print-jobs. +# The name is the DOS (not Unix) name of this +# directory. +# It should be placed on the first defined volume. +# (standard name is SYS volume). +# Then it will be created at starttime of mars_nwe. +# It must exist before printing. +# (_not_ the spooling-directories of the Linux-lpd) # PRINT_COMMAND: command used for serving the print-jobs under Linux # (see "man lpr" and "man magicfilter" for details) # @@ -536,7 +568,7 @@ # Section 310: watchdogs 310 7 # send wdog's only to device net < x ticks. - # 0 = allways send wdogs. < 0 = never send wdogs + # 0 = always send wdogs. < 0 = never send wdogs # Section 400: # station file for special handling of stations. @@ -551,3 +583,10 @@ # 1 = 400 are excludes, get nearest response normally enabled. # 2 = 400 are includes, get nearest response normally disabled. +# Section 402: station connect restrictions +# +# for special handling of the 'creat connection' call. +402 0 # 0 = ignore entry 400, creat connection ever enabled. + # 1 = 400 are excludes, creat connection normally enabled. + # 2 = 400 are includes, creat connection normally disabled. + diff --git a/examples/nwserv.stations b/examples/nwserv.stations index 3c4e00a..6ba0d60 100644 --- a/examples/nwserv.stations +++ b/examples/nwserv.stations @@ -10,5 +10,6 @@ #1 0.0.0.21:* # one special net # entry 1: is for get nearest server request handling. # look also into the examples/nw.ini file. +# entry 2: is for station connect restrictions. diff --git a/makefile.unx b/makefile.unx index 356866a..d2d462d 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 30-Aug-96 +#makefile.unx 11-Sep-96 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=98 -P_L=3 +P_L=4 #define D_P_L 1 DISTRIB=mars_nwe diff --git a/namspace.c b/namspace.c index 6b5ef81..2d4716b 100644 --- a/namspace.c +++ b/namspace.c @@ -336,6 +336,21 @@ static int add_hpath_to_nwpath(N_NW_PATH *nwpath, } /* while */ if (nwpath->volume < 0) result=-0x9c; leave_build_nwpath: + if ((!result) && (!act_obj_id) && !(entry8_flags & 1)) { + if (nwpath->volume) + result = -0x9c; /* wrong path, only volume 0 is OK */ + else { + char *p=nwpath->path; + char pp[10]; + while (*p=='/') ++p; + strmaxcpy(pp, p, 6); + upstr(pp); + p=pp+5; + if (memcmp(pp, "LOGIN", 5) || (*p!='\0' && *p!='/') ) + result=-0x9c; + } + } + if (!result) { NW_VOL *v = &nw_volumes[nwpath->volume]; if (nwpath->namespace == NAME_DOS || nwpath->namespace == NAME_OS2) { @@ -469,10 +484,14 @@ static int insert_get_base_entry(N_NW_PATH *nwpath, if (creatmode & FILE_ATTR_DIR) { /* creat dir */ - if (mkdir(unname, 0777)) result=-0x84; + if (mkdir(unname, 0777)) + result=-0x84; + else + chmod(unname, act_umode_dir); } else { /* creat file */ if ((result = creat(unname, 0777)) > -1) { + chmod(unname, act_umode_file); close(result); result = 0; } else result=-0x84; @@ -605,11 +624,13 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) N_NW_PATH *nwpath=&(dbe->nwpath); struct stat *stb=&(nwpath->statb); int result = 76; + uint32 owner = get_file_owner(stb); memset(p, 0, result); + if (infomask & INFO_MSK_DATA_STREAM_SPACE) { U32_TO_32(stb->st_size, p); } - p += 4; + p += 4; if (infomask & INFO_MSK_ATTRIBUTE_INFO) { uint32 mask=0L; @@ -637,7 +658,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p +=2; un_date_2_nw(stb->st_mtime, p, 0); p +=2; - U32_TO_32(1, p); + U32_TO_32(owner, p); p +=4; } else p+=8; @@ -646,7 +667,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, uint32 infomask, uint8 *p) p +=2; un_date_2_nw(stb->st_mtime, p, 0); p +=2; - U32_TO_32(1, p); + U32_TO_32(owner, p); p +=4; un_date_2_nw(stb->st_atime, p, 0); /* access date */ p +=2; @@ -1531,6 +1552,13 @@ int handle_func_0x56(uint8 *p, uint8 *responsedata, int task) case 0x04 : /* enumerate extended attributes */ { + struct OUTPUT { + uint8 dontknow1[16]; /* all zero */ + uint8 ea_handle[4]; /* ???? */ + uint8 dontknow3[4]; /* all zero */ + } *xdata= (struct OUTPUT*)responsedata; + memset(xdata, 0, sizeof(struct OUTPUT)); + result = sizeof(struct OUTPUT); } break; diff --git a/ncpserv.c b/ncpserv.c index aa6f13a..8bc641b 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -31,11 +31,13 @@ static char my_nwname[50]; static time_t akttime; static int server_goes_down=0; static int ipx_out_fd=-1; - +#if 0 static int tells_server_version=0; +#endif static int sock_nwbind=-1; static int sock_echo =-1; +static int station_restrictions=0; static int get_ini(void) { @@ -44,8 +46,15 @@ static int get_ini(void) uint8 buff[256]; int what; while (0 != (what =get_ini_entry(f, 0, buff, sizeof(buff)))) { +#if 0 if (6 == what) { /* Server Version */ tells_server_version = atoi((char*)buff); + } else +#endif + if (400 == what) { /* station file */ + new_str(station_fn, buff); + } else if (402 == what) { /* station connect restrictions */ + station_restrictions=atoi((char*)buff); } } /* while */ fclose(f); @@ -608,8 +617,20 @@ static void handle_ncp_request(void) #endif } else if (type == 0x1111) { /* GIVE CONNECTION Nr connection */ - int connection = (server_goes_down) ? 0 - : find_get_conn_nr(&from_addr); + int connection = 0; + + if (!server_goes_down) { + if (!station_restrictions) + connection=find_get_conn_nr(&from_addr); + else { + int do_sent = (station_restrictions == 1) ? 1 : 0; + if (find_station_match(2, &from_addr)) + do_sent = !do_sent; + if (do_sent) + connection=find_get_conn_nr(&from_addr); + } + } + XDPRINTF((2, 0, "GIVE CONNECTION NR=%d", connection)); if (connection) { CONNECTION *c = &(connections[connection-1]); diff --git a/nwbind.c b/nwbind.c index 2abebc8..5464f3f 100644 --- a/nwbind.c +++ b/nwbind.c @@ -1,5 +1,5 @@ /* nwbind.c */ -#define REVISION_DATE "29-Aug-96" +#define REVISION_DATE "04-Oct-96" /* NCP Bindery SUB-SERVER */ /* authentification and some message handling */ @@ -225,6 +225,25 @@ static void get_login_time(uint8 login_time[], CONNECTION *cx) login_time[6] = s_tm->tm_wday; } +static int build_login_response(uint8 *responsedata, uint32 obj_id) +{ + uint8 pw_name[40]; + int result; + act_c->object_id = obj_id; /* actuell Object ID */ + act_c->t_login = akttime; /* and login Time */ + 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)); + write_utmp(1, act_connection, act_c->pid_nwconn, + &(act_c->client_adr), pw_name); + return(result); +} + static void handle_fxx(int gelen, int func) { IPX_DATA ipxoutdata; @@ -396,15 +415,18 @@ static void handle_fxx(int gelen, int func) U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections); U16_TO_BE16(h, xdata->peak_connection); U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes); -#ifdef _MAR_TESTS_1 xdata->security_level=1; + /* + * if this level is 0 + * you cannot install access restrictions. + */ + +#ifdef _MAR_TESTS_1 xdata->sft_level=2; xdata->tts_level=1; - xdata->accounting_version=1; xdata->vap_version=1; xdata->queuing_version=1; - xdata->virtual_console_version=1; xdata->security_level=1; xdata->internet_bridge_version=1; @@ -467,15 +489,14 @@ static void handle_fxx(int gelen, int func) } } if (!result) { - uint8 pw_name[40]; - act_c->object_id = obj.id; /* actuell Object ID */ - act_c->t_login = akttime; /* u. login Time */ - get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), obj.id, pw_name); - result = get_home_dir(responsedata + 2*sizeof(int)+1, obj.id); - *(responsedata+ 2 * sizeof(int)) = (uint8) result; - data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); - write_utmp(1, act_connection, act_c->pid_nwconn, &(act_c->client_adr), pw_name); - } else completition = (uint8) -result; + internal_act = 1; + result = nw_test_adr_access(obj.id, &(act_c->client_adr)); + internal_act = 0; + } + if (!result) + data_len = build_login_response(responsedata, obj.id); + else + completition = (uint8) -result; } break; case 0x15 : { /* Get Object Connection List */ @@ -558,35 +579,28 @@ static void handle_fxx(int gelen, int func) xstrmaxcpy(obj.name, (char*)(p+3), *(p+2)); upstr(obj.name); XDPRINTF((2, 0, "LOGIN CRYPTED PW NAME='%s'",obj.name)); + if (0 == (result = find_obj_id(&obj, 0))) { internal_act = 1; result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); internal_act = 0; } + if (result > -1) { - uint8 pw_name[40]; - act_c->object_id = obj.id; /* actuell Object */ - act_c->t_login = akttime; /* and login time */ - get_guid((int*)responsedata, (int*)(responsedata+sizeof(int)), obj.id, pw_name); - result = get_home_dir(responsedata + 2*sizeof(int)+1, obj.id); - *(responsedata+ 2 * sizeof(int)) = (uint8) result; - data_len = 2 * sizeof(int) + 1 + (int) *(responsedata+2* sizeof(int)); - write_utmp(1, act_connection, act_c->pid_nwconn, - &(act_c->client_adr), pw_name); - } else { -#if 0 - /* this is not ok */ - if ((password_scheme & PW_SCHEME_LOGIN) && - result == -0xff && obj.id != 1) /* not supervisor */ - completition = 0xfb; /* We lie here, to force LOGIN */ - else /* to use the old call */ -#endif - completition = (uint8) -result; + internal_act = 1; + result = nw_test_adr_access(obj.id, &(act_c->client_adr)); + internal_act = 0; } - /* completition = 0xde means login time has expired */ - /* completition = 0xdf means good login, but */ - /* login time has expired */ - /* perhaps I will integrate it later */ + if (result > -1) + data_len = build_login_response(responsedata, obj.id); + else + completition = (uint8) -result; + /* + * completition = 0xde means login time has expired + * completition = 0xdf means good login, but + * login time has expired + * perhaps I will integrate it later. + */ } break; @@ -983,7 +997,15 @@ static void handle_fxx(int gelen, int func) case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */ /* TODO !!! */ - completition = (uint8)0xff; + 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; @@ -1288,7 +1310,7 @@ static void handle_bind_calls(uint8 *p) p += (*p+1); nw_new_obj_prop(0, obj.name, obj.type, O_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_DYNA|P_FL_ITEM, 0x40, - (char *)p, sizeof(ipxAddr_t)); + (char *)p, sizeof(ipxAddr_t), 1); } break; diff --git a/nwclient.c b/nwclient.c index bf14f65..6abfb28 100644 --- a/nwclient.c +++ b/nwclient.c @@ -314,7 +314,7 @@ static int file_search_cont(DIR_IDS *di, int seq, } return(-1); } - +#if 0 static int scan_dir_info(int dirhandle, char *path, int sub_dir) { uint8 *p=requestdata; @@ -356,6 +356,8 @@ static int allocate_dir_handle(int dirhandle, if (!handle_event()) return((int) *responsedata); return(-1); } +#endif + #if 0 static void scan_irgendwas(int dirhandle, int attrib, char *name) { @@ -630,6 +632,7 @@ static void test1(void) } #endif +#if 0 static void test1(void) { int dirhandle = allocate_dir_handle(0, 'd', "SYS:", 1); @@ -643,6 +646,7 @@ static void test1(void) } } +#endif static void test2(void) { diff --git a/nwconn.c b/nwconn.c index 00ea5c5..ca08453 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 13-Jul-96 */ +/* nwconn.c 03-Oct-96 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -565,21 +565,25 @@ static int handle_ncp_serv(void) if (!sequenz) { memset(xdata, 0, sizeof(struct XDATA)); xdata->entries=1; +#if 0 U32_TO_BE32(1, xdata->ids); /* SUPERVISOR */ +#else + U32_TO_BE32(act_obj_id, xdata->ids); /* actual LOGIN User */ + /* NOTE: this should be made better */ +#endif xdata->trustees[1] = 0x1; /* Supervisory */ xdata->trustees[0] = 0xff; /* all low */ data_len = sizeof(struct XDATA); } else completition = 0x9c; /* no more trustees */ } else completition = (uint8) (-result); - } else if (*p == 0x27) { /* Add Trustees to DIR ?? */ + } else if (*p == 0x27) { /* Add Ext Trustees to DIR */ #if 0 struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0x0, dlen, ufunc */ - uint8 dir_handle; /* Verzeichnis Handle */ - uint8 trustee_id[4]; /* Trustee Object ID */ - uint8 trustee_right_mask; - uint8 weis_nicht; /* ??? z.B. 0x0 */ + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0x0, dlen, ufunc */ + uint8 dir_handle; /* Handle */ + uint8 trustee_id[4]; /* Trustee Object ID */ + uint8 trustee_rights[2]; /* low - high */ uint8 pathlen; uint8 path; } *input = (struct INPUT *) (ncprequest); @@ -755,8 +759,11 @@ static int handle_ncp_serv(void) int len = input->len; int searchsequence; NW_FILE_INFO f; + uint32 owner; + memset(xdata, 0, sizeof(struct XDATA)); searchsequence = nw_search( (uint8*) &f, + &owner, (int)input->dir_handle, (int) GET_BE16(input->sequence), (int) input->search_attrib, @@ -764,7 +771,7 @@ static int handle_ncp_serv(void) if (searchsequence > -1) { memcpy(xdata->f, &f, sizeof(NW_FILE_INFO)); U16_TO_BE16((uint16) searchsequence, xdata->sequence); - U32_TO_BE32(1L, xdata->owner_id); /* Supervisor */ + U32_TO_BE32(owner, xdata->owner_id); data_len = sizeof(struct XDATA); } else completition = (uint8) (- searchsequence); } @@ -832,7 +839,8 @@ static int handle_ncp_serv(void) nw_free_handles(-1); set_default_guid(); nw_setup_home_vol(-1, NULL); - return(-1); /* nwbind must do rest */ + set_act_obj_id(0); /* NOT logged in */ + return(-1); /* nwbind must do a little rest */ break; case 0x1a : /* lock file */ @@ -876,8 +884,12 @@ static int handle_ncp_serv(void) if (!ufunc) completition=0; /* TTS not availible */ else completition=0xfb; /* request not known */ } break; - +#if 0 + this was wrong, I think case 0x3d : { /* commit file, flush file buffers */ + 0x3d seems to be no valid/used NCP call. +#endif + case 0x3b : { /* commit file, flush file buffers */ struct INPUT { uint8 header[7]; /* Requestheader */ uint8 reserve; @@ -885,9 +897,7 @@ static int handle_ncp_serv(void) uint8 fhandle[4]; /* filehandle */ } *input = (struct INPUT *)ncprequest; uint32 fhandle = GET_BE32(input->fhandle); - XDPRINTF((2,0, "TODO: COMMIT FILE:fhandle=%ld", fhandle)); - /* TODO */ - ; + XDPRINTF((5,0, "should be done some time: COMMIT FILE:fhandle=%ld", fhandle)); } break; @@ -980,8 +990,10 @@ static int handle_ncp_serv(void) int len = input->len; uint8 my_sequenz[2]; int searchsequence; + uint32 owner; memcpy(my_sequenz, input->sequenz, 2); searchsequence = nw_search( (uint8*) &(xdata->u), + &owner, (int)input->dir_handle, (int) GET_BE16(my_sequenz), (int) input->search_attrib, @@ -1427,10 +1439,11 @@ static void handle_after_bind() switch (ufunc) { case 0x14: /* Login Objekt, unencrypted passwords */ case 0x18: { /* crypt_keyed LOGIN */ - int fnlen = (int) *(bindresponse + 2 * sizeof(int)); + int fnlen = (int) *(bindresponse + 3 * sizeof(int)); /* ncpserv have changed the structure */ set_guid(*((int*)bindresponse), *((int*)(bindresponse+sizeof(int)))); - nw_setup_home_vol(fnlen, bindresponse + 2 * sizeof(int) +1); + set_act_obj_id(*((uint32*)(bindresponse + 2 * sizeof(int)))); + nw_setup_home_vol(fnlen, bindresponse + 3 * sizeof(int) +1); } break; diff --git a/nwdbm.c b/nwdbm.c index f9b5706..bcffc0c 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 07-Sep-96 data base for mars_nwe */ +/* nwdbm.c 04-Oct-96 data base for mars_nwe */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -112,34 +112,11 @@ void sync_dbm() #define store(key, content) dbm_store(my_dbm, key, content, DBM_REPLACE) -static int name_match(uint8 *s, uint8 *p) -{ - uint8 pc; - while ( (pc = *p++) != 0){ - switch (pc) { - - case '?' : if (!*s++) return(0); /* simple char */ - break; - - case '*' : if (!*p) return(1); /* last star */ - while (*s) { - if (name_match(s, p) == 1) return(1); - ++s; - } - return(0); - - default : if (pc != *s++) return(0); /* normal char */ - break; - } /* switch */ - } /* while */ - return ( (*s) ? 0 : 1); -} - int find_obj_id(NETOBJ *o, uint32 last_obj_id) { int result = -0xfc; /* no Object */ - XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x, lastid=0x%lx", - o->name, (int)o->type, last_obj_id)); + XDPRINTF((2, 0,"findobj_id OBJ=%s, type=0x%x, lastid=0x%x", + o->name, (int)o->type, (int)last_obj_id)); if (!dbminit(FNOBJ)){ @@ -158,12 +135,12 @@ int find_obj_id(NETOBJ *o, uint32 last_obj_id) NETOBJ *obj = (NETOBJ*)data.dptr; if ( ( ((int)obj->type == (int)o->type) || o->type == MAX_U16) && name_match(obj->name, o->name)) { - XDPRINTF((2, 0, "found OBJ=%s, id=0x%lx", obj->name, obj->id)); + XDPRINTF((2, 0, "found OBJ=%s, id=0x%x", obj->name, (int)obj->id)); result = 0; memcpy((char *)o, (char*)obj, sizeof(NETOBJ)); } else { - XDPRINTF((3,0,"not found,but NAME=%s, type=0x%x, id=0x%lx", - obj->name, (int)obj->type, obj->id)); + XDPRINTF((3,0,"not found,but NAME=%s, type=0x%x, id=0x%x", + obj->name, (int)obj->type, (int)obj->id)); } } if (result) key = nextkey(key); @@ -185,7 +162,7 @@ static int loc_delete_property(uint32 obj_id, int result = -0xfb; /* no property */ memset(xset, 0, sizeof(xset)); if (!prop_id) { - XDPRINTF((2,0, "loc_delete_property obj_id=%d, prop=%s", obj_id, prop_name)); + XDPRINTF((2,0, "loc_delete_property obj_id=0x%x, prop=%s", obj_id, prop_name)); if (!dbminit(FNPROP)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { NETPROP *p=(NETPROP*)key.dptr; @@ -204,7 +181,7 @@ static int loc_delete_property(uint32 obj_id, } else result = -0xff; dbmclose(); } else { - XDPRINTF((2,0, "loc_delete_property obj_id=%d, prop_id=%d", obj_id, (int)prop_id)); + XDPRINTF((2,0, "loc_delete_property obj_id=0x%x, prop_id=%d", obj_id, (int)prop_id)); xset[prop_id]++; result = prop_id; } @@ -251,17 +228,83 @@ static int loc_delete_property(uint32 obj_id, return(result); } +static int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) +{ + int result = 0; /* we lie insteed of -0xea; no such member */ + NETVAL val; + if (!dbminit(FNVAL)){ + key.dsize = NETVAL_KEY_SIZE; + key.dptr = (char*)&val; + val.obj_id = obj_id; + val.prop_id = (uint8)prop_id; + val.segment = (uint8)0; + data = fetch(key); + while (1) { + val.segment++; + data = fetch(key); + if (data.dptr != NULL) { + NETVAL *v = (NETVAL*)data.dptr; + uint8 *p = v->value; + int k = 0; + while (k++ < 32){ + if (GET_BE32(p) == member_id) { + memset(p, 0, 4); + memcpy(&val, v, sizeof(NETVAL)); + data.dptr = (char*)&val; + if (store(key, data)) result=-0xff; + else result=0; + goto L1; + } else p += 4; + } + } else break; + } + } else result = -0xff; +L1: + dbmclose(); + return(result); +} + +#define LOC_MAX_OBJS 10000 /* should be big enough ;) */ + static int loc_delete_obj(uint32 objid, int security) +/* delete's obj completely from bindery */ { int result = b_acc(objid, 0x33, 0x03); /* only supervisor or intern */ - if (result) return(result); /* no object delete priv */ + if (result) + return(result); /* no object delete priv */ + + /* now we delete all properties of this object */ (void)loc_delete_property(objid, (uint8*)"*", 0, 1); - if (!dbminit(FNOBJ)){ - key.dptr = (char*)&objid; - key.dsize = NETOBJ_KEY_SIZE; - if (delete(key)) result = -0xff; - } else result = -0xff; + + /* and now we delete all references of object in other set properties */ + if (!dbminit(FNPROP)){ + int anz=0; + uint32 objs[LOC_MAX_OBJS]; + uint8 props[LOC_MAX_OBJS]; + for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { + data = fetch(key); + if (data.dptr) { + NETPROP *prop=(NETPROP*)data.dptr; + if (prop->flags & P_FL_SET) { /* is set property */ + objs[anz] = prop->obj_id; + props[anz++] = prop->id; + if (anz == LOC_MAX_OBJS) break; + } + } + } + while (anz--) /* now try to delete obj members */ + prop_delete_member(objs[anz], props[anz], objid); + } else + result=-0xff; dbmclose(); + if (!result) { + if (!dbminit(FNOBJ)){ + key.dptr = (char*)&objid; + key.dsize = NETOBJ_KEY_SIZE; + if (delete(key)) result = -0xff; + } else result = -0xff; + dbmclose(); + } return(result); } @@ -324,8 +367,7 @@ int nw_change_obj_security(NETOBJ *o, int newsecurity) int nw_get_obj(NETOBJ *o) { - int result = -0xfc; /* no Object */ - XDPRINTF((2,0, "nw_get_obj von OBJ id = 0x%x", (int)o->id)); + int result = -0xfc; /* no Object */ if (!dbminit(FNOBJ)){ key.dsize = NETOBJ_KEY_SIZE; key.dptr = (char*)o; @@ -338,13 +380,15 @@ int nw_get_obj(NETOBJ *o) } } else result = -0xff; dbmclose(); + XDPRINTF((2,0, "nw_get_obj von OBJ id = 0x%x, result=0x%x", + (int)o->id, result)); return(result); } static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id) { int result = -0xfb; /* no Property */ - XDPRINTF((2,0, "find Prop id von name=0x%x:%s, lastid=%d", + XDPRINTF((2,0, "find Prop id of name=0x%x:%s, lastid=%d", obj_id, p->name, last_prop_id)); if (!dbminit(FNPROP)){ int flag = (last_prop_id) ? 0 : 1; @@ -376,7 +420,7 @@ static int find_prop_id(NETPROP *p, uint32 obj_id, int last_prop_id) static int loc_change_prop_security(NETPROP *p, uint32 obj_id) { int result = -0xfb; /* no Property */ - XDPRINTF((2,0, "loc_change_prop_security Prop id von name=0x%x:%s", obj_id, p->name)); + XDPRINTF((2,0, "loc_change_prop_security prop id of name=0x%x:%s", obj_id, p->name)); if (!dbminit(FNPROP)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { NETPROP *prop=(NETPROP*)key.dptr; @@ -506,41 +550,6 @@ L1: return(result); } -static int prop_delete_member(uint32 obj_id, int prop_id, uint32 member_id) -{ - int result = 0; /* we lie */ /* -0xea; /* no such member */ - NETVAL val; - if (!dbminit(FNVAL)){ - key.dsize = NETVAL_KEY_SIZE; - key.dptr = (char*)&val; - val.obj_id = obj_id; - val.prop_id = (uint8)prop_id; - val.segment = (uint8)0; - data = fetch(key); - while (1) { - val.segment++; - data = fetch(key); - if (data.dptr != NULL) { - NETVAL *v = (NETVAL*)data.dptr; - uint8 *p = v->value; - int k = 0; - while (k++ < 32){ - if (GET_BE32(p) == member_id) { - memset(p, 0, 4); - memcpy(&val, v, sizeof(NETVAL)); - data.dptr = (char*)&val; - if (store(key, data)) result=-0xff; - else result=0; - goto L1; - } else p += 4; - } - } else break; - } - } else result = -0xff; -L1: - dbmclose(); - return(result); -} static int ins_prop_val(uint32 obj_id, NETPROP *prop, int segment, uint8 *property_value, int erase_segments) @@ -588,7 +597,7 @@ int nw_get_prop_val_by_obj_id(uint32 obj_id, NETPROP prop; int result=-0xff; strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen); - XDPRINTF((2,0, "nw_get_prop_val_by_obj_id,id=0x%x, prop=%s, segment=%d", + XDPRINTF((5,0, "nw_get_prop_val_by_obj_id,id=0x%x, prop=%s, segment=%d", obj_id, prop.name, segment_nr)); if ((result=find_first_prop_id(&prop, obj_id))==0){ @@ -780,8 +789,8 @@ int nw_scan_property(NETPROP *prop, int result; strmaxcpy((char*)obj.name, (char*)object_name, object_namlen); strmaxcpy((char*)prop->name, (char*)prop_name, prop_namlen); - XDPRINTF((2,0, "nw_scan_property obj=%s, prop=%s, type=0x%x, last_scan=0x%lx", - obj.name, prop->name, object_type, *last_scan)); + XDPRINTF((2,0, "nw_scan_property obj=%s, prop=%s, type=0x%x, last_scan=0x%x", + obj.name, prop->name, object_type, (int)*last_scan)); obj.type = (uint16) object_type; if ((result = find_obj_id(&obj, 0)) == 0){ @@ -811,9 +820,9 @@ int nw_get_prop_val_str(uint32 q_id, char *propname, uint8 *buff) if (result > -1) { result=strlen(buff); - XDPRINTF((2,0, "nw_get_prop_val_str:%s strlen=%d", propname, result)); + XDPRINTF((5,0, "nw_get_prop_val_str:%s strlen=%d", propname, result)); } else - XDPRINTF((2,0, "nw_get_prop_val_str:%s, result=0x%x", propname, result)); + XDPRINTF((5,0, "nw_get_prop_val_str:%s, result=-0x%x", propname, -result)); return(result); } @@ -875,23 +884,21 @@ int nw_obj_has_prop(NETOBJ *obj) return(result); } -static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) +static int nw_create_obj_prop(uint32 obj_id, NETPROP *prop) { - int result = b_acc(obj->id, obj->security, 0x12); - XDPRINTF((3, 0, "create property='%s' objid=0x%x", prop->name, obj->id)); - if (result) return(result); + int result=0; if (!dbminit(FNPROP)){ uint8 founds[256]; memset((char*)founds, 0, sizeof(founds) ); for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { NETPROP *p=(NETPROP*)key.dptr; - if (p->obj_id == obj->id) { + if (p->obj_id == obj_id) { data = fetch(key); p = (NETPROP*)data.dptr; if (data.dptr != NULL && !strcmp(prop->name, p->name)){ prop->id = p->id; - prop->obj_id = obj->id; - result = -0xed; /* Property exists */ + prop->obj_id = obj_id; + result = -0xed; /* Property exists */ break; } else founds[p->id]++; } @@ -905,12 +912,14 @@ static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) key.dptr = (char *)prop; data.dsize = sizeof(NETPROP); data.dptr = (char *)prop; - prop->obj_id = obj->id; + prop->obj_id = obj_id; prop->id = (uint8)k; if (store(key, data)) result = -0xff; } } else result = -0xff; dbmclose(); + XDPRINTF((3, 0, "create property='%s' objid=0x%x, result=0x%x", + prop->name, obj_id, result)); return(result); } @@ -925,14 +934,15 @@ int nw_create_prop(int object_type, int result=-0xff; strmaxcpy((char*)obj.name, (char*)object_name, object_namlen); strmaxcpy((char*)prop.name, (char*)prop_name, prop_namlen); - XDPRINTF((2,0, "nw_create_prop obj=%s, prop=%s, type=0x%x", - obj.name, prop.name, object_type)); obj.type = (uint16) object_type; - if ((result = find_obj_id(&obj, 0)) == 0){ + if ( 0 == (result = find_obj_id(&obj, 0)) + && 0 == (result = b_acc(obj.id, obj.security, 0x12)) ) { prop.flags = (uint8)prop_flags; prop.security = (uint8)prop_security; - result = nw_create_obj_prop(&obj, &prop); + result = nw_create_obj_prop(obj.id, &prop); } + XDPRINTF((2,0, "nw_create_prop obj=%s, prop=%s, type=0x%x, result=0x%x", + obj.name, prop.name, object_type, result)); return(result); } @@ -955,7 +965,7 @@ static int nw_new_obj(uint32 *wanted_id, 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) + char *value, int valuesize, int ever) /* * creats new property value, if needed creats Object * and the property, @@ -971,12 +981,13 @@ uint32 nw_new_obj_prop(uint32 wanted_id, objflags, objsecurity); obj.id = wanted_id; obj.security = objsecurity; - if (propname && *propname) { + if (propname && *propname && !b_acc(obj.id, obj.security, 0x12)) { + int result; strmaxcpy(prop.name, propname, sizeof(prop.name)); prop.flags = (uint8)propflags; prop.security = (uint8)propsecurity; - nw_create_obj_prop(&obj, &prop); - if (valuesize){ + result=nw_create_obj_prop(obj.id, &prop); + if (valuesize && (!result || (result == -0xed && ever)) ){ uint8 locvalue[128]; memset(locvalue, 0, sizeof(locvalue)); memcpy(locvalue, value, min(sizeof(locvalue), valuesize)); @@ -1141,7 +1152,7 @@ static int nw_set_enpasswd(uint32 obj_id, uint8 *passwd, int dont_ch) if ((!dont_ch) || (nw_get_prop_val_str(obj_id, prop_name, NULL) < 1)) nw_new_obj_prop(obj_id, NULL, 0, 0, 0, prop_name, P_FL_STAT|P_FL_ITEM, 0x44, - passwd, 16); + passwd, 16, 1); } else if (!dont_ch) (void)loc_delete_property(obj_id, prop_name, 0, 1); return(0); @@ -1154,26 +1165,6 @@ int nw_set_passwd(uint32 obj_id, char *password, int dont_ch) uint8 s_uid[4]; U32_TO_BE32(obj_id, s_uid); shuffle(s_uid, password, strlen(password), passwd); -#if 0 - XDPRINTF((2,0, "password %s->0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", - password, - (int)passwd[0], - (int)passwd[1], - (int)passwd[2], - (int)passwd[3], - (int)passwd[4], - (int)passwd[5], - (int)passwd[6], - (int)passwd[7], - (int)passwd[8], - (int)passwd[9], - (int)passwd[10], - (int)passwd[11], - (int)passwd[12], - (int)passwd[13], - (int)passwd[14], - (int)passwd[15])); -#endif return(nw_set_enpasswd(obj_id, passwd, dont_ch)); } else return(nw_set_enpasswd(obj_id, NULL, dont_ch)); @@ -1197,8 +1188,8 @@ int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, int result = loc_nw_test_passwd(keybuff, storedpass, obj_id, cryptkey, oldpass); - XDPRINTF((5, 0, "Crypted change password: id=%lx, oldpresult=0x%x", - obj_id, result)); + XDPRINTF((5, 0, "Crypted change password: id=0x%x, oldpresult=0x%x", + (int)obj_id, result)); len=(cryptedlen ^ storedpass[0] ^ storedpass[1])&0x3f; XDPRINTF((5, 0, "real len of new pass = %d", len)); @@ -1231,8 +1222,37 @@ int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass, return(memcmp(newpass, storedpass, 16) ? 0 : 1); } +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 result=nw_get_prop_val_by_obj_id(obj_id, segment, + propname, strlen(propname), + buff, &more_segments, &property_flags); + if (result < 0) + return(0); /* we have no limits */ + else { + uint8 *p=buff; + int k=0; + while (k++ < 12) { + if ( (IPXCMPNET(client_adr->net, p)) + && ( (IPXCMPNODE(client_adr->node, p+4) ) + || (IPXCMPNODE(wildnode, p+4))) ) + return(0); + p+=10; + } + } + XDPRINTF((1, 0, "No access for Station %s", visable_ipx_adr(client_adr))); + return(-0xff); /* perhaps I find a better result later */ +} + +#if 0 int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) -/* addiert member to set, if member not in set */ +/* add member to set, if member not in set */ { int result = prop_find_member(obj_id, prop_id, member_id); if (-0xea == result) @@ -1240,15 +1260,20 @@ int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) else if (!result) result = -0xee; /* already exist */ return(result); } +#endif -int nw_new_add_prop_member(uint32 obj_id, char *propname, uint32 member_id) -/* addiert member to set, if member not in set */ +static int nw_new_add_prop_member(uint32 obj_id, char *propname, + int propflags, int propsecurity, + uint32 member_id) +/* add member to set, if member not in set */ { NETPROP prop; int result; strmaxcpy(prop.name, propname, sizeof(prop.name)); - result = find_prop_id(&prop, obj_id, 0); - if (!result) { + prop.flags = (uint8) (propflags | P_FL_SET); /* always SET */ + prop.security = (uint8) propsecurity; + result = nw_create_obj_prop(obj_id, &prop); + if (!result || result == -0xed) { /* created or exists */ if (-0xea == (result=prop_find_member(obj_id, prop.id, member_id))) return(prop_add_member(obj_id, prop.id, member_id)); else if (!result) result = -0xee; /* already exist */ @@ -1256,18 +1281,18 @@ int nw_new_add_prop_member(uint32 obj_id, char *propname, uint32 member_id) return(result); } -static void create_nw_db(char *fn, int allways) +static void create_nw_db(char *fn, int always) { char fname[200]; struct stat stbuff; sprintf(fname, "%s/%s.dir", PATHNAME_BINDERY, fn); - if (allways || stat(fname, &stbuff)){ + if (always || stat(fname, &stbuff)){ int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); } chmod(fname, 0600); sprintf(fname, "%s/%s.pag", PATHNAME_BINDERY, fn); - if (allways || stat(fname, &stbuff)){ + if (always || stat(fname, &stbuff)){ int fd = open(fname, O_CREAT | O_TRUNC | O_RDWR, 0600); if (fd > -1) close(fd); } @@ -1280,47 +1305,39 @@ static void add_pr_queue(uint32 q_id, char *q_command, uint32 su_id, uint32 ge_id) { - uint8 buff[12]; XDPRINTF((2,0, "ADD Q=%s, V=%s, C=%s", q_name, q_directory, q_command)); - U32_TO_BE32(su_id, buff); q_id = - nw_new_obj_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31, - "Q_OPERATORS", P_FL_SET, 0x31, - (char*)buff, 4); + nw_new_obj_prop(q_id, q_name, 0x3, O_FL_DYNA, 0x31, + "Q_DIRECTORY", P_FL_ITEM, 0x33, + q_directory, strlen(q_directory), 1); + /* this is mars_nwe own property to handle the print job !!! */ nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 , - "Q_DIRECTORY", P_FL_ITEM, 0x33, - q_directory, strlen(q_directory)); + "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33, + q_command, strlen(q_command), 1); - /* this is an own property to handle the print job !!! */ - nw_new_obj_prop(q_id ,NULL, 0 , 0 , 0 , - "Q_UNIX_PRINT", P_FL_ITEM| P_FL_DYNA, 0x33, - q_command, strlen(q_command)); - - U32_TO_BE32(ge_id, buff); - nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 , - "Q_USERS", P_FL_SET, 0x31, - (char*)buff, 4); + nw_new_add_prop_member(q_id, "Q_USERS", P_FL_STAT, 0x31, ge_id); + nw_new_add_prop_member(q_id, "Q_OPERATORS", P_FL_STAT, 0x31, su_id); #if 0 nw_new_obj_prop(q_id , NULL, 0 , 0 , 0 , "Q_SERVERS", P_FL_SET, 0x31, - NULL, 0); + NULL, 0, 0); #endif } static void add_user_to_group(uint32 u_id, uint32 g_id) { - nw_new_add_prop_member(u_id, "GROUPS_I'M_IN", g_id); - nw_new_add_prop_member(u_id, "SECURITY_EQUALS", g_id); - nw_new_add_prop_member(g_id, "GROUP_MEMBERS", u_id); + nw_new_add_prop_member(u_id, "GROUPS_I'M_IN", P_FL_STAT, 0x31, g_id); + nw_new_add_prop_member(u_id, "SECURITY_EQUALS", P_FL_STAT, 0x32, g_id); + nw_new_add_prop_member(g_id, "GROUP_MEMBERS", P_FL_STAT, 0x31, u_id); } static void add_user_2_unx(uint32 u_id, char *unname) { if (unname && *unname) - nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 , + nw_new_obj_prop(u_id, NULL, 0 , 0 , 0 , "UNIX_USER", P_FL_ITEM, 0x33, - (char*)unname, strlen(unname)); + (char*)unname, strlen(unname), 1); } static void add_user_g(uint32 u_id, uint32 g_id, @@ -1328,10 +1345,14 @@ static void add_user_g(uint32 u_id, uint32 g_id, char *password, int dont_ch) { /* Typ Flags Security */ - if (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x31) - && dont_ch) return; + dont_ch = (nw_new_obj(&u_id, name, 0x1 , 0x0, 0x31) + && dont_ch); + + if (dont_ch) return; + XDPRINTF((1, 0, "Add/Change User='%s', UnixUser='%s'", name, unname)); + add_user_to_group(u_id, g_id); add_user_2_unx(u_id, unname); if (password && *password) { @@ -1348,18 +1369,37 @@ static void add_group(char *name, char *unname, char *password) if (unname && *unname) nw_new_obj_prop(g_id, NULL, 0 , 0 , 0 , "UNIX_GROUP", P_FL_ITEM, 0x33, - (char*)unname, strlen(unname)); + (char*)unname, strlen(unname), 1); } -static int get_sys_unixname(uint8 *unixname, uint8 *sysentry) +static int xmkdir(char *unixname, int mode) +{ + char *p=unixname; + while (NULL != (p=strchr(p+1, '/'))) { + *p = '\0'; + if (!mkdir(unixname, mode)) + chmod(unixname, mode); + *p='/'; + } + if (!mkdir(unixname, mode)) { + chmod(unixname, mode); + return(0); + } + return(-1); +} + +static int get_sys_unixname(uint8 *unixname, uint8 *sysname, uint8 *sysentry) { - uint8 sysname[256]; uint8 optionstr[256]; int founds = sscanf((char*)sysentry, "%s %s %s",sysname, unixname, optionstr); if (founds > 1 && *unixname) { struct stat statb; - int result = 0; + int result = strlen(sysname); uint8 *pp = unixname + strlen(unixname); + if (*(sysname+result-1) == ':') + *(sysname+result-1) = '\0'; + upstr(sysname); + result=0; if (founds > 2) { uint8 *p; for (p=optionstr; *p; p++) { @@ -1372,37 +1412,49 @@ static int get_sys_unixname(uint8 *unixname, uint8 *sysentry) if (*(pp-1) != '/') *pp++ = '/'; *pp = '.'; *(pp+1) = '\0'; - if (stat(unixname, &statb) < 0) { - errorp(1, "stat error:unix dir for SYS:", "fname='%s'", unixname); + + if (stat(unixname, &statb) < 0) + xmkdir(unixname, 0777); + + if (stat(unixname, &statb) < 0 || !S_ISDIR(statb.st_mode)) { + errorp(1, "No good SYS", "unix name='%s'", unixname); return(-1); } + *pp = '\0'; return(result); } else return(-1); } -static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int shorten, +static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int flags, int downshift, int permiss, int gid, int uid, char *fn) + +/* flags & 1 = fn will be appended to unixname */ +/* flags & 2 = always modify uid/gid, permission */ { struct stat stb; strcpy((char*)pp, fn); if (downshift) downstr(pp); else upstr(pp); if (stat(unixname, &stb) < 0) { - if (mkdir(unixname, 0777)< 0) + if (xmkdir(unixname, permiss)< 0) errorp(1, "mkdir error", "fname='%s'", unixname); else { - chmod(unixname, permiss); - if (uid >-1 && gid > -1) chown(unixname, uid, gid); + if (uid >-1 && gid > -1) + chown(unixname, uid, gid); XDPRINTF((1, 0, "Created dir '%s'", unixname)); } + } else if (flags&2) { + chmod(unixname, permiss); + if (uid >-1 && gid > -1) + chown(unixname, uid, gid); } - if (shorten) *pp='\0'; - else { + if (flags&1) { pp += strlen(pp); *pp++='/'; *pp = '\0'; - } + } else + *pp='\0'; return(pp); } @@ -1429,12 +1481,6 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) uint32 ge_id = 0x01000001; uint32 serv_id = 0x03000001; uint32 q1_id = 0x0E000001; -#if 0 - uint32 guest_id = 0x02000001; - uint32 nbo_id = 0x0B000001; - uint32 ngr_id = 0x0C000001; - uint32 ps1_id = 0x0D000001; -#endif #ifdef _MAR_TESTS_1 uint32 pserv_id = 0L; #endif @@ -1446,7 +1492,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) sysentry[0] = '\0'; ge_id = nw_new_obj_prop(ge_id, "EVERYONE", 0x2, 0x0, 0x31, "GROUP_MEMBERS", P_FL_SET, 0x31, - NULL, 0); + NULL, 0, 0); if (f){ char buff[256]; int what; @@ -1534,12 +1580,12 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) upstr(serverna); nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, - (char*)adr, sizeof(ipxAddr_t)); + (char*)adr, sizeof(ipxAddr_t), 1); #ifdef _MAR_TESTS_1 nw_new_obj_prop(pserv_id, serverna, 0x47, O_FL_DYNA, 0x31, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, - (char*)adr, sizeof(ipxAddr_t)); + (char*)adr, sizeof(ipxAddr_t), 1); #endif } if (auto_ins_user) { @@ -1592,23 +1638,29 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) int result = 0; if (make_tests) { uint8 unixname[512]; - result = get_sys_unixname(unixname, sysentry); + uint8 maildir[512]; + uint8 sysname[256]; + result = get_sys_unixname(unixname, sysname, sysentry); if (result > -1) { uint32 objs[2000]; /* max. 2000 User should be enough :) */ int ocount=0; int downshift = (result & 1); - uint8 *pp = unixname+strlen(unixname); - uint8 *ppp; - test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "LOGIN"); - test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "SYSTEM"); - test_add_dir(unixname, pp, 1, downshift,0777, 0,0, "PUBLIC"); - ppp=test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "MAIL"); + int unlen = strlen(unixname); + uint8 *pp = unixname+unlen; + uint8 *ppp = maildir+unlen; + memcpy(maildir, unixname, unlen+1); + + test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "LOGIN"); + test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "SYSTEM"); + test_add_dir(unixname, pp, 0, downshift,0777, 0,0, "PUBLIC"); + ppp=test_add_dir(maildir, ppp, 1, downshift,0777, 0,0, "MAIL"); + if (!dbminit(FNOBJ)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { data = fetch(key); if (data.dptr) { NETOBJ *obj=(NETOBJ*)data.dptr; - if (obj->type == 1) { + if (obj->type == 1 || obj->type == 3) { objs[ocount++] = obj->id; if (ocount == 2000) break; } @@ -1616,18 +1668,35 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) } } dbmclose(); + while (ocount--) { - char sx[20]; - int gid; - int uid; - sprintf(sx, "%lx", objs[ocount]); - if (!get_guid(&gid, &uid, objs[ocount], NULL)) - test_add_dir(unixname, ppp, 1, downshift, 0770, gid, uid, sx); - else { - NETOBJ obj; - obj.id = objs[ocount]; - nw_get_obj(&obj); - errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name); + NETOBJ obj; + obj.id = objs[ocount]; + nw_get_obj(&obj); + if (obj.type == 1) { + char sx[20]; + int gid; + int uid; + sprintf(sx, "%x", (int)obj.id); + if (!get_guid(&gid, &uid, obj.id, NULL)) + test_add_dir(maildir, ppp, 2, downshift, 0733, gid, uid, sx); + else + errorp(0, "Cannot get unix uid/gid", "User=`%s`", obj.name); + + } else if (obj.type == 3) { /* print queue */ + uint8 buff[300]; + char *p; + int result=nw_get_q_dirname(obj.id, buff); + upstr(buff); + if (result > -1 && NULL != (p=strchr(buff, ':')) ) { + *p++='\0'; + if (!strcmp(buff, sysname)) { + test_add_dir(unixname, pp, 2, downshift, 0770, 0, 0, p); + } else + errorp(0, "Warning:queue dir not on first SYS", + "Queue=%s, Volume=%s", obj.name, sysname); + } else + errorp(0, "Cannot get queue dir", "Queue=%s", obj.name); } } result = 0; @@ -1642,13 +1711,13 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) /* * routine inits bindery * all dynamic objects and properties will be deletet. - * and the allways needed properties will be created + * and the always needed properties will be created * if not exist. */ { int anz=0; - uint32 objs[10000]; /* max.10000 Objekte */ - uint8 props[10000]; /* max 10000 Properties */ + uint32 objs[LOC_MAX_OBJS]; + uint8 props[LOC_MAX_OBJS]; create_nw_db(dbm_fn[FNOBJ], 0); create_nw_db(dbm_fn[FNPROP], 0); @@ -1662,35 +1731,37 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr) if ((obj->flags & O_FL_DYNA) || !obj->name[0]) { /* dynamic or without name */ objs[anz++] = obj->id; - if (anz == 10000) break; + if (anz == LOC_MAX_OBJS) break; } else if (obj->type == 1 /* && obj->id != 1 */ && obj->security != 0x31) { /* this is for correcting wrong obj security */ obj->security=0x31; (void)store(key, data); - XDPRINTF((1,0, "Correcting access obj_id=0x%lx(%s)", - obj->id, obj->name)); + XDPRINTF((1,0, "Correcting access obj_id=0x%x(%s)", + (int)obj->id, obj->name)); } } } } dbmclose(); - while (anz--) loc_delete_obj(objs[anz], 0x44); /* Now delete */ + while (anz--) + loc_delete_obj(objs[anz], 0x44); /* Now delete dynamic objects */ anz = 0; if (!dbminit(FNPROP)){ for (key = firstkey(); key.dptr != NULL; key = nextkey(key)) { data = fetch(key); if (data.dptr) { NETPROP *prop=(NETPROP*)data.dptr; - if (prop->flags & P_FL_DYNA) { /* Dynamisch */ + if (prop->flags & P_FL_DYNA) { /* dynamic */ objs[anz] = prop->obj_id; props[anz++] = prop->id; - if (anz == 10000) break; + if (anz == LOC_MAX_OBJS) break; } } } } dbmclose(); - while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz], 1); /* now delete */ + while (anz--) /* now delete dynamic properties */ + loc_delete_property(objs[anz], (char*)NULL, props[anz], 1); anz = nw_fill_standard(servername, adr); sync_dbm(); return(anz); @@ -1734,9 +1805,9 @@ static FILE *open_exp_file(char *path, int what_dbm, int mode) } + static int export_obj(char *path) { - char *err_str="export_obj"; int result = 1; FILE *f = open_exp_file(path, FNOBJ, 1); if (f != NULL) { @@ -1746,7 +1817,7 @@ static int export_obj(char *path) if (data.dptr) { NETOBJ *o=(NETOBJ*)data.dptr; fprintf(f, "0x%08x %-47s 0x%04x 0x%02x 0x%02x\n", - o->id, o->name, (int) o->type, + (int) o->id, o->name, (int) o->type, (int) o->flags, (int)o->security); } } @@ -1758,7 +1829,6 @@ static int export_obj(char *path) static int export_prop(char *path) { - char *err_str="export_prop"; int result = 1; FILE *f = open_exp_file(path, FNPROP, 1); if (f != NULL) { @@ -1768,7 +1838,7 @@ static int export_prop(char *path) if (data.dptr) { NETPROP *p=(NETPROP*)data.dptr; fprintf(f, "0x%08x 0x%02x %-15s 0x%02x 0x%02x\n", - p->obj_id, (int)p->id, p->name, + (int) p->obj_id, (int)p->id, p->name, (int) p->flags, (int)p->security); } } @@ -1780,7 +1850,6 @@ static int export_prop(char *path) static int export_val(char *path) { - char *err_str="export_val"; int result = 1; FILE *f = open_exp_file(path, FNVAL, 1); if (f != NULL) { @@ -1792,7 +1861,7 @@ static int export_val(char *path) int k=128; uint8 *p=v->value; fprintf(f, "0x%08x 0x%02x 0x%02x ", - v->obj_id, (int)v->prop_id, (int) v->segment); + (int) v->obj_id, (int)v->prop_id, (int) v->segment); while (k--) { fprintf(f, "%02x", (int)*p++); } @@ -1830,11 +1899,13 @@ static int import_obj(char *path) int type; int flags; int security; + int obj_id; line++; if (sscanf(buff, "%x %s %x %x %x", - &(obj.id), name, &type, + &(obj_id), name, &type, &flags, &security) == 5) { strmaxcpy(obj.name, name, 47); + obj.id = (uint32) obj_id; obj.type = (uint16)type; obj.flags = (uint8) flags; obj.security = (uint8) security; @@ -1870,12 +1941,13 @@ static int import_prop(char *path) NETPROP prop; int id; char name[300]; - int type; + int obj_id; int flags; int security; line++; if (sscanf(buff, "%x %x %s %x %x", - &(prop.obj_id), &id, name, &flags, &security) == 5) { + &(obj_id), &id, name, &flags, &security) == 5) { + prop.obj_id = (uint32)obj_id; prop.id = (uint8)id; strmaxcpy(prop.name, name, 15); prop.flags = (uint8) flags; @@ -1911,16 +1983,18 @@ static int import_val(char *path) while (fgets(buff, sizeof(buff), f) != NULL){ NETVAL val; int prop_id; + int obj_id; int segment; char value[300]; line++; if (sscanf(buff, "%x %x %x %s", - &(val.obj_id), &prop_id, &segment, value) == 4) { + &obj_id, &prop_id, &segment, value) == 4) { uint8 *p=val.value; uint8 *pp=value; char smallbuf[3]; int k=128; smallbuf[2] = '\0'; + val.obj_id = (uint32) obj_id; while (k--) { int i; memcpy(smallbuf, pp, 2); @@ -1936,7 +2010,7 @@ static int import_val(char *path) data.dptr = (char*)&val; if (store(key, data)) { errorp(0, err_str, "Cannot store obj_id=0x%8x, prop_id=0x%x", - val.obj_id, (int)val.prop_id); + (int)val.obj_id, (int)val.prop_id); } } else { errorp(0, err_str, "Wrong line=%d: `%s`",line, buff); diff --git a/nwdbm.h b/nwdbm.h index 9f21343..fa4effb 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -1,4 +1,4 @@ -/* nwdbm.h 30-Apr-96 */ +/* nwdbm.h 04-Oct-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -170,7 +170,7 @@ extern int nw_create_prop(int object_type, 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); + char *value, int valuesize, int ever); extern int get_guid(int *gid, int *uid, uint32 obj_id, uint8 *name); extern int get_home_dir(uint8 *homedir, uint32 obj_id); @@ -184,6 +184,8 @@ extern int nw_keychange_passwd(uint32 obj_id, int cryptedlen, uint8 *newpass, uint32 act_id); +extern int nw_test_adr_access(uint32 obj_id, ipxAddr_t *client_adr); + extern int nw_get_q_dirname(uint32 q_id, uint8 *buff); extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff); diff --git a/nwfile.c b/nwfile.c index 2a1eefb..afb2aab 100644 --- a/nwfile.c +++ b/nwfile.c @@ -1,4 +1,4 @@ -/* nwfile.c 16-Jul-96 */ +/* nwfile.c 29-Sep-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -123,19 +123,38 @@ void init_file_module(void) anz_fhandles = 0; } + +static int xsetegid(gid_t gid) +{ + int result = -1; + if (!seteuid(0)) { + if (setegid(gid)) { + XDPRINTF((2, 0, "Cannot change eff Group ID to %d", gid)); + } else + result=0; + if (seteuid(act_uid)) { + reset_guid(); + result = -1; + } + } + return(result); +} + int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, int attrib, int access, int creatmode) /* - * creatmode: 0 = open | 1 = creat (ever) | 2 = creatnew ( creat if not exist ) - * & 4 == save handle (creat) - * & 8 == ignore rights (create ever) + * creatmode: 0 = open + * | 1 = creat (ever) + * | 2 = creatnew ( creat if not exist ) + * & 4 == save handle (creat) + * & 8 == ignore rights (create ever) * attrib ?? * * access: 0x1=read, * 0x2=write, * 0x4=deny read, -> F_WRLCK * 0x8=deny write -> F_RDLCK - * 0x10=SH_COMPAT + * 0x10=SH_COMPAT * * 0x09 (O_RDONLY | O_DENYWRITE); * 0x05 (O_RDONLY | O_DENYREAD); @@ -152,154 +171,206 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff, int dowrite = (access & 2) || creatmode; if (fhandle > 0){ FILE_HANDLE *fh=&(file_handles[fhandle-1]); - int completition = -0xff; /* no File Found */ + int completition = 0; /* first ok */ int voloptions = get_volume_options(volume, 1); + int acc = (!stat(fh->fname, stbuff)) + ? get_real_access(stbuff) : -1; + + int did_grpchange = 0; if (dowrite && (voloptions & VOL_OPTION_READONLY)) { completition = (creatmode) ? -0x84 : -0x94; - } else if (voloptions & VOL_OPTION_IS_PIPE) { - /* this is a PIPE Volume */ - int statr = stat(fh->fname, stbuff); - if (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) { + } else if (acc > -1) { + /* do exist */ + if (!S_ISDIR(stbuff->st_mode)) { + if (!(voloptions & VOL_OPTION_IS_PIPE) + || S_ISFIFO(stbuff->st_mode) ) { + /* We look for normal file accesses */ + if (creatmode & 2) { + XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->fname)); + completition = -0x85; /* No Priv */ + } else if (dowrite && !(acc & W_OK) && !(creatmode & 0x8) ) + completition = (creatmode) ? -0x84 : -0x94; + else if (!(acc & R_OK) && !(creatmode & 0x8) ) + completition = -0x93; + } else if (acc & X_OK) { + /* special Handling for PIPE commands */ + if (!(acc & W_OK)) { + if (acc & 0x10) /* access owner */ + stbuff->st_mode |= S_IWUSR; + else if (acc & 0x20) /* access group */ + stbuff->st_mode |= S_IWGRP; + else + stbuff->st_mode |= S_IWOTH; + } + } else { + XDPRINTF((4, 0, "No PIPE command rights st_mode=0x%x uid=%d, gid=%d", + stbuff->st_uid, stbuff->st_gid)); + completition = -0xff; + } + } else + completition= -0xff; + } else if ( (voloptions & VOL_OPTION_IS_PIPE) || !creatmode) { + /* must exist, but don't */ + completition=-0xff; + } else { + /* File do not exist yet, but must be created */ + char *p=strrchr(unixname, '/'); + /* first we say: not OK */ + completition = -0xff; + if (p) { + *p='\0'; + acc = (!stat(unixname, stbuff)) + ? get_real_access(stbuff) : -1; + if (acc > 0) { + if (acc & W_OK) /* we need write access for this directory */ + completition=0; + else + completition=-0x84; /* no creat rights */ + } + *p='/'; + } + if (completition && (creatmode & 8)) { + acc=0; + completition=0; + } + } + + if ( (!completition) && (acc & 0x20) && (stbuff->st_gid != act_gid)) { + /* here we try a change egid */ + if (xsetegid(stbuff->st_gid)) { + completition = -0x85; /* no privillegs */ + } else { + did_grpchange++; + } + } + + if (!completition) { + if (voloptions & VOL_OPTION_IS_PIPE) { + /* <========= this is a PIPE Volume ====================> */ fh->fh_flags |= FH_IS_PIPE; if (S_ISFIFO(stbuff->st_mode)){ fh->fd = open(fh->fname, O_NONBLOCK | dowrite ? O_RDWR : O_RDONLY); + } else { - int is_ok=0; - if (act_uid == stbuff->st_uid) { - if (stbuff->st_mode & S_IXUSR) { - stbuff->st_mode |= S_IWUSR; - is_ok++; - } - } else if (act_gid == stbuff->st_gid) { - if (stbuff->st_mode & S_IXGRP) { - stbuff->st_mode |= S_IWGRP; - is_ok++; - } - } else { - if (stbuff->st_mode & S_IXOTH) { - stbuff->st_mode |= S_IWOTH; - is_ok++; - } - } - if (is_ok) { - fh->fh_flags |= FH_IS_PIPE_COMMAND; - fh->fd=-3; - } else { - fh->fd=-1; - XDPRINTF((5, 0, "No PIPE command rights st_mode=0x%x uid=%d, gid=%d", - stbuff->st_uid, stbuff->st_gid)); - } + fh->fh_flags |= FH_IS_PIPE_COMMAND; + fh->fd=-3; } if (fh->fd != -1) { - if (!dowrite) stbuff->st_size = 0x7fff0000 | (rand() & 0xffff); + if (!dowrite) + stbuff->st_size = 0x7fff0000 | (rand() & 0xffff); (void)time(&(stbuff->st_mtime)); - if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; + if (creatmode & 4) + fh->fh_flags |= FH_DO_NOT_REUSE; + if (did_grpchange) + xsetegid(act_gid); return(fhandle); } - } - } else { - if (creatmode) { /* creat File */ - if (creatmode & 0x2) { /* creatnew */ - if (!stat(fh->fname, stbuff)) { - XDPRINTF((5,0,"CREAT File exist!! :%s:", fh->fname)); - fh->fd = -1; - completition = -0x85; /* No Priv */ - } else { + } else { + /* <========= this is NOT a PIPE Volume ====================> */ + if (creatmode) { /* creat File */ + if (creatmode & 0x2) { /* creatnew */ XDPRINTF((5,0,"CREAT FILE:%s: Handle=%d", fh->fname, fhandle)); fh->fd = creat(fh->fname, 0777); - if (fh->fd < 0) completition = -0x84; /* no create Rights */ + if (fh->fd < 0) + completition = -0x84; /* no create Rights */ + else + chmod(fh->fname, act_umode_file); + } else { + XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->fname:%s: handle:%d", + attrib, access, fh->fname, fhandle)); + fh->fd = open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777); + if (fh->fd < 0) { + if (creatmode & 0x8) { + if ( (!seteuid(0)) && (-1 < (fh->fd = + open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777)))) { + chown(fh->fname, act_uid, act_gid); + } + did_grpchange=0; + reset_guid(); + } + if (fh->fd < 0) + completition = -0x85; /* no delete /create Rights */ + } else + chmod(fh->fname, act_umode_file); + } + if (fh->fd > -1) { + close(fh->fd); + fh->fd = open(fh->fname, O_RDWR); + fh->offd = 0L; + stat(fh->fname, stbuff); } } else { - XDPRINTF((5,0,"CREAT FILE, ever with attrib:0x%x, access:0x%x, fh->fname:%s: handle:%d", - attrib, access, fh->fname, fhandle)); - fh->fd = open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777); - if (fh->fd < 0) { - if (creatmode & 0x8) { - if ( (!seteuid(0)) && (-1 < (fh->fd = - open(fh->fname, O_CREAT|O_TRUNC|O_RDWR, 0777)))) { - chown(fh->fname, act_uid, act_gid); + /* 'normal' open of file */ + int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY; + if (S_ISFIFO(stbuff->st_mode)){ + acm |= O_NONBLOCK; + fh->fh_flags |= FH_IS_PIPE; + if (!dowrite) stbuff->st_size = 0x7fffffff; + (void)time(&(stbuff->st_mtime)); + } + fh->fd = open(fh->fname, acm); + XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d", + attrib,access, fh->fname, fhandle)); + fh->offd = 0L; + if (fh->fd < 0) + completition = dowrite ? -0x94 : -0x93; + } + + if (fh->fd > -1) { + if (!(fh->fh_flags & FH_IS_PIPE)) { + /* Not a PIPE */ + if ((access & 0x4) || (access & 0x8)) { + struct flock flockd; + int result; + flockd.l_type = (access & 0x8) ? F_RDLCK : F_WRLCK; + flockd.l_whence = SEEK_SET; + flockd.l_start = 0; + flockd.l_len = 0; + result = fcntl(fh->fd, F_SETLK, &flockd); + XDPRINTF((5, 0, "open shared lock:result=%d", result)); + if (result == -1) { + close(fh->fd); + fh->fd = -1; + completition=-0xfe; } - set_guid(act_gid, act_uid); } - if (fh->fd < 0) - completition = -0x85; /* no delete /create Rights */ +#if USE_MMAP + if (fh->fd > -1 && !dowrite) { + fh->size_mmap = fh->offd=lseek(fh->fd, 0L, SEEK_END); + if (fh->size_mmap > 0) { + fh->p_mmap = mmap(NULL, + fh->size_mmap, + PROT_READ, + MAP_SHARED, + fh->fd, 0); + if (fh->p_mmap == (uint8*) -1) { + fh->p_mmap = NULL; + fh->size_mmap=0; + } + } + } +#endif } } if (fh->fd > -1) { - close(fh->fd); - fh->fd = open(fh->fname, O_RDWR); - fh->offd = 0L; - stat(fh->fname, stbuff); + if (!dowrite) fh->fh_flags |= FH_IS_READONLY; + if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; + if (did_grpchange) + xsetegid(act_gid); + return(fhandle); } - } else { - int statr = stat(fh->fname, stbuff); - int acm = (dowrite) ? (int) O_RDWR : (int)O_RDONLY; - if ( (!statr && !S_ISDIR(stbuff->st_mode)) - || (statr && (acm & O_CREAT))){ - if ((!statr) && S_ISFIFO(stbuff->st_mode)){ - acm |= O_NONBLOCK; - fh->fh_flags |= FH_IS_PIPE; - if (!dowrite) stbuff->st_size = 0x7fffffff; - (void)time(&(stbuff->st_mtime)); - } - fh->fd = open(fh->fname, acm, 0777); - XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); - fh->offd = 0L; - if (fh->fd > -1) { - if (statr) stat(fh->fname, stbuff); - } else completition = dowrite ? -0x94 : -0x93; - } - } - if (fh->fd > -1) { - if (!(fh->fh_flags & FH_IS_PIPE)) { - /* Not a PIPE */ - if ((access & 0x4) || (access & 0x8)) { - struct flock flockd; - int result; - flockd.l_type = (access & 0x8) ? F_RDLCK : F_WRLCK; - flockd.l_whence = SEEK_SET; - flockd.l_start = 0; - flockd.l_len = 0; - result = fcntl(fh->fd, F_SETLK, &flockd); - XDPRINTF((5, 0, "open shared lock:result=%d", result)); - if (result == -1) { - close(fh->fd); - fh->fd = -1; - completition=-0xfe; - } - } -#if USE_MMAP - if (fh->fd > -1 && !dowrite) { - fh->size_mmap = fh->offd=lseek(fh->fd, 0L, SEEK_END); - if (fh->size_mmap > 0) { - fh->p_mmap = mmap(NULL, - fh->size_mmap, - PROT_READ, - MAP_SHARED, - fh->fd, 0); - if (fh->p_mmap == (uint8*) -1) { - fh->p_mmap = NULL; - fh->size_mmap=0; - } - } - } -#endif - } - } - if (fh->fd > -1) { - if (!dowrite) fh->fh_flags |= FH_IS_READONLY; - if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE; - return(fhandle); - } - } /* else (NOT DEVICE) */ - XDPRINTF((5,0,"OPEN FILE not OK ! fh->name:%s: fhandle=%d",fh->fname, fhandle)); + } /* else (NOT DEVICE) */ + } /* if !completition */ + if (did_grpchange) + xsetegid(act_gid); + XDPRINTF((5,0,"OPEN FILE not OK (-0x%x), fh->name:%s: fhandle=%d", + -completition, fh->fname, fhandle)); free_file_handle(fhandle); return(completition); } else return(-0x81); /* no more File Handles */ } - int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit) { if (fhandle > 0 && (--fhandle < anz_fhandles) ) { diff --git a/nwqueue.c b/nwqueue.c index 952fff9..ce614bb 100644 --- a/nwqueue.c +++ b/nwqueue.c @@ -1,4 +1,4 @@ -/* nwconn.c 10-Aug-96 */ +/* nwconn.c 29-Sep-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -266,16 +266,26 @@ static int create_queue_file(uint8 *job_file_name, { int result; - NW_FILE_INFO fnfo; *job_file_name = sprintf((char*)job_file_name+1, "%07lX%d.%03d", q_id, jo_id, connection); + seteuid(0); result=nw_alloc_dir_handle(0, dirname, dir_nam_len, 99, 2, 1); - if (result > -1) - result = nw_creat_open_file(result, job_file_name+1, - (int) *job_file_name, - &fnfo, 0x6, 0x6, 1 | 4 | 8); - + if (result > -1) { + char unixname[300]; + result=conn_get_kpl_unxname(unixname, result, + job_file_name+1, (int) *job_file_name); + if (result > -1) { + struct stat stbuff; + result=file_creat_open(result, (uint8*)unixname, + &stbuff, 0x6, 0x6, 1|4|8); + if (result > -1) { + chown(unixname, act_uid, act_gid); + chmod(unixname, 0660); + } + } + } + reset_guid(); XDPRINTF((5,0,"creat queue file bez=`%s` handle=%d", job_bez, result)); return(result); @@ -381,7 +391,13 @@ int nw_close_file_queue(uint8 *queue_id, strmaxcpy((uint8*)printcommand, prc, prc_len); nw_close_datei(fhandle, 1); jo->fhandle = 0L; - if (NULL != (f = fopen(unixname, "r"))) { + if (NULL == (f = fopen(unixname, "r"))) { + /* OK now we try the open as root */ + seteuid(0); + f = fopen(unixname, "r"); + reset_guid(); + } + if (NULL != f) { int is_ok = 0; FILE_PIPE *fp = ext_popen(printcommand, geteuid(), getegid()); if (fp) { @@ -404,7 +420,9 @@ int nw_close_file_queue(uint8 *queue_id, XDPRINTF((1,0,"Cannot open pipe `%s`", printcommand)); fclose(f); if (is_ok) { + seteuid(0); unlink(unixname); + reset_guid(); result=0; } } else XDPRINTF((1,0,"Cannot open queue-file `%s`", unixname)); diff --git a/nwserv.c b/nwserv.c index 10c3302..a549cf8 100644 --- a/nwserv.c +++ b/nwserv.c @@ -110,7 +110,6 @@ static int server_goes_down_secs = 10; static int server_broadcast_secs = 60; static int save_ipx_routes = 0; -static uint8 *station_fn=NULL; static int nearest_request_flag=0; #if IN_NWROUTED @@ -526,61 +525,6 @@ void get_server_data(char *name, XDPRINTF((2,0,"NW386 %s found at:%s", name, visable_ipx_adr(adr))); } -static int name_match(uint8 *s, uint8 *p) -{ - uint8 pc; - while ( (pc = *p++) != 0){ - switch (pc) { - case '?' : if (!*s++) return(0); /* simple char */ - break; - - case '*' : if (!*p) return(1); /* last star */ - while (*s) { - if (name_match(s, p) == 1) return(1); - ++s; - } - return(0); - - default : if (pc != *s++) return(0); /* normal char */ - break; - } /* switch */ - } /* while */ - return ( (*s) ? 0 : 1); -} - -static 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); -} - static void handle_sap(int fd, int ipx_pack_typ, int data_len, @@ -1132,10 +1076,10 @@ static void close_all(void) static void down_server(void) { if (!server_down_stamp) { - write_to_ncpserv(0xffff, 0, NULL, 0); - write_to_nwbind( 0xffff, 0, NULL, 0); signal(SIGHUP, SIG_IGN); signal(SIGPIPE, SIG_IGN); + write_to_ncpserv(0xffff, 0, NULL, 0); + write_to_nwbind( 0xffff, 0, NULL, 0); fprintf(stderr, "\007"); fprintf(stderr, "\n*********************************************\n"); fprintf(stderr, "\nWARNING: NWE-%s shuts down in %3d sec !!!\n", @@ -1149,6 +1093,14 @@ static void down_server(void) } } +#if !IN_NWROUTED +static int fl_got_sigchld=0; +static void sig_chld(int rsig) +{ + fl_got_sigchld++; +} +#endif + static int fl_get_int=0; static void sig_quit(int rsig) { @@ -1252,14 +1204,17 @@ int main(int argc, char **argv) polls[j].fd = -1; } } + +#if !IN_NWROUTED + signal(SIGCHLD, sig_chld); +#endif + if ( !start_nwbind( my_nwname, &my_server_adr) && !start_ncpserv(my_nwname, &my_server_adr) ) { /* now do polling */ time_t broadtime; time(&broadtime); - set_sigs(); - polls[NEEDED_SOCKETS].fd = fd_nwbind_in; #if !IN_NWROUTED @@ -1278,9 +1233,30 @@ int main(int argc, char **argv) int anz_poll = poll(polls, NEEDED_POLLS, broadmillisecs); int call_wdog=0; time(&akttime_stamp); +#if !IN_NWROUTED + if (fl_got_sigchld) { + int stat_loc=-1; + int pid; + int status=-1; + fl_got_sigchld=0; + if ((pid =waitpid(-1, &stat_loc, 0)) > -1) { + status=WEXITSTATUS(stat_loc); + if (WIFSIGNALED(stat_loc)) status=-99; + } + if (pid == pid_nwbind || pid == pid_ncpserv) { + errorp(1, "CHILD died", "Child=%s, result=%d", + (pid==pid_nwbind) ? "NWBIND" : "NCPSERV", status); + down_server(); + } else + errorp(1, "unknown CHILD died", NULL); + + } +#endif if (fl_get_int) { - if (fl_get_int == 1) handle_hup_reqest(); - else if (fl_get_int == 2) down_server(); + if (fl_get_int == 1) + handle_hup_reqest(); + else if (fl_get_int == 2) + down_server(); } if (anz_poll > 0) { /* i have to work */ struct pollfd *p = &polls[0]; diff --git a/tools.c b/tools.c index 180064f..7d1a55f 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 07-Aug-96 */ +/* tools.c 29-Sep-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -59,7 +59,8 @@ char *xmalloc(uint size) char *xcmalloc(uint size) { char *p = xmalloc(size); - if (size) memset(p, 0, size); + if (size) + memset(p, 0, size); return(p); } @@ -74,7 +75,8 @@ void x_x_xfree(char **p) int strmaxcpy(uint8 *dest, uint8 *source, int len) { int slen = (source != (uint8 *)NULL) ? min(len, strlen((char*)source)) : 0; - if (slen) memcpy(dest, source, slen); + if (slen) + memcpy(dest, source, slen); dest[slen] = '\0'; return(slen); } @@ -82,10 +84,13 @@ int strmaxcpy(uint8 *dest, uint8 *source, int len) int x_x_xnewstr(uint8 **p, uint8 *s) { int len = (s == NULL) ? 0 : strlen((char*)s); - if (*p != (uint8 *)NULL) free((char*)*p); + if (*p != (uint8 *)NULL) + free((char*)*p); *p = (uint8*)xmalloc(len+1); - if (len) strcpy((char*)(*p), (char*)s); - else **p = '\0'; + if (len) + strcpy((char*)(*p), (char*)s); + else + **p = '\0'; return (len); } @@ -104,16 +109,29 @@ void dprintf(char *p, ...) } void xdprintf(int dlevel, int mode, char *p, ...) +/* mode flags + * 0x01 : no 'begin line' + * 0x02 : no new line (endline) + * 0x10 : add errno print. + */ { va_list ap; + int errnum = errno; if (nw_debug >= dlevel) { - if (!(mode & 1)) fprintf(logfile, "%-8s %d:", get_modstr(), connection); + if (!(mode & 1)) + fprintf(logfile, "%-8s %d:", get_modstr(), connection); if (p) { va_start(ap, p); vfprintf(logfile, p, ap); va_end(ap); } - if (!(mode & 2)) fprintf(logfile, "\n"); + if (mode & 0x10) { + fprintf(logfile, ", errno=%d", errnum); + if (errnum > 0 && errnum < _sys_nerr) + fprintf(logfile, " (%s)", _sys_errlist[errnum]); + } + if (!(mode & 2)) + fprintf(logfile, "\n"); fflush(logfile); } } @@ -422,6 +440,14 @@ uint8 *downstr(uint8 *ss) return(ss); } +int hextoi(char *buf) +{ + int i; + if (!buf || (1 != sscanf(buf, "%x", &i))) + i=0; + return(i); +} + char *hex_str(char *buf, uint8 *s, int len) { char *pp=buf; @@ -431,3 +457,63 @@ char *hex_str(char *buf, uint8 *s, int len) } return(buf); } + +int name_match(uint8 *s, uint8 *p) +/* simple match routine matches '?' and '*' */ +{ + uint8 pc; + while ( (pc = *p++) != 0){ + switch (pc) { + case '?' : if (!*s++) return(0); /* simple char */ + break; + + case '*' : if (!*p) return(1); /* last star */ + while (*s) { + if (name_match(s, p) == 1) return(1); + ++s; + } + return(0); + + default : if (pc != *s++) return(0); /* normal char */ + break; + } /* switch */ + } /* while */ + return ( (*s) ? 0 : 1); +} + +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); +} + + diff --git a/tools.h b/tools.h index 64801c7..825a011 100644 --- a/tools.h +++ b/tools.h @@ -1,4 +1,4 @@ -/* tools.h : 01-May-96 */ +/* tools.h : 29-Sep-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -58,8 +58,15 @@ extern uint8 up_char(uint8 ch); extern uint8 *downstr(uint8 *ss); extern uint8 *upstr(uint8 *ss); +extern int hextoi(char *buf); 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; #if DO_DEBUG # define DPRINTF(x) dprintf x