diff --git a/connect.c b/connect.c index 25a5363..749191a 100644 --- a/connect.c +++ b/connect.c @@ -1,4 +1,4 @@ -/* connect.c 10-Mar-96 */ +/* connect.c 20-Mar-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -297,6 +297,7 @@ int fn_match(uint8 *s, uint8 *p, uint8 options) typedef struct { int attrib; struct stat statb; + uint8 *ubuf; /* userbuff */ } FUNC_SEARCH; static int func_search_entry(NW_PATH *nwpath, int attrib, @@ -313,11 +314,14 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, int volume = nwpath->volume; uint8 soptions; FUNC_SEARCH fs_local; - if (!fs) fs = &fs_local; + if (!fs) { + fs = &fs_local; + fs->ubuf = NULL; + } fs->attrib = attrib; if (volume < 0 || volume >= used_nw_volumes) return(-1); /* something wrong */ else soptions = nw_volumes[volume].options; - strcpy(entry, nwpath->fn); + strcpy((char*)entry, (char*)nwpath->fn); if (soptions & 1) downstr(entry); /* now downshift chars */ nwpath->fn[0] = '\0'; strcpy(xkpath, build_unix_name(nwpath, 1|2)); @@ -333,16 +337,16 @@ static int func_search_entry(NW_PATH *nwpath, int attrib, uint8 *name=(uint8*)(dirbuff->d_name); okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') - || (!strcmp(name, entry)) + || (!strcmp((char*)name, (char*)entry)) || fn_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; - strcpy(kpath, name); + strcpy(kpath, (char*)name); if (!stat(xkpath, &(fs->statb))) { okflag = ( ( ( (fs->statb.st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10)) || ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ - strcpy(nwpath->fn, name); + strcpy((char*)nwpath->fn, (char*)name); if (soptions & 1) upstr(nwpath->fn); XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode)); result = (*fs_func)(nwpath, fs); @@ -375,7 +379,7 @@ static int get_dir_entry(NW_PATH *nwpath, uint8 soptions; if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ else soptions = nw_volumes[volume].options; - strcpy(entry, nwpath->fn); + strcpy((char*)entry, (char*)nwpath->fn); if (soptions & 1) downstr(entry); /* now downshift chars */ nwpath->fn[0] = '\0'; @@ -395,16 +399,16 @@ static int get_dir_entry(NW_PATH *nwpath, uint8 *name=(uint8*)(dirbuff->d_name); okflag = (name[0] != '.' && ( (entry[0] == '*' && entry[1] == '\0') - || (!strcmp(name, entry)) + || (!strcmp((char*)name, (char*)entry)) || fn_match(name, entry, soptions))); if (okflag) { *kpath = '\0'; - strcpy(kpath, name); + strcpy(kpath, (char*)name); if (!stat(xkpath, statb)) { okflag = ( ( ( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10)) || ( ( (statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ - strcpy(nwpath->fn, name); + strcpy((char*)nwpath->fn, (char*)name); if (soptions & 1) upstr(nwpath->fn); XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode)); break; /* ready */ @@ -465,12 +469,12 @@ static int get_dh_entry(DIR_HANDLE *dh, if (dirbuff->d_ino) { uint8 *name=(uint8*)(dirbuff->d_name); okflag = (name[0] != '.' && ( - (!strcmp(name, entry)) || + (!strcmp((char*)name, (char*)entry)) || (entry[0] == '*' && entry[1] == '\0') || fn_match(name, entry, dh->vol_options))); if (okflag) { - strcpy(dh->kpath, name); + strcpy(dh->kpath, (char*)name); XDPRINTF((5,0,"get_dh_entry Name=%s unixname=%s", name, dh->unixname)); @@ -478,7 +482,7 @@ static int get_dh_entry(DIR_HANDLE *dh, okflag = ( (( (statb->st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10)) || (((statb->st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10))); if (okflag){ - strcpy(search, name); + strcpy((char*)search, (char*)name); if (dh->vol_options & 1) upstr(search); break; /* ready */ } @@ -530,10 +534,10 @@ void conn_build_path_fn( uint8 *vol, *p1 = '\0'; if (fn != NULL) { /* if with filename */ if (p != NULL){ /* exist directory-path */ - strcpy(fn, p); + strcpy((char*)fn, (char*)p); *p = '\0'; } else { /* only filename */ - strcpy(fn, path); + strcpy((char*)fn, (char*)path); *path= '\0'; } } @@ -564,7 +568,7 @@ static int build_path( NW_PATH *path, if (vol[0]) { /* there is a volume in path */ int j = used_nw_volumes; while (j--) { - if (!strcmp(nw_volumes[j].sysname, vol)) { + if (!strcmp((char*)nw_volumes[j].sysname, (char*)vol)) { path->volume = j; break; } @@ -584,7 +588,7 @@ static int nw_path_ok(NW_PATH *nwpath) while (j++ < (int)used_dirs){ if (d->inode && d->volume == nwpath->volume - && !strcmp(nwpath->path, d->path)){ + && !strcmp((char*)nwpath->path, (char*)d->path)){ return(d->inode); } d++; @@ -606,7 +610,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ uint8 *p=searchpath; int completition=0; - strcpy(searchpath, nwpath->path); /* save path */ + strcpy((char*)searchpath, (char*)nwpath->path); /* save path */ if (nwpath->volume > -1) { /* absolute path */ nwpath->path[0] = '\0'; @@ -618,7 +622,7 @@ static int build_verz_name(NW_PATH *nwpath, /* gets complete path */ p++; nwpath->path[0] = '\0'; } else /* get path from dir_handle */ - strcpy(nwpath->path, dirs[dir_handle].path); + strcpy((char*)nwpath->path, (char*)dirs[dir_handle].path); } else return(-0x9b); /* wrong dir handle */ } @@ -754,12 +758,12 @@ static int get_file_attrib(NW_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { XDPRINTF((5,0, "get_file_attrib of %s", conn_get_nwpath_name(nwpath) )); - strncpy(f->name, nwpath->fn, sizeof(f->name)); + strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); /* Attribute */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ /* TLINK (TCC 2.0) don't like it ???? */ #if 1 - if (!strcmp(nwpath->fn, "TURBOC.$LN")) f->attrib = 0x20; + if (!strcmp((char*)nwpath->fn, "TURBOC.$LN")) f->attrib = 0x20; else f->attrib = 0x80; #else f->attrib = 0x20; @@ -777,7 +781,7 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, NW_PATH *nwpath) { XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath))); - strncpy(d->name, nwpath->fn, sizeof(d->name)); + strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name)); d->attrib = 0x10; /* Verzeichnis */ d->ext_attrib = 0xff; /* effektive rights ?? */ @@ -792,8 +796,6 @@ static int get_dir_attrib(NW_DIR_INFO *d, struct stat *stb, return(1); } - - static int do_delete_file(NW_PATH *nwpath, FUNC_SEARCH *fs) { char unname[256]; @@ -817,6 +819,38 @@ int nw_delete_datei(int dir_handle, uint8 *data, int len) return(completition); } +static int do_set_file_info(NW_PATH *nwpath, FUNC_SEARCH *fs) +{ + char unname[256]; + NW_FILE_INFO *f=(NW_FILE_INFO*)fs->ubuf; + strcpy(unname, build_unix_name(nwpath, 0)); + XDPRINTF((5,0,"set_file_info unname:%s:", unname)); + if (get_volume_options(nwpath->volume, 1) & VOL_OPTION_IS_PIPE) + return(0); /* don't change 'pipe commands' */ + else { + struct utimbuf ut; + ut.actime = ut.modtime = nw_2_un_time(f->modify_date, f->modify_time); + if (!utime(unname, &ut)) return(0); + } + return(-0x85); /* NO Privileges */ +} + +int nw_set_file_information(int dir_handle, uint8 *data, int len, + int searchattrib, NW_FILE_INFO *f) +{ + NW_PATH nwpath; + int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); + if (completition > -1) { + FUNC_SEARCH fs; + fs.ubuf = (uint8*)f; + completition = func_search_entry(&nwpath, searchattrib, + do_set_file_info, &fs); + if (completition < 0) return(completition); + else if (!completition) return(-0xff); + } + return(completition); +} + int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus) { char unname[256]; @@ -964,7 +998,7 @@ int nw_init_connect(void) int what; int k = MAX_NW_DIRS; NW_DIR *d = &(dirs[0]); - strcpy(nwlogin.path, login); + strcpy((char*)nwlogin.path, (char*)login); nwlogin.fn[0] = '\0'; nwlogin.volume = 0; @@ -985,13 +1019,13 @@ int nw_init_connect(void) while (k++ < anz_dirhandles) free_dir_handle(k); } else connect_is_init++; - while (0 != (what = get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { + while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))) { if (what == 10) { /* GID */ - default_gid = atoi(buff); + default_gid = atoi((char*)buff); } else if (what == 11) { /* UID */ - default_uid = atoi(buff); + default_uid = atoi((char*)buff); } else if (what == 103) { /* Debug */ - nw_debug = atoi(buff); + nw_debug = atoi((char*)buff); } } /* while */ nw_init_volumes(f); @@ -1278,7 +1312,7 @@ int nw_creat_open_file(int dir_handle, uint8 *data, int len, int completition = conn_get_kpl_path(&nwpath, dir_handle, data, len, 0); if (completition > -1) { struct stat stbuff; - completition=file_creat_open(nwpath.volume, build_unix_name(&nwpath, 0), + completition=file_creat_open(nwpath.volume, (uint8*)build_unix_name(&nwpath, 0), &stbuff, attrib, access, creatmode); if (completition > -1) @@ -1307,7 +1341,7 @@ static int s_nw_scan_dir_info(int dir_handle, uint8 dirname[256]; if (!dirsequenz) dirsequenz++; - strcpy(dirname, wild); + strcpy((char*)dirname, (char*)wild); XDPRINTF((5,0,"SCAN_DIR: rights = 0x%x, subnr = %d", (int)rights, (int)GET_BE16(subnr))); @@ -1321,13 +1355,13 @@ static int s_nw_scan_dir_info(int dir_handle, XDPRINTF((5,0,"SCAN_DIR: von %s, found %s:", dh->unixname, dirname)); if (++aktsequenz == dirsequenz) { /* actual found */ U16_TO_BE16(aktsequenz, subnr); - strncpy(subname, dirname, 16); + strncpy((char*)subname, (char*)dirname, 16); U32_TO_BE32(1L, owner); /* erstmal */ un_date_2_nw(stbuff.st_mtime, subdatetime); un_time_2_nw(stbuff.st_mtime, subdatetime+2); return(0xff); } - strcpy(dirname, wild); + strcpy((char*)dirname, (char*)wild); } /* while */ } else { strcpy(dh->kpath, "."); @@ -1411,8 +1445,8 @@ static void get_dos_file_attrib(NW_DOS_FILE_INFO *f, struct stat *stb, NW_PATH *nwpath) { - f->namlen=min(strlen(nwpath->fn), 12); - strncpy(f->name, nwpath->fn, f->namlen); + f->namlen=min(strlen((char*)nwpath->fn), 12); + strncpy((char*)f->name, (char*)nwpath->fn, f->namlen); /* Attribute */ /* 0x20 Archive Flag */ /* 0x80 Sharable */ @@ -1449,8 +1483,8 @@ static void get_dos_dir_attrib(NW_DOS_DIR_INFO *f, struct stat *stb, NW_PATH *nwpath) { - f->namlen=min(strlen(nwpath->fn), 12); - strncpy(f->name, nwpath->fn, f->namlen); + f->namlen=min(strlen((char*)nwpath->fn), 12); + strncpy((char*)f->name, (char*)nwpath->fn, f->namlen); f->attributes[0] = 0x10; /* Dir */ xun_date_2_nw(stb->st_mtime, f->created.date); xun_time_2_nw(stb->st_mtime, f->created.time); @@ -1596,7 +1630,7 @@ static void set_entry_time(uint8 *entry_time) entry_time[5] = (uint8) s_tm->tm_sec; } -static int create_queue_file(char *job_file_name, +static int create_queue_file(uint8 *job_file_name, uint32 q_id, int jo_id, int connection, @@ -1608,7 +1642,7 @@ static int create_queue_file(char *job_file_name, int result; NW_FILE_INFO fnfo; *job_file_name - = sprintf(job_file_name+1, "%07lX%d.%03d", q_id, jo_id, connection); + = sprintf((char*)job_file_name+1, "%07lX%d.%03d", q_id, jo_id, connection); result=nw_alloc_dir_handle(0, dirname, dir_nam_len, 99, 2, 1); if (result > -1) @@ -1713,12 +1747,12 @@ int nw_close_file_queue(uint8 *queue_id, INT_QUEUE_JOB *jo=queue_jobs[jo_id-1]; int fhandle = (int)jo->fhandle; char unixname[300]; - strmaxcpy(unixname, file_get_unix_name(fhandle), sizeof(unixname)-1); + strmaxcpy((uint8*)unixname, (uint8*)file_get_unix_name(fhandle), sizeof(unixname)-1); XDPRINTF((5,0,"nw_close_file_queue fhandle=%d", fhandle)); if (*unixname) { char printcommand[256]; FILE *f=NULL; - strmaxcpy(printcommand, prc, prc_len); + strmaxcpy((uint8*)printcommand, prc, prc_len); nw_close_datei(fhandle, 1); jo->fhandle = 0L; if (NULL != (f = fopen(unixname, "r"))) { diff --git a/connect.h b/connect.h index 0d69a77..4c42287 100644 --- a/connect.h +++ b/connect.h @@ -61,6 +61,9 @@ extern int nw_creat_open_file(int dir_handle, uint8 *data, int len, NW_FILE_INFO *info, int attrib, int access, int mode); extern int nw_delete_datei(int dir_handle, uint8 *data, int len); +extern int nw_set_file_information(int dir_handle, uint8 *data, int len, + int searchattrib, NW_FILE_INFO *f); + extern int nw_chmod_datei(int dir_handle, uint8 *data, int len, int modus); extern int mv_file(int qdirhandle, uint8 *q, int qlen, diff --git a/doc/CHANGES b/doc/CHANGES index 1a2aa44..57aa177 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,5 +1,5 @@ Sorry, this is in German only. :-( -Aenderungen in mars_nwe bis zum : 10-Feb-96 +Aenderungen in mars_nwe bis zum : 21-Mar-96 -------------------------------- Erste 'oeffentliche' Version ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ @@ -95,3 +95,12 @@ Erste 'oeffentliche' Version - Moeglichkeit der stationsabhaengigen Steuerung von Nearest Server Response eingebaut. ^^^^^^^^^^ VERSION 0.97 ^^^^^^^^ +- Bug in connect.c (nw_scan_dir_info) korrigiert. +- neuses Modul nwbind erzeugt. Dadurch Designaenderungen an + allen Modulen. +- Alle NCP-Responses erhalten nun als Dest Addresse den NCP-Socket. + OS/2 Client u. evtl. auch andere (Win95 ?) erwarten es. ! +- Password Schema leicht veraendert/erweitert. + modus '8' -> modus '7', neuer modus '8'. +- neue Routine 0x17, 0x10 (set file information) codiert. + diff --git a/doc/NEWS b/doc/NEWS index a49d30b..04afd2a 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -1,4 +1,16 @@ # in this files are important notes for user of mars_nwe. +------21-Mar-96--- 0.97.pl2 ---------- +Entry '7' in ini/conf file modified. +Old mode '8' is now mode '7' and mode '8' +is now extended by allowing empty mars_nwe passwords +although the linux password from this user is not empty. +- +Now mars_nwe works fine with OS/2 Client. :) +- +There is a new little kernelpatch 'kpatch1.3.72' in the +examples directory. +With this patch mars_nwe will speed up more than 30 %. + ------10-Mar-96--- 0.97.pl0 ---------- New Conf-file entry '211' for broadcast periods. Entries 400, 401 for special handling of the nearest server request. diff --git a/doc/mars_nwe.lsm b/doc/mars_nwe.lsm index c42f75d..36d755d 100644 --- a/doc/mars_nwe.lsm +++ b/doc/mars_nwe.lsm @@ -1,7 +1,7 @@ Begin3 Title: mars_nwe -Version: 0.97 -Entered-date: 10-Mar-96 +Version: 0.97.pl2 +Entered-date: 21-Mar-96 Description: full novell-server-emulator (src),beta supports file-services, bindery-services, printing-services, routing-services @@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli Author: mstover@freeway.de (Martin Stover) Maintained-by: mstover@freeway.de (Martin Stover) Primary-site: linux01.gwdg.de /pub/ncpfs - 110kB mars_nwe-0.97.tgz + 120kB mars_nwe-0.97.pl2.tgz Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Platforms: Linux (1.2.xx, 1.3.32, > 1.3.55 tested, others should work) Copying-policy: GNU diff --git a/emutli.c b/emutli.c index 935c569..ad2e49c 100644 --- a/emutli.c +++ b/emutli.c @@ -191,17 +191,31 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug) int result=-1; int sock=sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX); if (socket < 0) { - errorp(0, "EMUTLI:init_ipx", NULL); + errorp(1, "EMUTLI:init_ipx", NULL); exit(1); } else { set_sock_debug(sock); - close(sock); result=0; /* makes 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; + } else result =-1; + close(sock); + if (result) { + errorp(1, "EMUTLI:init_ipx socket 0x451", NULL); + exit(1); + } del_internal_net(); add_internal_net(network, node); have_ipx_started++; + } else { + close(sock); } } return(result); diff --git a/examples/README.patch b/examples/README.kpatch1.3.56 similarity index 100% rename from examples/README.patch rename to examples/README.kpatch1.3.56 diff --git a/examples/README.kpatch1.3.72 b/examples/README.kpatch1.3.72 new file mode 100644 index 0000000..9b2a2ac --- /dev/null +++ b/examples/README.kpatch1.3.72 @@ -0,0 +1,12 @@ +The kernelpatch kpatch1.3.72 you can use directly for kernels 1.3.72 .. ??? +but it should be easy to apply this patch to all kernels. +By older kernels 'sk->protinfo.af_ipx.' must become 'sk->' . +After applying this patch please rebuild mars_nwe (make clean) +for getting notice of new ioctl call 'SIOCIPXNCPCONN'. + +This patch is only necessary to speed up mars_nwe. (ca. 30 .. 50 % ) +Perhaps this patch will get a place in the kerneldistribution one day. :) + +This kernelpatch was originally designed by Volker Lendecke. + +Martin diff --git a/examples/kpatch1.3.72 b/examples/kpatch1.3.72 new file mode 100644 index 0000000..6b8f7ea --- /dev/null +++ b/examples/kpatch1.3.72 @@ -0,0 +1,72 @@ +Index: include/linux/ipx.h +--- linux.org/include/linux/ipx.h Mon Dec 11 19:55:58 1995 ++++ linux/include/linux/ipx.h Thu Mar 21 17:14:49 1996 +@@ -74,5 +74,6 @@ + #define SIOCAIPXITFCRT (SIOCPROTOPRIVATE) + #define SIOCAIPXPRISLT (SIOCPROTOPRIVATE+1) + #define SIOCIPXCFGDATA (SIOCPROTOPRIVATE+2) ++#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE+3) + #endif + +Index: include/net/sock.h +Prereq: 1.0.4 +--- linux.org/include/net/sock.h Mon Mar 11 02:08:59 1996 ++++ linux/include/net/sock.h Thu Mar 21 02:36:23 1996 +@@ -96,6 +96,7 @@ + ipx_address dest_addr; + ipx_interface *intrfc; + unsigned short port; ++ unsigned short ipx_ncp_conn; + #ifdef CONFIG_IPX_INTERN + unsigned char node[IPX_NODE_LEN]; + #endif +Index: net/ipx/af_ipx.c +--- linux.org/net/ipx/af_ipx.c Sun Mar 10 22:51:28 1996 ++++ linux/net/ipx/af_ipx.c Thu Mar 21 17:26:54 1996 +@@ -438,6 +438,20 @@ + ipx_socket *sock1 = NULL, *sock2 = NULL; + struct sk_buff *skb1 = NULL, *skb2 = NULL; + ++ if (intrfc == ipx_primary_net ++ && ntohs(ipx->ipx_dest.sock) == 0x451 ++ && *((char*)(ipx+1)) == 0x22 ++ && *((char*)(ipx+1)+1) == 0x22) { ++ int connection = (int) *((char*)(ipx+1)+3); ++ /* 255 connections are enough ;) */ ++ if (connection) { ++ for (sock1=intrfc->if_sklist; ++ (sock1 != NULL) && ++ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection); ++ sock1=sock1->next);; ++ } ++ } ++ if (sock1 == NULL) + sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + + /* +@@ -1628,6 +1642,7 @@ + sizeof(sk->protinfo.af_ipx.dest_addr)); + sk->protinfo.af_ipx.port = 0; + sk->protinfo.af_ipx.ncp_server = 0; ++ sk->protinfo.af_ipx.ipx_ncp_conn = 0; /* no ncp socket yet */ + sk->mtu=IPX_MTU; + + if(sock!=NULL) +@@ -2128,6 +2143,17 @@ + if(err) return err; + return(ipxcfg_get_config_data((void *)arg)); + } ++ ++ case SIOCIPXNCPCONN: ++ { ++ if (!suser()) return(-EPERM); ++ err = verify_area(VERIFY_READ, (void *)arg, ++ sizeof(unsigned short)); ++ if (err) return err; ++ sk->protinfo.af_ipx.ipx_ncp_conn = get_fs_word(arg); ++ return 0; ++ } ++ + case SIOCGSTAMP: + if (sk) + { diff --git a/examples/nw.ini b/examples/nw.ini index 59b18ef..55eb533 100644 --- a/examples/nw.ini +++ b/examples/nw.ini @@ -50,21 +50,24 @@ # that it is a 3.11 Server, although many calls # (namespace services) of a real 3.11 Server are missing yet. # simple namespace services are implemented for testing -# since V 0.96pl8. To test them, this entry must be set to '1'. -# and config.h must be altered to allow namespace calls. +# since V 0.96pl8. To test them, this entry must be set to > 0. +# and config.h must be altered to compile in namespace calls. 6 0 # tells server version: 0=2.15, 1=3.11, 2=3.12 +###################################### # Password handling 7 0 # 0 = use only encrypted passwords stuff (default) # 1 = allow the unencrypted change password routine. - # 8 = allow all unencrypted stuff. + # 7 = allow all unencrypted stuff, no empty nwe passwords. + # 8 = allow all unencrypted stuff, allow empty nwe passwords. # 9 = use all unencryted calls + get crypt key will allways fail # so the login program will use the old unencryted calls. + # this will *not* work with all clients !! (OS2/client) ###################################### # GID and UID for _minimal_ rights # will be used for not logins or not assigned mars_nwe users. 10 200 # GID 11 201 # UID -############################# +###################################### # the following passwords should be removed after the first # start, because these entries will be inserted (crypted) into # the bindery. If you specify a password here, then this password @@ -81,7 +84,7 @@ # Read UnixUsers automaticly from passwd into bindery # switch password 15 0 secure11 -# ^^^ 0=off (default), 1=on, 99=overwrite existing users. +# ^^^ 0=off (default), 1=on, 99=overwrite existing mars_nwe users. # !!! IMPORTANT !!! # If you enable this feature you should chose a secure # password for the users, because all not existent @@ -102,6 +105,7 @@ 102 0 # debug NCPSERV 103 0 # debug NWCONN 104 0 # debug (start) NWCLIENT +105 0 # debug NWBIND ############################# 200 1 # 0 = no logfile and dont daemonize nwserv # # 1 = daemonize nwserv and use logfile diff --git a/makefile.unx b/makefile.unx index 32b0ae4..c82a02a 100644 --- a/makefile.unx +++ b/makefile.unx @@ -1,5 +1,5 @@ #if 0 -#makefile.unx 10-Mar-96 +#makefile.unx 15-Mar-96 #endif VPATH=$(V_VPATH) @@ -9,7 +9,7 @@ C=.c V_H=0 V_L=97 -P_L=1 +P_L=2 #define D_P_L 1 DISTRIB=mars_nwe @@ -62,6 +62,7 @@ PROG2=nwserv PROG3=nwconn PROG4=ncpserv PROG5=nwclient +PROG6=nwbind #include "config.h" #ifdef FILENAME_NW_INI @@ -91,17 +92,18 @@ NWROUTE_O=nwroute1$(O) NWROUTE_O=nwroute1$(O) #endif -PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) +PROGS=$(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) OBJ1= $(EMUTLIOBJ) net1$(O) tools$(O) OBJ2= $(OBJ1) $(NWROUTE_O) OBJ3= $(OBJ1) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) -OBJ4= $(OBJ1) nwdbm$(O) nwcrypt$(O) +OBJ4= $(OBJ1) OBJ5= $(OBJ1) +OBJ6= $(OBJ1) nwdbm$(O) nwcrypt$(O) OBJS= net1$(O) tools$(O) connect$(O) nwdbm$(O) $(NWROUTE_O) \ namspace$(O) nwvolume$(O) \ - $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) + $(PROG2)$(O) $(PROG3)$(O) $(PROG4)$(O) $(PROG5)$(O) $(PROG6)$(O) HOBJ3= $(PROG3)$(O) connect$(O) namspace$(O) nwvolume$(O) nwfile$(O) @@ -120,11 +122,15 @@ $(PROG3): $(PROG3)$(O) $(OBJ3) $(CC) -o $(VPATH)/$(PROG3) $(PROG3)$(O) $(OBJ3) $(NSLLIB) $(PROG4): $(PROG4)$(O) $(OBJ4) - $(CC) -o $(VPATH)/$(PROG4) $(PROG4)$(O) $(OBJ4) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) + $(CC) -o $(VPATH)/$(PROG4) $(PROG4)$(O) $(OBJ4) $(NSLLIB) $(PROG5): $(PROG5)$(O) $(OBJ5) $(CC) -o $(VPATH)/$(PROG5) $(PROG5)$(O) $(OBJ5) $(NSLLIB) +$(PROG6): $(PROG6)$(O) $(OBJ6) + $(CC) -o $(VPATH)/$(PROG6) $(PROG6)$(O) $(OBJ6) $(NDBMLIB) $(CRYPTLIB) $(NSLLIB) + + $(HOBJ3): namspace.h connect.h nwvolume.h nwfile.h $(OBJS): net.h config.h diff --git a/ncpserv.c b/ncpserv.c index f48f07d..399312d 100644 --- a/ncpserv.c +++ b/ncpserv.c @@ -1,5 +1,4 @@ -/* ncpserv.c */ -#define REVISION_DATE "14-Mar-96" +/* ncpserv.c 20-Mar-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -18,14 +17,9 @@ */ #include "net.h" -#include "nwdbm.h" - -#if !CALL_NCPSERV_OVER_SOCKET -static struct pollfd polls[2]; -#endif static int ncp_fd = -1; -static uint8 ipx_in_data[IPX_MAX_DATA+500]; /* space for additional data */ +static uint8 ipx_in_data[IPX_MAX_DATA]; static NCPREQUEST *ncprequest = (NCPREQUEST*)&ipx_in_data; static struct t_unitdata ud; static int in_len=0; @@ -38,6 +32,26 @@ static time_t akttime; static int server_goes_down=0; static int ipx_out_fd=-1; +static int tells_server_version=0; +static int sock_nwbind=-1; + + +static int get_ini(void) +{ + FILE *f = open_nw_ini(); + if (f){ + uint8 buff[256]; + int what; + while (0 != (what =get_ini_entry(f, 0, buff, sizeof(buff)))) { + if (6 == what) { /* Server Version */ + tells_server_version = atoi((char*)buff); + } + } /* while */ + fclose(f); + } + return(0); +} + /* next should be '1', is for testing only */ #define USE_PERMANENT_OUT_SOCKET 1 @@ -49,7 +63,7 @@ static void write_to_nwserv(int what, int connection, int mode, write(FD_NWSERV, &what, sizeof(int)); write(FD_NWSERV, &connection, sizeof(int)); write(FD_NWSERV, &size, sizeof(int)); - write(FD_NWSERV, data, size); /* ipxAddr_t */ + write(FD_NWSERV, data, size); /* ipxAddr_t + socknr */ break; case 0x4444 : /* tell the wdog there's no need to look 0 */ @@ -61,6 +75,7 @@ static void write_to_nwserv(int what, int connection, int mode, write(FD_NWSERV, &mode, sizeof(int)); break; + case 0x5555 : /* close connection */ case 0x6666 : /* send to client that server holds message */ write(FD_NWSERV, &what, sizeof(int)); write(FD_NWSERV, &connection, sizeof(int)); @@ -75,8 +90,8 @@ static void write_to_nwserv(int what, int connection, int mode, } } -#define nwserv_insert_wdog(connection, adr) \ - write_to_nwserv(0x2222, (connection), 0, (adr), sizeof(ipxAddr_t)) +#define nwserv_insert_conn(connection, adr, size) \ + write_to_nwserv(0x2222, (connection), 0, (adr), (size)) #define nwserv_handle_wdog(connection, mode) \ write_to_nwserv(0x4444, (connection), (mode), NULL, 0) @@ -84,8 +99,8 @@ static void write_to_nwserv(int what, int connection, int mode, #define nwserv_reset_wdog(connection) \ write_to_nwserv(0x4444, (connection), 0, NULL, 0) -#define nwserv_close_wdog(connection) \ - write_to_nwserv(0x4444, (connection), 99, NULL, 0) +#define nwserv_close_conn(connection) \ + write_to_nwserv(0x5555, (connection), 0, NULL, 0) #define nwserv_handle_msg(connection) \ write_to_nwserv(0x6666, (connection), 0, NULL, 0) @@ -93,7 +108,7 @@ static void write_to_nwserv(int what, int connection, int mode, #define nwserv_down_server() \ write_to_nwserv(0xffff, 0, 0, NULL, 0) -static int open_ipx_sockets() +static int open_ipx_sockets(void) { struct t_bind bind; ncp_fd=t_open("/dev/ipx", O_RDWR, NULL); @@ -105,7 +120,7 @@ static int open_ipx_sockets() bind.addr.len = sizeof(ipxAddr_t); bind.addr.maxlen = sizeof(ipxAddr_t); bind.addr.buf = (char*)&my_addr; - bind.qlen = 0; /* immer */ + bind.qlen = 0; /* ever 0 */ if (t_bind(ncp_fd, &bind, &bind) < 0){ t_error("t_bind in open_ipx_sockets !OK"); close(ncp_fd); @@ -130,64 +145,40 @@ static int open_ipx_sockets() typedef struct { int fd; /* writepipe */ /* or if CALL_NWCONN_OVER_SOCKET then sock_nr of nwconn */ - int pid; /* pid from son */ ipxAddr_t client_adr; /* address client */ - uint32 object_id; /* logged object */ - /* 0 = not logged in */ - uint8 crypt_key[8]; /* password generation */ - uint8 message[60]; /* saved BCastmessage */ int sequence; /* previous sequence */ int retry; /* one reply being serviced is sent */ time_t last_access; /* time of last 0x2222 request */ - time_t t_login; /* login time */ } CONNECTION; static CONNECTION connections[MAX_CONNECTIONS]; -static int anz_connect=0; /* actual anz connections */ +static int anz_connect=0; /* actual count connections */ static int new_conn_nr(void) { int j = -1; - int one_found=0; if (!anz_connect){ /* init all */ j = MAX_CONNECTIONS; while (j--) { connections[j].fd = -1; connections[j].pid = -1; - connections[j].message[0] = '\0'; } anz_connect++; return(1); } - j = -1; while (++j < MAX_CONNECTIONS) { CONNECTION *c=&(connections[j]); if (c->fd < 0 && c->pid < 0) { - c->message[0] = '\0'; if (++j > anz_connect) anz_connect=j; return(j); } } - /* nothing free */ - j=MAX_CONNECTIONS; - while (j-- && one_found < 3) { - CONNECTION *c=&(connections[j]); - if (!c->object_id) { /* NOT LOGGED IN */ - /* makes wdog test faster */ - nwserv_handle_wdog(j+1, 1); - one_found++; - } - } - - if (!one_found) { - j=0; - while (j++ < MAX_CONNECTIONS) - nwserv_handle_wdog(j, 2); /* slow activate wdog */ - } - + j=0; + while (j++ < MAX_CONNECTIONS) + nwserv_handle_wdog(j, 2); /* slow activate wdog */ return(0); /* nothing free */ } @@ -214,7 +205,7 @@ static int find_conn_nr(ipxAddr_t *addr) static void clear_connection(int conn) { - nwserv_close_wdog(conn); + nwserv_close_conn(conn); if (conn > 0 && --conn < anz_connect) { CONNECTION *c = &connections[conn]; if (c->fd > -1) { @@ -224,7 +215,6 @@ static void clear_connection(int conn) c->fd = -1; if (c->pid > -1) kill(c->pid, SIGTERM); /* kill it */ } - c->object_id = 0; } } @@ -237,11 +227,10 @@ static void kill_connections(void) while ((pid=waitpid(-1, &stat_loc, WNOHANG)) > 0) { conn = anz_connect; while (conn--) { - CONNECTION *c = &connections[conn]; - if (c->pid == pid) clear_connection(conn+1); + if (connections[conn].pid == pid) clear_connection(conn+1); } } - conn = anz_connect; + conn = anz_connect; while (conn--) { CONNECTION *c = &connections[conn]; if (c->fd < 0 && c->pid > -1) { @@ -249,7 +238,7 @@ static void kill_connections(void) c->pid = -1; } } - conn = anz_connect; + conn = anz_connect; while (conn--) { CONNECTION *c = &connections[conn]; if (c->fd < 0 && c->pid < 0) anz_connect--; @@ -260,15 +249,11 @@ static void kill_connections(void) static int find_get_conn_nr(ipxAddr_t *addr) { int connection=find_conn_nr(addr); -#if 0 - if (connection) { - clear_connection(connection); - connection=0; - } -#endif + if (!connection){ if ((connection = new_conn_nr()) > 0){ CONNECTION *c=&(connections[connection-1]); + #if !CALL_NWCONN_OVER_SOCKET int fds[2]; memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t)); @@ -283,7 +268,7 @@ static int find_get_conn_nr(ipxAddr_t *addr) memcpy((char*) &(c->client_adr), (char *)addr, sizeof(ipxAddr_t)); ipx_fd=t_open("/dev/ipx", O_RDWR, NULL); if (ipx_fd > -1) { - U16_TO_BE16(0, my_addr.sock); /* actual write socket */ + U16_TO_BE16(SOCK_AUTO, my_addr.sock); /* actual write socket */ bind.addr.len = sizeof(ipxAddr_t); bind.addr.maxlen = sizeof(ipxAddr_t); bind.addr.buf = (char*)&my_addr; @@ -292,17 +277,11 @@ static int find_get_conn_nr(ipxAddr_t *addr) if (nw_debug) t_error("t_bind !OK"); t_close(ipx_fd); ipx_fd = -1; - } else { - ; -#if 0 - t_unbind(ipx_fd); - t_close(ipx_fd); - ipx_fd = (int) GET_BE16(my_addr.sock); -#endif } } else { if (nw_debug) t_error("t_open !Ok"); } + if (ipx_fd < 0) { errorp(0, "find_get_conn_nr, socket", NULL); free_conn_nr(connection); @@ -314,6 +293,7 @@ static int find_get_conn_nr(ipxAddr_t *addr) if (pid < 0) { errorp(0, "find_get_conn_nr, fork", NULL); free_conn_nr(connection); + #if !CALL_NWCONN_OVER_SOCKET close(fds[0]); close(fds[1]); @@ -328,7 +308,9 @@ static int find_get_conn_nr(ipxAddr_t *addr) char pidstr[20]; char connstr[20]; char addrstr[100]; - int j = 2; + char nwbindsock[20]; + + int j = 3; #if !CALL_NWCONN_OVER_SOCKET close(fds[1]); /* no writing */ dup2(fds[0], 0); /* becomes stdin */ @@ -337,17 +319,22 @@ static int find_get_conn_nr(ipxAddr_t *addr) dup2(ipx_fd, 0); /* becomes stdin */ close(ipx_fd); #endif - while (j++ < 100) close(j); /* close all > stderr */ + + dup2(ncp_fd, 3); /* becomes 3 */ + while (j++ < 100) close(j); /* close all > 3 */ sprintf(pidstr, "%d", akt_pid); sprintf(connstr, "%d", connection); ipx_addr_to_adr(addrstr, addr); + sprintf(nwbindsock, "%04x", sock_nwbind); execl(get_exec_path(pathname, progname), progname, - pidstr, addrstr, connstr, NULL); + pidstr, addrstr, connstr, nwbindsock, NULL); + exit(1); /* normaly not reached */ } c->pid = pid; + #if CALL_NWCONN_OVER_SOCKET c->fd = (int) GET_BE16(my_addr.sock); close(ipx_fd); @@ -359,37 +346,21 @@ static int find_get_conn_nr(ipxAddr_t *addr) } } } - if (connection) nwserv_insert_wdog(connection, (char*)addr); + if (connection) { + uint8 buff[sizeof(ipxAddr_t)+sizeof(uint16)]; + memcpy(buff, addr, sizeof(ipxAddr_t)); +#if CALL_NWCONN_OVER_SOCKET + /* here i can use the nwconn socket */ + U16_TO_BE16(connections[connection-1].fd, buff+sizeof(ipxAddr_t)); +#else + /* and in this mode all must be go over ncpserv */ + U16_TO_BE16(SOCK_NCP, buff+sizeof(ipxAddr_t)); +#endif + nwserv_insert_conn(connection, (char*)buff, sizeof(buff)); + } return(connection); } -static void sent_down_message(void) -{ - int k = -1; - server_goes_down++; - while (++k < anz_connect) { - CONNECTION *cn=&connections[k]; - if (cn->fd > -1) { - strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58); - nwserv_handle_msg(k+1); - } - } /* while */ -} - -static void get_login_time(uint8 login_time[], CONNECTION *cx) -{ - struct tm *s_tm = localtime(&(cx->t_login)); - - login_time[0] = s_tm->tm_year; - login_time[1] = s_tm->tm_mon+1; - login_time[2] = s_tm->tm_mday; - - login_time[3] = s_tm->tm_hour; - login_time[4] = s_tm->tm_min; - login_time[5] = s_tm->tm_sec; - login_time[6] = s_tm->tm_wday; -} - #if CALL_NWCONN_OVER_SOCKET static void send_to_nwconn(int nwconn_sock, char *data, int size) { @@ -401,982 +372,6 @@ static void send_to_nwconn(int nwconn_sock, char *data, int size) #endif -static int handle_fxx(CONNECTION *c, int gelen, int func) -/* here are handled the global 0x15, 0x17, 0x57 functions */ -{ - IPX_DATA ipxoutdata; - NCPRESPONSE *ncpresponse = (NCPRESPONSE*)&ipxoutdata; - uint8 *responsedata = ((uint8*)&ipxoutdata)+sizeof(NCPRESPONSE); - uint8 *requestdata = ((uint8*)ncprequest)+sizeof(NCPREQUEST); -#if 0 - uint8 len = *(requestdata+1); -#endif - uint8 ufunc = *(requestdata+2); - uint8 *rdata = requestdata+3; - uint8 completition = 0; - uint8 connect_status= 0; - int data_len = 0; - - if (nw_debug > 1){ - int j = gelen - sizeof(NCPREQUEST); - if (nw_debug){ - XDPRINTF((1, 0, "NCP 0x%x REQUEST:ufunc:0x%x", func, ufunc)); - if (j > 0){ - uint8 *p=requestdata; - XDPRINTF((1, 2, "len %d, DATA:", j)); - while (j--) { - int c = *p++; - if (c > 32 && c < 127) XDPRINTF((1, 3, ",\'%c\'", (char) c)); - else XDPRINTF((1, 3, ",0x%x", c)); - } - XDPRINTF((1, 1, NULL)); - } - } - } - - if (0x15 == func) { - switch (ufunc) { /* Messages */ - case 0x0 : { /* Send Broadcast Message (old) */ - int anz_conns = (int)*(rdata); /* Number of connections */ - uint8 *conns = rdata+1; /* connectionslist */ - int msglen = *(conns+anz_conns); - uint8 *msg = conns+anz_conns+1; - uint8 *p = responsedata; - int one_found = 0; - int k = -1; - *p++ = (uint8) anz_conns; - while (++k < anz_conns) { - int connr = (int) (*conns++); - int result = 0xff; /* target not ok */ - CONNECTION *cn; - if (connr > 0 && --connr < anz_connect - && ((cn = &connections[connr]))->fd > -1 ) { - if (!cn->message[0]) { - strmaxcpy(cn->message, msg, min(58, msglen)); - result = 0; /* Ok */ - } else result = 0xfc; /* server holds message */ - nwserv_handle_msg(connr+1); - one_found++; - } - *p++ = (uint8)result; - } - if (one_found) data_len = anz_conns+1; - else completition=0xff; - } - break; - - case 0x01: { /* Get Broadcast Message (old) */ - *responsedata = (uint8) strmaxcpy(responsedata+1, c->message, 58); - c->message[0] = '\0'; - data_len = (int)(*responsedata) + 1; - } - break; - - case 0x03: { /* Enable Broadcasts */ - ;;; - XDPRINTF((2, 0, "TODO: enable Broadcasts")); - } - break; - - case 0x09: { /* Broadcast to CONSOLE */ - char message[60]; - strmaxcpy(message, rdata+1, min(59, *rdata)); - fprintf(stderr, "\n:%s\n", message); - } - break; - - case 0xa: /* Send Broadcast Message (new) */ - case 0xb: /* Get Broadcast Message (new) */ - default : return(-1); /* not handled */ - } /* switch */ - } else if (0x17 == func) { /* Fileserver Enviro */ - switch (ufunc) { - case 0x01 : { /* Change User Password OLD */ - completition=0xff; - } - break; - -#if FUNC_17_02_IS_DEBUG - case 0x02 : { /* I hope this is call isn't used */ - /* now missused as a debug switch :) */ - struct XDATA { - uint8 nw_debug; /* old level */ - } *xdata = (struct XDATA*) responsedata; - errorp(2, "0x17, ufunc=2", "Got debugchange =%d for module=%d", - (int)*(rdata+1), (int) *rdata); - if (*rdata == NWCONN) - return(-1); /* let nwconn do the call */ - - if (*rdata == NCPSERV) { - xdata->nw_debug = (uint8) nw_debug; - nw_debug = (int) *(rdata+1); - data_len = 1; - } else completition=0xff; - } - break; -#endif - - case 0x0c : { /* Verify Serialization */ - completition=0xff; - } - break; - - case 0x0e : { /* Get Disk Utilization */ - completition=0xff; - } - break; - - case 0x11 : { /* Get FileServer Info */ - struct XDATA { - uint8 servername[48]; - uint8 version; /* 2 or 3 */ - uint8 subversion; /* 15 or 11 */ - uint8 maxconnections[2]; - uint8 connection_in_use[2]; - uint8 max_volumes[2]; - uint8 os_revision; - uint8 sft_level; - uint8 tts_level; - uint8 peak_connection[2]; - uint8 accounting_version; - uint8 vap_version; - uint8 queuing_version; - uint8 print_server_version; - uint8 virtual_console_version; - uint8 security_level; - uint8 internet_bridge_version; - uint8 reserved[60]; - } *xdata = (struct XDATA*) responsedata; - int k, i; - memset(xdata, 0, sizeof(struct XDATA)); - strcpy(xdata->servername, my_nwname); - - if (!tells_server_version) { - xdata->version = 2; - xdata->subversion = 15; - } else { - xdata->version = 3; - xdata->subversion = (tells_server_version == 2) - ? 12 - : 11; - } - - i=0; - for (k=0; k < anz_connect; k++) { - if (connections[k].fd > -1) i++; - } - U16_TO_BE16(i, xdata->connection_in_use); - U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections); - U16_TO_BE16(anz_connect, xdata->peak_connection); - U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes); - data_len = sizeof(struct XDATA); - } break; - - case 0x12 : { /* Get Network Serial Number */ - struct XDATA { - uint8 serial_number[4]; - uint8 appl_number[2]; - } *xdata = (struct XDATA*) responsedata; - /* serial-number 4-Byte */ - U32_TO_BE32(NETWORK_SERIAL_NMBR, xdata->serial_number); - /* applikation-number 2-Byte */ - U16_TO_BE16(NETWORK_APPL_NMBR, xdata->appl_number); - data_len = sizeof(struct XDATA); - } - break; - - case 0x13 : { /* Get Connection Internet Address */ - int conn = (int)*(rdata); /* Connection Nr */ - if (conn && --conn < anz_connect - && connections[conn].fd > -1 ) { - CONNECTION *cx=&(connections[conn]); - data_len = sizeof(ipxAddr_t); - memcpy(responsedata, (char*)&(cx->client_adr), data_len); - } else completition = 0xff; - } break; - - case 0x14 : { /* Login Objekt, unencrypted passwords */ - uint8 *p = rdata; - uint8 *p1 = p+3 + *(p+2); /* here is password */ - int result; - NETOBJ obj; - char password[80]; - obj.type = GET_BE16(p); - xstrmaxcpy(obj.name, p+3, (int) *(p+2)); - upstr(obj.name); - xstrmaxcpy(password, p1+1, (int) *p1); - XDPRINTF((10, 0, "LOGIN unencrypted PW NAME='%s', PASSW='%s'", - obj.name, password)); - if (0 == (result = find_obj_id(&obj, 0))) { - if (password_scheme & PW_SCHEME_LOGIN) { -#if 0 - if (obj.id == 1) { - result=-0xff; /* SUPERVISOR ever encryted !! */ - XDPRINTF((1, 0, "Supervisor tried unencrypted LOGIN")); - } else -#endif - result=nw_test_unenpasswd(obj.id, password); - } else { - XDPRINTF((1, 0, "unencryted logins are not enabled")); - result=-0xff; - } - } - if (!result) { - c->object_id = obj.id; /* actuell Object ID */ - c->t_login = akttime; /* u. login Time */ - get_guid((int*) (rdata+2), (int*) (rdata+2+sizeof(int)), obj.id); - in_len=12 + 2*sizeof(int); - return(-1); /* nwconn must do the rest */ - } else completition = (uint8) -result; - } break; - - case 0x15 : { /* Get Object Connection List */ - uint8 *p = rdata; - int result; - NETOBJ obj; - obj.type = GET_BE16(p); - p+=2; - strmaxcpy((char*)obj.name, (char*)(p+1), (int) *(p)); - upstr(obj.name); - result = find_obj_id(&obj, 0); - if (!result){ - int k=-1; - int anz = 0; - p = responsedata+1; - while (++k < anz_connect && anz < 255) { - CONNECTION *cn= &connections[k]; - if (cn->fd > -1 && cn->object_id == obj.id) { - *p++=(uint8)k+1; - anz++; - } - } /* while */ - *responsedata = anz; - data_len = 1 + anz; - } else completition=(uint8)-result; - } - break; - - case 0x16 : { /* Get Connection Info, OLD */ - struct XDATA { - uint8 object_id[4]; - uint8 object_type[2]; - uint8 object_name[48]; - uint8 login_time[7]; - uint8 reserved; - } *xdata = (struct XDATA*) responsedata; - int conn = (uint16)*(rdata); /* Connection Nr */ - memset(xdata, 0, sizeof(struct XDATA)); - data_len = sizeof(struct XDATA); - if (conn && conn <= anz_connect - && connections[conn-1].fd > -1 ) { - CONNECTION *cx=&(connections[conn-1]); - NETOBJ obj; - int result; - obj.id = cx->object_id; - result = nw_get_obj(&obj); - if (!result) { - memset(xdata, 0, sizeof(struct XDATA)); - U32_TO_BE32(obj.id, xdata->object_id); - U16_TO_BE16(obj.type, xdata->object_type); - strncpy(xdata->object_name, obj.name, 48); - get_login_time(xdata->login_time, cx); - } /* else completition = (uint8)(-result); */ - } else if (!conn || conn > MAX_CONNECTIONS) { - data_len = 0; - completition = 0xfd; - } - } break; - - case 0x17 : { /* get crypt key */ - int k = sizeof(c->crypt_key); - uint8 *p = c->crypt_key; - uint8 *pp = responsedata; - data_len = k; - while (k--) *pp++ = *p++ = -#ifndef _MAR_TESTS_ - (uint8) rand(); -#else - (uint8) k; -#endif - /* if all here are same (1 or 2) then the resulting key is */ - /* 00000000 */ - if (password_scheme & PW_SCHEME_GET_KEY_FAIL) - completition=0xfb; - } - break; - - case 0x18 : { /* crypt_keyed LOGIN */ - uint8 *p = rdata+sizeof(c->crypt_key); - NETOBJ obj; - int result; - obj.type = GET_BE16(p); - obj.id = 0; - 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))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); - if (result > -1) { - c->object_id = obj.id; /* actuell Object */ - c->t_login = akttime; /* and login time */ - get_guid((int*)(rdata+2), (int*)(rdata+2+sizeof(int)), obj.id); - in_len=12 + 2*sizeof(int); - return(-1); /* nwconn must do the rest */ - } else { - 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 */ - completition = (uint8) -result; - } - } - break; - - case 0x1c : { /* Get Connection Info, new */ - struct XDATA { - uint8 object_id[4]; - uint8 object_type[2]; - uint8 object_name[48]; - uint8 login_time[7]; - uint8 reserved; - } *xdata = (struct XDATA*) responsedata; - int conn = (uint16)*(rdata); /* Connection Nr */ - if (conn && --conn < anz_connect){ - CONNECTION *cx=&(connections[conn]); - NETOBJ obj; - int result; - obj.id = cx->object_id; - result = nw_get_obj(&obj); - if (!result) { - memset(xdata, 0, sizeof(struct XDATA)); - U32_TO_BE32(obj.id, xdata->object_id); - U16_TO_BE16(obj.type, xdata->object_type); - strncpy(xdata->object_name, obj.name, 48); - get_login_time(xdata->login_time, cx); - data_len = sizeof(struct XDATA); - } else completition = (uint8)(-result); - } else completition = 0xff; - } break; - - - case 0x32 : { /* Create Bindery Object */ - NETOBJ obj; - int result; - uint8 *p = rdata; - obj.flags = *p++; - obj.security = *p++; - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)p+3, (int) *(p+2)); - result = nw_create_obj(&obj, 0); - if (result < 0) completition = (uint8) -result; - } break; - - case 0x33 : { /* delete OBJECT */ - uint8 *p = rdata; - int result; - NETOBJ obj; - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); - result = nw_delete_obj(&obj); - if (result < 0) completition = (uint8) -result; - } break; - - case 0x34 : { /* rename OBJECT, only SU */ - int result=-0xff; - if (1 == c->object_id) { - uint8 *p = rdata; - NETOBJ obj; - uint8 newname[256]; - uint8 *p1 = p+3 + *(p+2); /* new Name Length */ - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); - strmaxcpy((char*)newname, (char*)(p1+1), (int) *(p1)); - result = nw_rename_obj(&obj, newname); - } - if (result) completition = (uint8) -result; - } break; - - - case 0x35 : { /* get Bindery Object ID */ - struct XDATA { - uint8 object_id[4]; - uint8 object_type[2]; - uint8 object_name[48]; - } *xdata = (struct XDATA*) responsedata; - uint8 *p = rdata; - int result; - NETOBJ obj; - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); - upstr(obj.name); - result = find_obj_id(&obj, 0); - if (!result){ - U32_TO_BE32(obj.id, xdata->object_id); - U16_TO_BE16(obj.type, xdata->object_type); - strncpy(xdata->object_name, obj.name, 48); - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } break; - - case 0x36 : { /* get Bindery Object Name */ - struct XDATA { - uint8 object_id[4]; - uint8 object_type[2]; - uint8 object_name[48]; - } *xdata = (struct XDATA*) responsedata; - uint8 *p = rdata; - int result; - NETOBJ obj; - obj.id = GET_BE32(p); - result = nw_get_obj(&obj); - if (!result){ - U32_TO_BE32(obj.id, xdata->object_id); - U16_TO_BE16(obj.type, xdata->object_type); - strncpy(xdata->object_name, obj.name, 48); - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } break; - - case 0x37 : { /* Scan Bindery Object */ - struct XDATA { - uint8 object_id[4]; - uint8 object_type[2]; - uint8 object_name[48]; - uint8 object_flag; - uint8 object_security; - uint8 object_has_properties; - } *xdata = (struct XDATA*) responsedata; - uint32 last_obj_id = GET_BE32(rdata); - uint8 *p = rdata+4; - int result; - NETOBJ obj; - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)(p+3),(int) *(p+2)); - upstr(obj.name); - result = find_obj_id(&obj, last_obj_id); - if (!result){ - U32_TO_BE32(obj.id, xdata->object_id); - U16_TO_BE16(obj.type, xdata->object_type); - strncpy(xdata->object_name, obj.name, 48); - xdata->object_flag = obj.flags; - xdata->object_security = obj.security; - if (nw_obj_has_prop(&obj) > 0) - xdata->object_has_properties = 0xff; - else xdata->object_has_properties = 0; - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } - break; - - case 0x38 : { /* change Bindery Objekt Security */ - /* only SU ! */ - int result= -0xff; - if (1 == c->object_id) { - uint8 *p = rdata; - NETOBJ obj; - obj.type = GET_BE16(p+1); - xstrmaxcpy(obj.name, (char*)(p+4), (int) *(p+3)); - result = nw_change_obj_security(&obj, (int)*p); - } - if (result < 0) completition = (uint8) -result; - } break; - - case 0x39 : { /* create Property */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+=2); - uint8 *object_name = ++p; - int prop_flags = (int) *(p+=object_namlen); - int prop_security = (int) *(++p); - int prop_namlen = (int) *(++p); - uint8 *prop_name = ++p; - int result = nw_create_prop( object_type, - object_name, object_namlen, - prop_name, prop_namlen, - prop_flags, prop_security); - if (result) completition = (uint8) -result; - } break; - - - case 0x3a : { /* delete property */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+2); - uint8 *object_name= p+3; - int prop_namlen = (int) *(p+3+object_namlen); - uint8 *prop_name = p+4+object_namlen; - int result = nw_delete_property( object_type, - object_name, object_namlen, - prop_name, prop_namlen); - if (result < 0) completition = (uint8) -result; - } break; - - case 0x3b : { /* Change Prop Security */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+=2); - uint8 *object_name= ++p; - int prop_security = (int) *(p+=object_namlen); - int prop_namlen = (int) *(++p); - uint8 *prop_name = ++p; - int result = nw_change_prop_security(object_type, - object_name, object_namlen, - prop_name, prop_namlen, prop_security); - if (result) completition = (uint8) -result; - } break; - - case 0x3c : { /* Scan Property */ - struct XDATA { - uint8 prop_name[16]; - uint8 flags; /* set=2, dynamic=1 */ - uint8 security; - uint8 akt_scan[4]; - uint8 has_value; /* ff, if there are Prop's Values */ - uint8 weisnicht; - } *xdata = (struct XDATA*) responsedata; - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+2); - uint8 *object_name = (p+=3); - uint32 last_scan = GET_BE32((p+object_namlen)); - uint8 prop_namlen = (int)* (p+=object_namlen+4); - uint8 *prop_name = ++p; - NETPROP prop; - int result = nw_scan_property(&prop, - object_type, object_name, object_namlen, - prop_name, prop_namlen, &last_scan); - if (result > -1) { - strncpy(xdata->prop_name, - prop.name, sizeof(xdata->prop_name)); - U32_TO_BE32(last_scan, xdata->akt_scan); - xdata->flags = prop.flags; - xdata->security = prop.security; - xdata->has_value = (uint8) result; - xdata->weisnicht = 0x0; - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } break; - - case 0x3d : { /* read Bindery Property Value */ - struct XDATA { - uint8 property_value[128]; - uint8 more_segments; - uint8 property_flags; - } *xdata = (struct XDATA*) responsedata; - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+2); - uint8 *object_name= p+3; - int segment_nr = (int) *(p+3+object_namlen); - int prop_namlen = (int) *(p+4+object_namlen); - uint8 *prop_name = p+5+object_namlen; - int result = nw_get_prop_val( object_type, - object_name, object_namlen, - segment_nr, - prop_name, prop_namlen, - xdata->property_value, - &(xdata->more_segments), - &(xdata->property_flags)); - if (!result){ - data_len = sizeof(struct XDATA); - } else completition = (uint8) -result; - } break; - - case 0x3e : { /* write Bindery Property Value */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+2); - uint8 *object_name= p+3; - int segment_nr = (int) *(p+3+object_namlen); - int erase_segment = (int) *(p+4+object_namlen); - int prop_namlen = (int) *(p+5+object_namlen); - uint8 *prop_name = p+6+object_namlen; - uint8 *valdata = p+6+object_namlen+prop_namlen; - int result = nw_write_prop_value( object_type, - object_name, object_namlen, - segment_nr, erase_segment, - prop_name, prop_namlen, - valdata); - if (result) completition = (uint8) -result; - } break; - - case 0x40: { /* change object password */ - if (password_scheme & PW_SCHEME_CHANGE_PW) { - uint8 *p = rdata; - uint8 oldpassword[50]; - uint8 newpassword[50]; - NETOBJ obj; - int result; - obj.type = GET_BE16(p); - p+=2; - xstrmaxcpy(obj.name, p+1, (int) *p); - upstr(obj.name); - p += ((*p)+1); - xstrmaxcpy(oldpassword, p+1, (int) *p); - p += ((*p)+1); - xstrmaxcpy(newpassword, p+1, (int) *p); - if (0 == (result = find_obj_id(&obj, 0))) { - XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword, - newpassword)); - if (c->object_id == 1 || - 0 == (result=nw_test_unenpasswd(obj.id, oldpassword))) - result=nw_set_passwd(obj.id, newpassword, 0); - } - if (result < 0) completition = (uint8) -result; - } else { - XDPRINTF((1, 0, "Change object password unencryted not enabled")); - completition=0xff; - } - } break; - - case 0x41 : { /* add Bindery Object to Set */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+=2); - uint8 *object_name= ++p; - int prop_namlen = (int) *(p+=object_namlen); - uint8 *prop_name = ++p; - int member_type = GET_BE16(p+prop_namlen); - int member_namlen = (int) *(p+=(prop_namlen+2)); - uint8 *member_name= ++p; - int result = nw_add_obj_to_set( object_type, - object_name, object_namlen, - prop_name, prop_namlen, - member_type, - member_name, member_namlen); - if (result) completition = (uint8) -result; - } break; - - case 0x42 : { /* delete Bindery Object from Set */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+=2); - uint8 *object_name= ++p; - int prop_namlen = (int) *(p+=object_namlen); - uint8 *prop_name = ++p; - int member_type = GET_BE16(p+prop_namlen); - int member_namlen = (int) *(p+=(prop_namlen+2)); - uint8 *member_name= ++p; - int result = nw_delete_obj_from_set( object_type, - object_name, object_namlen, - prop_name, prop_namlen, - member_type, - member_name, member_namlen); - if (result) completition = (uint8) -result; - } break; - - case 0x43 : { /* is Bindery Object in Set */ - uint8 *p = rdata; - int object_type = GET_BE16(p); - int object_namlen = (int) *(p+=2); - uint8 *object_name= ++p; - int prop_namlen = (int) *(p+=object_namlen); - uint8 *prop_name = ++p; - int member_type = GET_BE16(p+prop_namlen); - int member_namlen = (int) *(p+=(prop_namlen+2)); - uint8 *member_name= ++p; - int result = nw_is_obj_in_set( object_type, - object_name, object_namlen, - prop_name, prop_namlen, - member_type, - member_name, member_namlen); - if (result) completition = (uint8) -result; - } break; - - - case 0x44 : { /* CLOSE BINDERY */ - ; - } break; - - case 0x45 : { /* OPEN BINDERY */ - ; - } break; - - - case 0x46 : { /* GET BINDERY ACCES LEVEL */ -#if 0 - struct XDATA { - uint8 acces_level; - uint8 object_id[4]; - } *xdata = (struct XDATA*) responsedata; -#else - uint8 *xdata = responsedata; -#endif - - NETOBJ obj; - obj.id = c->object_id; - if (0 != obj.id) { - int result = nw_get_obj(&obj); - if (!result) { - *xdata = obj.security; - U32_TO_BE32(obj.id, (xdata+1)); - XDPRINTF((2,0, "ACCESS LEVEL:=0x%x, obj=0x%lx", - (int) obj.security, obj.id)); - data_len = 5; - } else completition = (uint8)-result; - } else { - *xdata = 0; - memset(xdata+1, 0xff, 4); - data_len = 5; - } - } - break; - - - case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */ - /* TODO !!! */ - completition = (uint8)0xff; - } - break; - - case 0x48 : { /* GET BINDERY ACCES LEVEL from OBJECT ??? */ - struct XDATA { - uint8 acces_level; - } *xdata = (struct XDATA*) responsedata; - NETOBJ obj; - int result; - obj.id = GET_BE32(rdata); - result = nw_get_obj(&obj); - if (!result) { - xdata->acces_level = obj.security; - data_len = sizeof(struct XDATA); - } else completition = (uint8)-result; - } - break; - - case 0x49 : { /* IS CALLING STATION A MANAGER */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - /* TODO !! */ - completition = 0; /* here allways Manager */ - /* not manager, then completition = 0xff */ - } - break; - - case 0x4a : { /* keyed verify password */ - uint8 *p = rdata+sizeof(c->crypt_key); - NETOBJ obj; - int result; - obj.type = GET_BE16(p); - strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2)); - upstr(obj.name); - if (0 == (result = find_obj_id(&obj, 0))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); - if (result < 0) completition = (uint8) -result; - XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', result=%d", - obj.name, result)); - } - break; - -#ifdef _CHANGE_PASSWD_TESTING_ - case 0x4b : { /* keyed change pasword */ - uint8 *p = rdata+sizeof(c->crypt_key); - NETOBJ obj; - int result; - obj.type = GET_BE16(p); - p+=2; - strmaxcpy((char*)obj.name, (char*)(p+1), *p); - upstr(obj.name); - p += (*p+1); /* here is now password-type ?? 0x60,0x66 */ - - if (0 == (result = find_obj_id(&obj, 0))) - result=nw_test_passwd(obj.id, c->crypt_key, rdata); -#if 0 - if (result > -1) - result=nw_set_enpasswd(obj.id, p+1); -#endif - if (result< 0) completition = (uint8) -result; - XDPRINTF((1, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", - obj.name, result)); - } - break; -#endif - - case 0x4c : { /* List Relations of an Object */ - XDPRINTF((1, 0, "TODO:List Relations of an Object")); - completition=0xfb; - } break; - - case 0x64 : { /* Create Queue */ - XDPRINTF((1, 0, "TODO:Create QUEUE ??")); - } break; - - case 0x66 : { /* Read Queue Current Status */ - /* !!!!!! TO DO */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - XDPRINTF((1, 0, "TODO:READ QUEUE STATUS of Q=0x%lx", obj.id)); - completition=0xd5; /* no Queue Job */ - }break; - - case 0x6A : /* Remove Job from Queue OLD */ - case 0x80 : { /* Remove Job from Queue NEW */ - NETOBJ obj; - uint32 jobnr = (ufunc == 0x6A) - ? GET_BE16(rdata+4) - : GET_BE32(rdata+4); - obj.id = GET_BE32(rdata); - XDPRINTF((1, 0, "TODO:Remove Job=%ld from Queue Q=0x%lx", jobnr, obj.id)); - completition=0xd5; /* no Queue Job */ - }break; - - case 0x6B : { /* Get Queue Job List, old */ - /* !!!!!! TO DO */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - XDPRINTF((1, 0, "TODO:GET QUEUE JOB LIST von Q=0x%lx", obj.id)); - completition=0xd5; /* no Queue Job */ - }break; - - case 0x6C : { /* Get Queue Job Entry */ - /* !!!!!! TODO */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - XDPRINTF((1, 0, "TODO: GET QUEUE JOB ENTRY von Q=0x%lx", obj.id)); - completition=0xd5; /* no Queue Job */ - }break; - - case 0x68: /* creat queue job and file old */ - case 0x79: { /* creat queue job and file new */ - uint32 q_id = GET_BE32(rdata); - uint8 *dir_name = rdata+4+280+1; - int result = nw_get_q_dirname(q_id, dir_name); - if (result > -1) { - *(dir_name-1) = result; - in_len = 295 + result; - return(-1); /* nwconn must do the rest !!!!! */ - } else completition = (uint8) -result; - } - break; - - - case 0x69: /* close file and start queue old ?? */ - case 0x7f: { /* close file and start queue */ - uint32 q_id = GET_BE32(rdata); - uint8 *prc = rdata+4+4+1; - int result = nw_get_q_prcommand(q_id, prc); - if (result > -1) { - *(prc-1) = result; - in_len = 19 + result; - return(-1); /* nwconn must do the rest !!!!! */ - } else completition = (uint8) -result; - } - break; - - - case 0x7d : { /* Read Queue Current Status, new */ - NETOBJ obj; - obj.id = GET_BE32(rdata); - XDPRINTF((1, 0, "TODO:READ QUEUE STATUS NEW of Q=0x%lx", obj.id)); - completition=0xd5; /* no Queue Job */ - }break; - - case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ - XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); - /* !!!!!! TODO completition=0xc6 (no rights) */ - } break; - - case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */ - char *company = "Mars :-)"; - char *revision = "Version %d.%d"; - char *revision_date = REVISION_DATE; - char *copyright = "(C)opyright Martin Stover"; - int k=strlen(company)+1; - int l; - memset(responsedata, 0, 512); - strcpy(responsedata, company); - - l = 1 + sprintf(responsedata+k, revision, - _VERS_H_, _VERS_L_ ); -#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); - k += (strlen(copyright)+1); - data_len = k; - } break; - - case 0xcd : { /* GET FILE SERVER LOGIN STATUS */ - struct XDATA { - uint8 login_allowed; /* 0 NO , 1 YES */ - } *xdata = (struct XDATA*) responsedata; - xdata->login_allowed = 1; - data_len = 1; - } - break; - - case 0xd1 : /* Send Console Broadcast (old) */ - { - uint8 *p = rdata; - int anz_conns = (int) *p++; - uint8 *co = p; - int msglen = (int) *(p+anz_conns); - char *msg = (char*) p+anz_conns+1; - int k = -1; - if (anz_conns) { - while (++k < anz_conns) { - int conn= (int) *co++; - if (conn == ncprequest->connection) { - strmaxcpy(c->message, msg, min(58, msglen)); - connect_status = 0x40; /* don't know why */ - } else if (conn && --conn < anz_connect) { - CONNECTION *cc= &(connections[conn]); - if (cc->object_id) { /* if logged */ - strmaxcpy(cc->message, msg, min(58, msglen)); - nwserv_handle_msg(conn+1); - } - } - } - } else { - strmaxcpy(c->message, msg, min(58, msglen)); - connect_status = 0x40; /* don't know why */ - } - } - break; -#if 0 - case 0xfd : /* Send Console Broadcast (new) */ - return(-1); /* nicht erkannt */ - break; -#endif - - case 0xd3 : { /* down File Server */ - if (c->object_id == 1) { /* only SUPERVISOR */ - /* inform nwserv */ - nwserv_down_server(); - } else completition = 0xff; - } - break; - - default : return(-1); /* not known here */ - } /* switch */ - } else if (0x57 == func) { /* namespace functions not handled !! */ - completition = 0xfb; /* 2.15 don't kwown namespace services */ - } else return(-1); /* not kwown here */ - U16_TO_BE16(0x3333, ncpresponse->type); - ncpresponse->sequence = ncprequest->sequence; - ncpresponse->connection = ncprequest->connection; - ncpresponse->reserved = 0; - ncpresponse->completition = completition; - if (c->message[0]) connect_status |= 0x40; - ncpresponse->connect_status = connect_status; -#if CALL_NWCONN_OVER_SOCKET - data_len+=sizeof(NCPRESPONSE); - send_to_nwconn(c->fd, (char*)ncpresponse, data_len); -#else - data_len=write(c->fd, (char*)ncpresponse, - sizeof(NCPRESPONSE) + data_len); -#endif - XDPRINTF((2, 0, "0x%x 0x%x compl:0x%x, write to %d, anz = %d", - func, (int)ufunc, (int) completition, c->fd, data_len)); - - return(0); /* ok */ -} - static void ncp_response(int type, int sequence, int connection, int task, int completition, int connect_status, @@ -1394,36 +389,15 @@ static void ncp_response(int type, int sequence, if (nw_debug){ char comment[80]; sprintf(comment, "NCP-RESP compl=0x%x ", completition); - send_ipx_data(ipx_out_fd, 17, sizeof(NCPRESPONSE) + data_len, + send_ipx_data(ncp_fd, 17, sizeof(NCPRESPONSE) + data_len, (char *) ncpresponse, &from_addr, comment); } else - send_ipx_data(ipx_out_fd, 17, sizeof(NCPRESPONSE) + data_len, + send_ipx_data(ncp_fd, 17, sizeof(NCPRESPONSE) + data_len, (char *) ncpresponse, &from_addr, NULL); } -#if 0 -static void sig_child(int isig) -{ - int k=-1; - int status; - int pid; - signal(SIGCHLD, sig_child); - pid=wait(&status); - XDPRINTF((1,0, "GOT conn pid=%d", pid)); - if (pid > -1) { - while (++k < anz_connect) { - CONNECTION *c = &connections[k]; - if (c->pid == pid) { - clear_connection(k+1); - break; - } - } - kill(pid, SIGKILL); /* kill it */ - } -} -#endif static void close_all(void) { @@ -1440,7 +414,6 @@ static void close_all(void) ipx_out_fd = -1; } } - sync_dbm(); } static int server_is_down=0; @@ -1453,7 +426,6 @@ static int got_sig_child=0; static void sig_child(int isig) { got_sig_child++; - signal(SIGCHLD, sig_child); } static void set_sig(void) @@ -1466,67 +438,13 @@ static void set_sig(void) signal(SIGHUP, SIG_IGN); } -static void handle_bind_calls(uint8 *p) -{ - int func = (int) *p; - p += 2; - switch (func) { - case 0x01 : - { /* insert NET_ADDRESS */ - NETOBJ obj; - obj.type = GET_BE16(p); - p += 2; - strmaxcpy(obj.name, p+1, *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)); - } - break; - - case 0x02 : - { /* delete complete Object */ - NETOBJ obj; - obj.type = GET_BE16(p); - p += 2; - strmaxcpy(obj.name, p+1, *p); - nw_delete_obj(&obj); /* also deletes all properties */ - } - break; - - default : break; - } -} - static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size) { - if (*offs == 0) { -#if CALL_NCPSERV_OVER_SOCKET - memcpy(ipxd, &ipx_in_data, ud.udata.len); -#else - if (read(0, (char*)&(ipxd->owndata.d), sizeof(int)) == sizeof(int)) { - if (ipxd->owndata.d.size >= size && - ipxd->owndata.d.size < IPX_MAX_DATA - sizeof(ipxd->owndata)) { - - if (ipxd->owndata.d.size > - read(0, (char*)&(ipxd->owndata.d.function), - ipxd->owndata.d.size) ) { - size=-1; - } - - } else { - errorp(1, "xread:", "datasize = %d", ipxd->owndata.d.size); - size=-1; - } - } else size = -1; -#endif - } if (size > -1 && *offs + size > ipxd->owndata.d.size) { errorp(1, "xread:", "prog error: *offs=%d + size=%d > d.size=%d", *offs, size, ipxd->owndata.d.size); size = -1; } - if (size > -1) { memcpy(data, ((uint8 *)&(ipxd->owndata.d.function)) + *offs, size); *offs+=size; @@ -1537,46 +455,33 @@ static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size) } static int handle_ctrl(void) -/* reads stdin pipe or packets from nwserv */ +/* packets from nwserv */ { - IPX_DATA ipxd; int what; int conn; int result = 0; int offs=0; - int data_len = xread(&ipxd, &offs, (uint8*)&(what), sizeof(int)); - if (data_len == sizeof(int)) { - XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd.owndata.d.size)); - switch (what) { - case 0x5555 : /* clear_connection */ - if (sizeof (int) == - xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) - clear_connection(conn); - break; + IPX_DATA *ipxd = (IPX_DATA*)&ipx_in_data; + int data_len = xread(ipxd, &offs, (uint8*)&(what), sizeof(int)); - case 0x3333 : /* 'bindery' calls */ + if (data_len == sizeof(int)) { + XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", what, ipxd->owndata.d.size)); + switch (what) { + case 0x5555 : /* clear_connection, from wdog process */ if (sizeof (int) == - xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) { - uint8 *buff = (uint8*) xmalloc(conn+10); - XDPRINTF((2,0, "0x3333 len=%d", conn)); - if (conn == xread(&ipxd, &offs, buff, conn)) - handle_bind_calls(buff); - else - XDPRINTF((1, 1, "0x3333 protokoll error:len=%d", conn)); - xfree(buff); - } + xread(ipxd, &offs, (uint8*)&(conn), sizeof(int))) + clear_connection(conn); break; case 0xeeee: get_ini_debug(NCPSERV); - (void)nw_fill_standard(NULL, NULL); - sync_dbm(); + get_ini(); break; case 0xffff : /* server down */ - data_len = xread(&ipxd, &offs, (char*)&conn, sizeof(int)); + data_len = xread(ipxd, &offs, (uint8*)&conn, sizeof(int)); if (sizeof(int) == data_len && conn == what) - sent_down_message(); + server_goes_down++; break; default : break; @@ -1594,20 +499,20 @@ static void handle_ncp_request(void) int type; in_len = ud.udata.len; time(&akttime); - XDPRINTF((10, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr))); - if ((type = GET_BE16(ncprequest->type)) == 0x2222 || type == 0x5555) { + XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr))); + if ((type = GET_BE16(ncprequest->type)) == 0x2222 + || type == 0x5555) { int connection = (int)ncprequest->connection; XDPRINTF((10,0, "GOT 0x%x in NCPSERV connection=%d", type, connection)); + if ( connection > 0 && connection <= anz_connect) { CONNECTION *c = &(connections[connection-1]); + if (!memcmp(&from_addr, &(c->client_adr), sizeof(ipxAddr_t))) { if (c->fd > -1){ if (type == 0x2222) { - int sent_here = 1; - int func = ncprequest->function; int diff_time = akttime - c->last_access; c->last_access = akttime; - if (diff_time > 50) /* after max. 50 seconds */ nwserv_reset_wdog(connection); /* tell the wdog there's no need to look */ @@ -1621,22 +526,7 @@ static void handle_ncp_request(void) return; } #endif - switch (func) { - case 0x15 : /* Messages */ - case 0x17 : /* File Server Environment */ - sent_here = handle_fxx(c, in_len, func); - break; - - case 0x57 : if (!tells_server_version) { - /* 2.15 er don't have namespace_calls */ - sent_here = handle_fxx(c, in_len, func); - } - break; - - default : break; - } /* switch */ - - if (sent_here) { + if (1) { int anz= #if CALL_NWCONN_OVER_SOCKET in_len; @@ -1645,9 +535,6 @@ static void handle_ncp_request(void) write(c->fd, (char*)ncprequest, in_len); #endif XDPRINTF((10,0, "write to %d, anz = %d", c->fd, anz)); - if (func == 0x19) { /* logout */ - c->object_id = 0; /* not LOGIN */ - } } c->sequence = ncprequest->sequence; /* save last sequence */ c->retry = 0; @@ -1657,7 +544,7 @@ static void handle_ncp_request(void) if ( (uint8) (c->sequence+1) == (uint8) ncprequest->sequence) #endif { - clear_connection(ncprequest->connection); + clear_connection(connection); ncp_response(0x3333, ncprequest->sequence, connection, @@ -1683,16 +570,28 @@ static void handle_ncp_request(void) 0xff, /* conn status */ 0); +#if !CALL_NWCONN_OVER_SOCKET + /* here comes a call from nwbind */ + } else if (type == 0x3333 + && IPXCMPNODE(from_addr.node, my_addr.node) + && IPXCMPNET (from_addr.net, my_addr.net)) { + int connection = (int)ncprequest->connection; + XDPRINTF((6,0, "GOT 0x3333 in NCPSERV connection=%d", connection)); + if ( connection > 0 && connection <= anz_connect) { + CONNECTION *c = &(connections[connection-1]); + if (c->fd > -1) write(c->fd, (char*)ncprequest, in_len); + } +#endif } else if (type == 0x1111) { /* GIVE CONNECTION Nr connection */ - int connection = (server_goes_down) ? 0 : find_get_conn_nr(&from_addr); + int connection = (server_goes_down) ? 0 + : find_get_conn_nr(&from_addr); XDPRINTF((2, 0, "GIVE CONNECTION NR=%d", connection)); if (connection) { CONNECTION *c = &(connections[connection-1]); int anz; - c->message[0] = '\0'; - c->object_id = 0; /* firsttime set 0 for NOT LOGIN */ c->sequence = 0; + #if CALL_NWCONN_OVER_SOCKET anz = in_len; send_to_nwconn(c->fd, (char*)ncprequest, in_len); @@ -1705,41 +604,33 @@ static void handle_ncp_request(void) 0xf9, /* completition */ 0, /* conn status */ 0); -#if CALL_NCPSERV_OVER_SOCKET + } else if (type == 0xeeee - && ((OWN_DATA*)(&ipx_in_data))->type1[0] == 0xee - && ((OWN_DATA*)(&ipx_in_data))->type1[1] == 0xee && IPXCMPNODE(from_addr.node, my_addr.node) && IPXCMPNET (from_addr.net, my_addr.net)) { /* comes from nwserv */ handle_ctrl(); -#endif } else { int connection = (int)ncprequest->connection; int sequence = (int)ncprequest->sequence; XDPRINTF((1,0, "Got UNKNOWN TYPE: 0x%x", type)); - ncp_response(0x3333, sequence, connection, - 1, 0xfb, 0, 0); + ncp_response(0x3333, sequence, connection, 1, 0xfb, 0, 0); } } } int main(int argc, char *argv[]) { - if (argc != 3) { - fprintf(stderr, "usage ncpserv address nwname\n"); + if (argc != 4) { + fprintf(stderr, "usage ncpserv nwname address nwbindsock\n"); exit(1); } init_tools(NCPSERV, 0); + get_ini(); strncpy(my_nwname, argv[1], 48); my_nwname[47] = '\0'; adr_to_ipx_addr(&my_addr, argv[2]); - - if (nw_init_dbm(my_nwname, &my_addr) <0) { - errorp(1, "nw_init_dbm", NULL); - exit(1); - } - + sscanf(argv[3], "%x", &sock_nwbind); #ifdef LINUX set_emu_tli(); #endif @@ -1764,51 +655,15 @@ int main(int argc, char *argv[]) ud.udata.buf = (char*)&ipx_in_data; set_sig(); -#if CALL_NCPSERV_OVER_SOCKET while (!server_is_down) { handle_ncp_request(); if (got_sig_child) { + XDPRINTF((2, 0, "Got SIGCHLD")); kill_connections(); got_sig_child=0; + signal(SIGCHLD, sig_child); } } -#else - polls[0].events = polls[1].events = POLLIN|POLLPRI; - polls[0].revents = polls[1].revents= 0; - polls[0].fd = ncp_fd; - polls[1].fd = 0; /* stdin */ - while (!server_is_down) { - int anz_poll = poll(polls, 2, 60000); - if (anz_poll > 0) { /* i have to work */ - struct pollfd *p = &polls[0]; - int j = -1; - while (++j < 2) { - if (p->revents){ - if (!j) { /* ncp-socket */ - XDPRINTF((99,0, "POLL revents=%d", p->revents)); - if (p->revents & ~POLLIN) - errorp(0, "STREAM error", "revents=0x%x", p->revents ); - else - handle_ncp_request(); - } else if (p->fd==0) { /* fd_ncpserv_in */ - XDPRINTF((2,0,"POLL %d, fh=%d", p->revents, p->fd)); - if (p->revents & ~POLLIN) - errorp(0, "STREAM error", "revents=0x%x", p->revents ); - else handle_ctrl(); - } - if (! --anz_poll) break; - } /* if */ - p++; - } /* while */ - } else { - XDPRINTF((3,0,"POLLING ...")); - } - if (got_sig_child) { - kill_connections(); - got_sig_child=0; - } - } -#endif close_all(); return(0); } diff --git a/net.h b/net.h index cfc7011..90ec931 100644 --- a/net.h +++ b/net.h @@ -1,4 +1,4 @@ -/* net.h 01-Mar-96 */ +/* net.h 20-Mar-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * @@ -97,19 +97,18 @@ # undef CALL_NWCONN_OVER_SOCKET #endif -#ifdef CALL_NCPSERV_OVER_SOCKET -# undef CALL_NCPSERV_OVER_SOCKET -#endif - - #include "config.h" #ifndef CALL_NWCONN_OVER_SOCKET -# define CALL_NWCONN_OVER_SOCKET 0 -#endif - -#ifndef CALL_NCPSERV_OVER_SOCKET -# define CALL_NCPSERV_OVER_SOCKET 1 +# ifdef LINUX +# ifdef SIOCIPXNCPCONN +# define CALL_NWCONN_OVER_SOCKET 1 +# else +# define CALL_NWCONN_OVER_SOCKET 0 +# endif +# else +# define CALL_NWCONN_OVER_SOCKET 0 +# endif #endif #ifndef DO_DEBUG @@ -298,9 +297,10 @@ typedef union { } ncprequest; struct S_OWN_DATA { uint8 type[2]; /* 0xeeee */ - uint8 type1[2]; /* 0xeeee */ + uint8 sequence; + uint8 connection; struct { - int size; /* size of next two entries */ + int size; /* size of next two entries */ int function; uint8 data[1]; } d; @@ -309,10 +309,10 @@ typedef union { } IPX_DATA; typedef struct S_SIP SIP; -typedef struct S_SQP SQP; -typedef struct S_SAP SAP; -typedef struct S_SAPS SAPS; -typedef struct S_RIP RIP; +typedef struct S_SQP SQP; +typedef struct S_SAP SAP; +typedef struct S_SAPS SAPS; +typedef struct S_RIP RIP; typedef struct S_CONFREQ CONFREQ; typedef struct S_DIAGRESP DIAGRESP; @@ -320,25 +320,27 @@ typedef struct S_NCPRESPONSE NCPRESPONSE; typedef struct S_NCPREQUEST NCPREQUEST; typedef struct S_OWN_DATA OWN_DATA; +#define OWN_DATA_IPX_BASE_SIZE 8 + /* SOCKETS */ #define SOCK_AUTO 0x0000 /* Autobound Socket */ -#define SOCK_ROUTE 0x0001 /* Routing Information */ -#define SOCK_ECHO 0x0002 /* Echo Protokoll Packet */ -#define SOCK_ERROR 0x0003 /* Error Handler Packet */ -#define SOCK_NCP 0x0451 /* File Service CORE */ +#define SOCK_ROUTE 0x0001 /* Routing Information */ +#define SOCK_ECHO 0x0002 /* Echo Protokoll Packet */ +#define SOCK_ERROR 0x0003 /* Error Handler Packet */ +#define SOCK_NCP 0x0451 /* File Service CORE */ #define SOCK_SAP 0x0452 /* SAP Service Advertising Packet */ -#define SOCK_RIP 0x0453 /* Routing Information Packet */ -#define SOCK_NETBIOS 0x0455 /* NET BIOS Packet */ -#define SOCK_DIAGNOSE 0x0456 /* Diagnostic Packet */ +#define SOCK_RIP 0x0453 /* Routing Information Packet */ +#define SOCK_NETBIOS 0x0455 /* NET BIOS Packet */ +#define SOCK_DIAGNOSE 0x0456 /* Diagnostic Packet */ #define SOCK_NVT 0x8063 /* NVT (Network Virtual Terminal) */ -/* PACKET TYPES */ -#define PACKT_0 0 /* unknown */ -#define PACKT_ROUTE 1 /* Routing Information */ -#define PACKT_ECHO 2 /* Echo Packet */ -#define PACKT_ERROR 3 /* Error Packet */ +/* PACKET TYPES */ +#define PACKT_0 0 /* unknown */ +#define PACKT_ROUTE 1 /* Routing Information */ +#define PACKT_ECHO 2 /* Echo Packet */ +#define PACKT_ERROR 3 /* Error Packet */ #define PACKT_EXCH 4 /* Packet Exchange Packet */ -#define PACKT_SPX 5 /* SPX Packet */ +#define PACKT_SPX 5 /* SPX Packet */ /* 16 - 31 Experimental */ #define PACKT_CORE 17 /* Core Protokoll (NCP) */ diff --git a/net1.c b/net1.c index 55d3125..ebfa639 100644 --- a/net1.c +++ b/net1.c @@ -1,4 +1,4 @@ -/* net1.c, 14-Jan-96 */ +/* net1.c, 20-Mar-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -192,3 +192,48 @@ int send_ipx_data(int fdx, int pack_typ, return(result); } +#if 0 +int get_ipx_addr(ipxAddr_t *addr) +{ + int fd=t_open("/dev/ipx", O_RDWR, NULL); + struct t_optmgmt optb; + int result = -1; + if (fd < 0) { + t_error("t_open !Ok"); + return(-1); + } + optb.opt.maxlen = optb.opt.len = sizeof(ipxAddr_t); + optb.opt.buf = (char*)addr; + optb.flags = 0; + result = t_optmgmt(fd, &optb, &optb); + if (result < 0) t_error("t_optmgmt !Ok"); + else result=0; + t_close(fd); + return(result); +} +#else + +int get_ipx_addr(ipxAddr_t *addr) +{ + int fd=t_open("/dev/ipx", O_RDWR, NULL); + struct t_bind bind; + int result = -1; + if (fd < 0) { + t_error("t_open !Ok"); + return(-1); + } + bind.addr.len = sizeof(ipxAddr_t); + bind.addr.maxlen = sizeof(ipxAddr_t); + bind.addr.buf = (char*)addr; + bind.qlen = 0; /* ever */ + memset(addr, 0, sizeof(ipxAddr_t)); + if (t_bind(fd, &bind, &bind) < 0) + t_error("tbind:get_ipx_addr"); + else { + result=0; + t_unbind(fd); + } + t_close(fd); + return(result); +} +#endif diff --git a/net1.h b/net1.h index 7068445..5fa3465 100644 --- a/net1.h +++ b/net1.h @@ -1,4 +1,4 @@ -/* net1.h 14-Jan-96 */ +/* net1.h 20-Mar-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -16,7 +16,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#ifndef _M_NET1_H_ +#define _M_NET1_H_ #ifndef LINUX extern void print_t_info(struct t_info *t); @@ -37,3 +38,6 @@ extern int send_ipx_data(int fd, int pack_typ, int data_len, char *data, ipxAddr_t *to_addr, char *comment); +extern int get_ipx_addr(ipxAddr_t *addr); + +#endif diff --git a/nwbind.c b/nwbind.c new file mode 100644 index 0000000..df992f5 --- /dev/null +++ b/nwbind.c @@ -0,0 +1,1404 @@ +/* nwbind.c */ +#define REVISION_DATE "21-Mar-96" +/* NCP Bindery SUB-SERVER */ +/* authentification and some message handling */ + +/* (C)opyright (C) 1993,1996 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 "nwdbm.h" + +/* next should be '1', is for testing only */ +#define USE_PERMANENT_OUT_SOCKET 1 + +static char my_nwname[50]; +static ipxAddr_t my_addr; +static time_t akttime; +static int ipx_out_fd=-1; + +static int ncp_fd = 0; /* stdin */ +static struct t_unitdata ud; +static uint8 ipx_in_data[IPX_MAX_DATA]; +static uint8 ipx_pack_typ = 17; +static int rcv_flags = 0; +static ipxAddr_t from_addr; /* actual calling address */ +static NCPREQUEST *ncprequest = (NCPREQUEST*)&ipx_in_data; +static int server_goes_down=0; + +static void write_to_nwserv(int what, int connection, int mode, + char *data, int size) +{ + switch (what) { + case 0x2222 : /* insert wdog connection */ + write(FD_NWSERV, &what, sizeof(int)); + write(FD_NWSERV, &connection, sizeof(int)); + write(FD_NWSERV, &size, sizeof(int)); + write(FD_NWSERV, data, size); /* ipxAddr_t */ + break; + + case 0x4444 : /* tell the wdog there's no need to look 0 */ + /* fast activate wdog to free connection 1 */ + /* slow activate wdog to free connection 2 */ + /* the connection ist closed 99 */ + write(FD_NWSERV, &what, sizeof(int)); + write(FD_NWSERV, &connection, sizeof(int)); + write(FD_NWSERV, &mode, sizeof(int)); + break; + + case 0x6666 : /* send to client that server holds message */ + write(FD_NWSERV, &what, sizeof(int)); + write(FD_NWSERV, &connection, sizeof(int)); + break; + + case 0xffff : /* tell nwserv to down the server */ + write(FD_NWSERV, &what, sizeof(int)); + write(FD_NWSERV, &what, sizeof(int)); + break; + + default : break; + } +} + +#define nwserv_handle_msg(connection) \ + write_to_nwserv(0x6666, (connection), 0, NULL, 0) + +#define nwserv_down_server() \ + write_to_nwserv(0xffff, 0, 0, NULL, 0) + +static int open_ipx_sockets(void) +{ + struct t_bind bind; + bind.addr.len = sizeof(ipxAddr_t); + bind.addr.maxlen = sizeof(ipxAddr_t); + bind.addr.buf = (char*)&my_addr; + bind.qlen = 0; /* immer */ +#if 0 + ncp_fd=t_open("/dev/ipx", O_RDWR, NULL); + if (ncp_fd < 0) { + t_error("t_open !Ok"); + return(-1); + } + U16_TO_BE16(SOCK_BINDERY, my_addr.sock); + if (t_bind(ncp_fd, &bind, &bind) < 0){ + t_error("t_bind in open_ipx_sockets !OK"); + close(ncp_fd); + return(-1); + } +#endif + +#if USE_PERMANENT_OUT_SOCKET + ipx_out_fd=t_open("/dev/ipx", O_RDWR, NULL); + if (ipx_out_fd > -1) { + U16_TO_BE16(SOCK_AUTO, my_addr.sock); /* dynamic socket */ + if (t_bind(ipx_out_fd, &bind, &bind) < 0) { + if (nw_debug) t_error("2. t_bind in open_ipx_sockets !OK"); + t_close(ipx_out_fd); + ipx_out_fd = -1; + } + } else { + if (nw_debug) t_error("2. t_open !Ok"); + } + +#endif + return(0); +} + +typedef struct { + ipxAddr_t client_adr; /* address remote client */ + uint32 object_id; /* logged object */ + /* 0 = not logged in */ + 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 */ +} CONNECTION; + +static CONNECTION connections[MAX_CONNECTIONS]; + +static void sent_down_message(void) +{ + int k = -1; + server_goes_down++; + while (++k < MAX_CONNECTIONS) { + CONNECTION *cn=&connections[k]; + if (cn->active) { + strmaxcpy(cn->message, "SERVER IS GOING DOWN", 58); + nwserv_handle_msg(k+1); + } + } /* while */ +} + +static void open_clear_connection(int conn, int activate, uint8 *addr) +{ + if (conn > 0 && --conn < MAX_CONNECTIONS) { + CONNECTION *c = &connections[conn]; + c->active = activate; + c->message[0] = '\0'; + c->object_id = 0; + c->t_login = 0; + if (activate && addr) { + memcpy(&(c->client_adr), addr, sizeof(ipxAddr_t)); + c->send_to_sock = GET_BE16(addr+sizeof(ipxAddr_t)); + } + } +} + +static void get_login_time(uint8 login_time[], CONNECTION *cx) +{ + struct tm *s_tm = localtime(&(cx->t_login)); + + login_time[0] = s_tm->tm_year; + login_time[1] = s_tm->tm_mon+1; + login_time[2] = s_tm->tm_mday; + + login_time[3] = s_tm->tm_hour; + login_time[4] = s_tm->tm_min; + login_time[5] = s_tm->tm_sec; + login_time[6] = s_tm->tm_wday; +} + +static void handle_fxx(CONNECTION *c, int gelen, int func) +{ + IPX_DATA ipxoutdata; + NCPRESPONSE *ncpresponse = (NCPRESPONSE*)&ipxoutdata; + uint8 *responsedata = ((uint8*)&ipxoutdata)+sizeof(NCPRESPONSE); + uint8 *requestdata = ((uint8*)ncprequest)+sizeof(NCPREQUEST); +#if 0 + uint8 len = *(requestdata+1); +#endif + + uint8 ufunc = *(requestdata+2); + uint8 *rdata = requestdata+3; + uint8 completition = 0; + uint8 connect_status= 0; + int data_len = 0; + + if (nw_debug > 1){ + int j = gelen - sizeof(NCPREQUEST); + if (nw_debug){ + XDPRINTF((1, 0, "NCP 0x%x REQUEST:ufunc:0x%x", func, ufunc)); + if (j > 0){ + uint8 *p=requestdata; + XDPRINTF((1, 2, "len %d, DATA:", j)); + while (j--) { + int c = *p++; + if (c > 32 && c < 127) XDPRINTF((1, 3, ",\'%c\'", (char) c)); + else XDPRINTF((1, 3, ",0x%x", c)); + } + XDPRINTF((1, 1, NULL)); + } + } + } + if (0x15 == func) { + switch (ufunc) { /* Messages */ + case 0x0 : { /* Send Broadcast Message (old) */ + int anz_conns = (int)*(rdata); /* Number of connections */ + uint8 *conns = rdata+1; /* connectionslist */ + int msglen = *(conns+anz_conns); + uint8 *msg = conns+anz_conns+1; + uint8 *p = responsedata; + int one_found = 0; + int k = -1; + *p++ = (uint8) anz_conns; + while (++k < anz_conns) { + int connr = (int) (*conns++); + int result = 0xff; /* target not ok */ + CONNECTION *cn; + if (connr > 0 && --connr < MAX_CONNECTIONS + && ((cn = &connections[connr]))->active ) { + if (!cn->message[0]) { + strmaxcpy(cn->message, msg, min(58, msglen)); + result = 0; /* Ok */ + } else result = 0xfc; /* server holds message */ + nwserv_handle_msg(connr+1); + one_found++; + } + *p++ = (uint8)result; + } + if (one_found) data_len = anz_conns+1; + else completition=0xff; + } + break; + + case 0x01: { /* Get Broadcast Message (old) */ + *responsedata = (uint8) strmaxcpy(responsedata+1, c->message, 58); + c->message[0] = '\0'; + data_len = (int)(*responsedata) + 1; + } + break; + + case 0x03: { /* Enable Broadcasts */ + ;;; + XDPRINTF((2, 0, "TODO: enable Broadcasts")); + } + break; + + case 0x09: { /* Broadcast to CONSOLE */ + char message[60]; + strmaxcpy(message, rdata+1, min(59, *rdata)); + fprintf(stderr, "\n:%s\n", message); + } + break; + + case 0xa: /* Send Broadcast Message (new) */ + case 0xb: /* Get Broadcast Message (new) */ + default : completition=0xfb; /* not handled */ + } /* switch */ + } else if (0x17 == func) { /* Fileserver Enviro */ + switch (ufunc) { + case 0x01 : { /* Change User Password OLD */ + completition=0xff; + } + break; + +#if FUNC_17_02_IS_DEBUG + case 0x02 : { /* I hope this is call isn't used */ + /* now missused as a debug switch :) */ + + struct XDATA { + uint8 nw_debug; /* old level */ + } *xdata = (struct XDATA*) responsedata; + + if (*rdata == NWBIND) { + xdata->nw_debug = (uint8) nw_debug; + nw_debug = (int) *(rdata+1); + data_len = 1; + } else completition=0xff; + } + break; +#endif + + case 0x0c : { /* Verify Serialization */ + completition=0xff; + } + break; + + case 0x0e : { /* Get Disk Utilization */ + completition=0xff; + } + break; +#if 0 + case 0x10 : set file information. handled in nwconn. +#endif + + case 0x11 : { /* Get FileServer Info */ + struct XDATA { + uint8 servername[48]; + uint8 version; /* 2 or 3 */ + uint8 subversion; /* 15 or 11 */ + uint8 maxconnections[2]; + uint8 connection_in_use[2]; + uint8 max_volumes[2]; + uint8 os_revision; + uint8 sft_level; + uint8 tts_level; + uint8 peak_connection[2]; + uint8 accounting_version; + uint8 vap_version; + uint8 queuing_version; + uint8 print_server_version; + uint8 virtual_console_version; + uint8 security_level; + uint8 internet_bridge_version; + uint8 reserved[60]; + } *xdata = (struct XDATA*) responsedata; + int k, i; + memset(xdata, 0, sizeof(struct XDATA)); + strcpy(xdata->servername, my_nwname); + if (!tells_server_version) { + xdata->version = 2; + xdata->subversion = 15; + } else { + xdata->version = 3; + xdata->subversion = (tells_server_version == 2) + ? 12 + : 11; + } + + i=0; + for (k=0; k < MAX_CONNECTIONS; k++) { + if (connections[k].active) i++; + } + U16_TO_BE16(i, xdata->connection_in_use); + U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections); + U16_TO_BE16(MAX_CONNECTIONS, xdata->peak_connection); + U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes); + data_len = sizeof(struct XDATA); + } + break; + + case 0x12 : { /* Get Network Serial Number */ + struct XDATA { + uint8 serial_number[4]; + uint8 appl_number[2]; + } *xdata = (struct XDATA*) responsedata; + /* serial-number 4-Byte */ + U32_TO_BE32(NETWORK_SERIAL_NMBR, xdata->serial_number); + /* applikation-number 2-Byte */ + U16_TO_BE16(NETWORK_APPL_NMBR, xdata->appl_number); + data_len = sizeof(struct XDATA); + } + break; + + case 0x13 : { /* Get Connection Internet Address */ + int conn = (int)*(rdata); /* Connection Nr */ + if (conn && --conn < MAX_CONNECTIONS + && connections[conn].active ) { + CONNECTION *cx=&(connections[conn]); + data_len = sizeof(ipxAddr_t); + memcpy(responsedata, (char*)&(cx->client_adr), data_len); + } else completition = 0xff; + } break; + + case 0x14 : { /* Login Objekt, unencrypted passwords */ + uint8 *p = rdata; + uint8 *p1 = p+3 + *(p+2); /* here is password */ + int result; + NETOBJ obj; + char password[80]; + obj.type = GET_BE16(p); + xstrmaxcpy(obj.name, p+3, (int) *(p+2)); + upstr(obj.name); + xstrmaxcpy(password, p1+1, (int) *p1); + XDPRINTF((10, 0, "LOGIN unencrypted PW NAME='%s', PASSW='%s'", + obj.name, password)); + if (0 == (result = find_obj_id(&obj, 0))) { + if (password_scheme & PW_SCHEME_LOGIN) { +#if 0 + if (obj.id == 1) { + result=-0xff; /* SUPERVISOR ever encryted !! */ + XDPRINTF((1, 0, "Supervisor tried unencrypted LOGIN")); + } else +#endif + result=nw_test_unenpasswd(obj.id, password); + } else { + XDPRINTF((1, 0, "unencryted logins are not enabled")); + result=-0xff; + } + } + if (!result) { + c->object_id = obj.id; /* actuell Object ID */ + c->t_login = akttime; /* u. login Time */ + get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)), obj.id); + data_len = 2 * sizeof(int); + } else completition = (uint8) -result; + } break; + + case 0x15 : { /* Get Object Connection List */ + uint8 *p = rdata; + int result; + NETOBJ obj; + obj.type = GET_BE16(p); + p+=2; + strmaxcpy((char*)obj.name, (char*)(p+1), (int) *(p)); + upstr(obj.name); + result = find_obj_id(&obj, 0); + if (!result){ + int k=-1; + int anz = 0; + p = responsedata+1; + while (++k < MAX_CONNECTIONS && anz < 255) { + CONNECTION *cn= &connections[k]; + if (cn->active && cn->object_id == obj.id) { + *p++=(uint8)k+1; + anz++; + } + } /* while */ + *responsedata = anz; + data_len = 1 + anz; + } else completition=(uint8)-result; + } + break; + + case 0x16 : { /* Get Connection Info, OLD */ + struct XDATA { + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + uint8 login_time[7]; + uint8 reserved; + } *xdata = (struct XDATA*) responsedata; + int conn = (uint16)*(rdata); /* Connection Nr */ + memset(xdata, 0, sizeof(struct XDATA)); + data_len = sizeof(struct XDATA); + if (conn && conn <= MAX_CONNECTIONS + && connections[conn-1].active ) { + CONNECTION *cx=&(connections[conn-1]); + NETOBJ obj; + int result; + obj.id = cx->object_id; + result = nw_get_obj(&obj); + if (!result) { + memset(xdata, 0, sizeof(struct XDATA)); + U32_TO_BE32(obj.id, xdata->object_id); + U16_TO_BE16(obj.type, xdata->object_type); + strncpy(xdata->object_name, obj.name, 48); + get_login_time(xdata->login_time, cx); + } /* else completition = (uint8)(-result); */ + } else if (!conn || conn > MAX_CONNECTIONS) { + data_len = 0; + completition = 0xfd; + } + } break; + + case 0x17 : { /* get crypt key */ + int k = sizeof(c->crypt_key); + uint8 *p = c->crypt_key; + uint8 *pp = responsedata; + data_len = k; + while (k--) *pp++ = *p++ = +#ifndef _MAR_TESTS_ + (uint8) rand(); +#else + (uint8) k; +#endif + /* if all here are same (1 or 2) then the resulting key is */ + /* 00000000 */ + if (password_scheme & PW_SCHEME_GET_KEY_FAIL) + completition=0xfb; + } + break; + + case 0x18 : { /* crypt_keyed LOGIN */ + uint8 *p = rdata+sizeof(c->crypt_key); + NETOBJ obj; + int result; + obj.type = GET_BE16(p); + obj.id = 0; + 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))) + result=nw_test_passwd(obj.id, c->crypt_key, rdata); + if (result > -1) { + c->object_id = obj.id; /* actuell Object */ + c->t_login = akttime; /* and login time */ + get_guid((int*)responsedata, (int*)(responsedata+sizeof(int)), obj.id); + data_len = 2 * sizeof(int); + } 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; + } + } + break; + + case 0x1c : { /* Get Connection Info, new */ + struct XDATA { + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + uint8 login_time[7]; + uint8 reserved; + } *xdata = (struct XDATA*) responsedata; + int conn = (uint16)*(rdata); /* Connection Nr */ + if (conn && --conn < MAX_CONNECTIONS){ + CONNECTION *cx=&(connections[conn]); + NETOBJ obj; + int result; + obj.id = cx->object_id; + result = nw_get_obj(&obj); + if (!result) { + memset(xdata, 0, sizeof(struct XDATA)); + U32_TO_BE32(obj.id, xdata->object_id); + U16_TO_BE16(obj.type, xdata->object_type); + strncpy(xdata->object_name, obj.name, 48); + get_login_time(xdata->login_time, cx); + data_len = sizeof(struct XDATA); + } else completition = (uint8)(-result); + } else completition = 0xff; + } break; + + + case 0x32 : { /* Create Bindery Object */ + NETOBJ obj; + int result; + uint8 *p = rdata; + obj.flags = *p++; + obj.security = *p++; + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)p+3, (int) *(p+2)); + result = nw_create_obj(&obj, 0); + if (result < 0) completition = (uint8) -result; + } break; + + case 0x33 : { /* delete OBJECT */ + uint8 *p = rdata; + int result; + NETOBJ obj; + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); + result = nw_delete_obj(&obj); + if (result < 0) completition = (uint8) -result; + } break; + + case 0x34 : { /* rename OBJECT, only SU */ + int result=-0xff; + if (1 == c->object_id) { + uint8 *p = rdata; + NETOBJ obj; + uint8 newname[256]; + uint8 *p1 = p+3 + *(p+2); /* new Name Length */ + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); + strmaxcpy((char*)newname, (char*)(p1+1), (int) *(p1)); + result = nw_rename_obj(&obj, newname); + } + if (result) completition = (uint8) -result; + } break; + + + case 0x35 : { /* get Bindery Object ID */ + struct XDATA { + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + } *xdata = (struct XDATA*) responsedata; + uint8 *p = rdata; + int result; + NETOBJ obj; + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)(p+3), (int) *(p+2)); + upstr(obj.name); + result = find_obj_id(&obj, 0); + if (!result){ + U32_TO_BE32(obj.id, xdata->object_id); + U16_TO_BE16(obj.type, xdata->object_type); + strncpy(xdata->object_name, obj.name, 48); + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } break; + + case 0x36 : { /* get Bindery Object Name */ + struct XDATA { + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + } *xdata = (struct XDATA*) responsedata; + uint8 *p = rdata; + int result; + NETOBJ obj; + obj.id = GET_BE32(p); + result = nw_get_obj(&obj); + if (!result){ + U32_TO_BE32(obj.id, xdata->object_id); + U16_TO_BE16(obj.type, xdata->object_type); + strncpy(xdata->object_name, obj.name, 48); + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } break; + + case 0x37 : { /* Scan Bindery Object */ + struct XDATA { + uint8 object_id[4]; + uint8 object_type[2]; + uint8 object_name[48]; + uint8 object_flag; + uint8 object_security; + uint8 object_has_properties; + } *xdata = (struct XDATA*) responsedata; + uint32 last_obj_id = GET_BE32(rdata); + uint8 *p = rdata+4; + int result; + NETOBJ obj; + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)(p+3),(int) *(p+2)); + upstr(obj.name); + result = find_obj_id(&obj, last_obj_id); + if (!result){ + U32_TO_BE32(obj.id, xdata->object_id); + U16_TO_BE16(obj.type, xdata->object_type); + strncpy(xdata->object_name, obj.name, 48); + xdata->object_flag = obj.flags; + xdata->object_security = obj.security; + if (nw_obj_has_prop(&obj) > 0) + xdata->object_has_properties = 0xff; + else xdata->object_has_properties = 0; + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } + break; + + case 0x38 : { /* change Bindery Objekt Security */ + /* only SU ! */ + int result= -0xff; + if (1 == c->object_id) { + uint8 *p = rdata; + NETOBJ obj; + obj.type = GET_BE16(p+1); + xstrmaxcpy(obj.name, (char*)(p+4), (int) *(p+3)); + result = nw_change_obj_security(&obj, (int)*p); + } + if (result < 0) completition = (uint8) -result; + } break; + + case 0x39 : { /* create Property */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+=2); + uint8 *object_name = ++p; + int prop_flags = (int) *(p+=object_namlen); + int prop_security = (int) *(++p); + int prop_namlen = (int) *(++p); + uint8 *prop_name = ++p; + int result = nw_create_prop( object_type, + object_name, object_namlen, + prop_name, prop_namlen, + prop_flags, prop_security); + if (result) completition = (uint8) -result; + } break; + + + case 0x3a : { /* delete property */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+2); + uint8 *object_name= p+3; + int prop_namlen = (int) *(p+3+object_namlen); + uint8 *prop_name = p+4+object_namlen; + int result = nw_delete_property( object_type, + object_name, object_namlen, + prop_name, prop_namlen); + if (result < 0) completition = (uint8) -result; + } break; + + case 0x3b : { /* Change Prop Security */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+=2); + uint8 *object_name= ++p; + int prop_security = (int) *(p+=object_namlen); + int prop_namlen = (int) *(++p); + uint8 *prop_name = ++p; + int result = nw_change_prop_security(object_type, + object_name, object_namlen, + prop_name, prop_namlen, prop_security); + if (result) completition = (uint8) -result; + } break; + + case 0x3c : { /* Scan Property */ + struct XDATA { + uint8 prop_name[16]; + uint8 flags; /* set=2, dynamic=1 */ + uint8 security; + uint8 akt_scan[4]; + uint8 has_value; /* ff, if there are Prop's Values */ + uint8 weisnicht; + } *xdata = (struct XDATA*) responsedata; + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+2); + uint8 *object_name = (p+=3); + uint32 last_scan = GET_BE32((p+object_namlen)); + uint8 prop_namlen = (int)* (p+=object_namlen+4); + uint8 *prop_name = ++p; + NETPROP prop; + int result = nw_scan_property(&prop, + object_type, object_name, object_namlen, + prop_name, prop_namlen, &last_scan); + if (result > -1) { + strncpy(xdata->prop_name, + prop.name, sizeof(xdata->prop_name)); + U32_TO_BE32(last_scan, xdata->akt_scan); + xdata->flags = prop.flags; + xdata->security = prop.security; + xdata->has_value = (uint8) result; + xdata->weisnicht = 0x0; + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } break; + + case 0x3d : { /* read Bindery Property Value */ + struct XDATA { + uint8 property_value[128]; + uint8 more_segments; + uint8 property_flags; + } *xdata = (struct XDATA*) responsedata; + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+2); + uint8 *object_name= p+3; + int segment_nr = (int) *(p+3+object_namlen); + int prop_namlen = (int) *(p+4+object_namlen); + uint8 *prop_name = p+5+object_namlen; + int result = nw_get_prop_val( object_type, + object_name, object_namlen, + segment_nr, + prop_name, prop_namlen, + xdata->property_value, + &(xdata->more_segments), + &(xdata->property_flags)); + if (!result){ + data_len = sizeof(struct XDATA); + } else completition = (uint8) -result; + } break; + + case 0x3e : { /* write Bindery Property Value */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+2); + uint8 *object_name= p+3; + int segment_nr = (int) *(p+3+object_namlen); + int erase_segment = (int) *(p+4+object_namlen); + int prop_namlen = (int) *(p+5+object_namlen); + uint8 *prop_name = p+6+object_namlen; + uint8 *valdata = p+6+object_namlen+prop_namlen; + int result = nw_write_prop_value( object_type, + object_name, object_namlen, + segment_nr, erase_segment, + prop_name, prop_namlen, + valdata); + if (result) completition = (uint8) -result; + } break; + + case 0x40: { /* change object password */ + if (password_scheme & PW_SCHEME_CHANGE_PW) { + uint8 *p = rdata; + uint8 oldpassword[50]; + uint8 newpassword[50]; + NETOBJ obj; + int result; + obj.type = GET_BE16(p); + p+=2; + xstrmaxcpy(obj.name, p+1, (int) *p); + upstr(obj.name); + p += ((*p)+1); + xstrmaxcpy(oldpassword, p+1, (int) *p); + p += ((*p)+1); + xstrmaxcpy(newpassword, p+1, (int) *p); + if (0 == (result = find_obj_id(&obj, 0))) { + XDPRINTF((6, 0, "CHPW: OLD=`%s`, NEW=`%s`", oldpassword, + newpassword)); + if (c->object_id == 1 || + 0 == (result=nw_test_unenpasswd(obj.id, oldpassword))){ + if ( (c->object_id != 1) + || *newpassword + || !(password_scheme & PW_SCHEME_LOGIN)) + result=nw_set_passwd(obj.id, newpassword, 0); + else result = -0xff; + } + } + if (result < 0) completition = (uint8) -result; + } else { + XDPRINTF((1, 0, "Change object password unencryted not enabled")); + completition=0xff; + } + } break; + + case 0x41 : { /* add Bindery Object to Set */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+=2); + uint8 *object_name= ++p; + int prop_namlen = (int) *(p+=object_namlen); + uint8 *prop_name = ++p; + int member_type = GET_BE16(p+prop_namlen); + int member_namlen = (int) *(p+=(prop_namlen+2)); + uint8 *member_name= ++p; + int result = nw_add_obj_to_set( object_type, + object_name, object_namlen, + prop_name, prop_namlen, + member_type, + member_name, member_namlen); + if (result) completition = (uint8) -result; + } break; + + case 0x42 : { /* delete Bindery Object from Set */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+=2); + uint8 *object_name= ++p; + int prop_namlen = (int) *(p+=object_namlen); + uint8 *prop_name = ++p; + int member_type = GET_BE16(p+prop_namlen); + int member_namlen = (int) *(p+=(prop_namlen+2)); + uint8 *member_name= ++p; + int result = nw_delete_obj_from_set( object_type, + object_name, object_namlen, + prop_name, prop_namlen, + member_type, + member_name, member_namlen); + if (result) completition = (uint8) -result; + } break; + + case 0x43 : { /* is Bindery Object in Set */ + uint8 *p = rdata; + int object_type = GET_BE16(p); + int object_namlen = (int) *(p+=2); + uint8 *object_name= ++p; + int prop_namlen = (int) *(p+=object_namlen); + uint8 *prop_name = ++p; + int member_type = GET_BE16(p+prop_namlen); + int member_namlen = (int) *(p+=(prop_namlen+2)); + uint8 *member_name= ++p; + int result = nw_is_obj_in_set( object_type, + object_name, object_namlen, + prop_name, prop_namlen, + member_type, + member_name, member_namlen); + if (result) completition = (uint8) -result; + } break; + + + case 0x44 : { /* CLOSE BINDERY */ + ; + } break; + + case 0x45 : { /* OPEN BINDERY */ + ; + } break; + + + case 0x46 : { /* GET BINDERY ACCES LEVEL */ +#if 0 + struct XDATA { + uint8 acces_level; + uint8 object_id[4]; + } *xdata = (struct XDATA*) responsedata; +#else + uint8 *xdata = responsedata; +#endif + + NETOBJ obj; + obj.id = c->object_id; + if (0 != obj.id) { + int result = nw_get_obj(&obj); + if (!result) { + *xdata = obj.security; + U32_TO_BE32(obj.id, (xdata+1)); + XDPRINTF((2,0, "ACCESS LEVEL:=0x%x, obj=0x%lx", + (int) obj.security, obj.id)); + data_len = 5; + } else completition = (uint8)-result; + } else { + *xdata = 0; + memset(xdata+1, 0xff, 4); + data_len = 5; + } + } + break; + + + case 0x47 : { /* SCAN BINDERY OBJECT TRUSTEE PATH */ + /* TODO !!! */ + completition = (uint8)0xff; + } + break; + + case 0x48 : { /* GET BINDERY ACCES LEVEL from OBJECT ??? */ + struct XDATA { + uint8 acces_level; + } *xdata = (struct XDATA*) responsedata; + NETOBJ obj; + int result; + obj.id = GET_BE32(rdata); + result = nw_get_obj(&obj); + if (!result) { + xdata->acces_level = obj.security; + data_len = sizeof(struct XDATA); + } else completition = (uint8)-result; + } + break; + + case 0x49 : { /* IS CALLING STATION A MANAGER */ + NETOBJ obj; + obj.id = GET_BE32(rdata); + /* TODO !! */ + completition = 0; /* here allways Manager */ + /* not manager, then completition = 0xff */ + } + break; + + case 0x4a : { /* keyed verify password */ + uint8 *p = rdata+sizeof(c->crypt_key); + NETOBJ obj; + int result; + obj.type = GET_BE16(p); + strmaxcpy((char*)obj.name, (char*)(p+3), *(p+2)); + upstr(obj.name); + if (0 == (result = find_obj_id(&obj, 0))) + result=nw_test_passwd(obj.id, c->crypt_key, rdata); + if (result < 0) completition = (uint8) -result; + XDPRINTF((2,0, "Keyed Verify PW from OBJECT='%s', result=%d", + obj.name, result)); + } + break; + +#ifdef _CHANGE_PASSWD_TESTING_ + case 0x4b : { /* keyed change pasword */ + uint8 *p = rdata+sizeof(c->crypt_key); + NETOBJ obj; + int result; + obj.type = GET_BE16(p); + p+=2; + strmaxcpy((char*)obj.name, (char*)(p+1), *p); + upstr(obj.name); + p += (*p+1); /* here is now password-type ?? 0x60,0x66 */ + + if (0 == (result = find_obj_id(&obj, 0))) + result=nw_test_passwd(obj.id, c->crypt_key, rdata); +#if 0 + if (result > -1) + result=nw_set_enpasswd(obj.id, p+1); +#endif + if (result< 0) completition = (uint8) -result; + XDPRINTF((1, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", + obj.name, result)); + } + break; +#endif + + case 0x4c : { /* List Relations of an Object */ + XDPRINTF((1, 0, "TODO:List Relations of an Object")); + completition=0xfb; + } break; + + case 0x64 : { /* Create Queue */ + XDPRINTF((1, 0, "TODO:Create QUEUE ??")); + completition=0xfb; + } break; + + case 0x65 : { /* Delete Queue */ + XDPRINTF((1, 0, "TODO:Delete QUEUE ??")); + completition=0xfb; + } break; + + + case 0x66 : { /* Read Queue Current Status,old */ + /* !!!!!! TO DO */ + NETOBJ obj; + struct XDATA { + uint8 queue_id[4]; + uint8 status; + uint8 entries; + uint8 servers; + uint8 data[1]; /* server_id + server_station list */ + } *xdata = (struct XDATA*) responsedata; + obj.id = GET_BE32(rdata); + memset(xdata, 0, sizeof(struct XDATA)); + U32_TO_BE32(obj.id, xdata->queue_id); + data_len = sizeof(struct XDATA); + XDPRINTF((1, 0, "TODO:READ QUEUE STATUS,old of Q=0x%lx", obj.id)); + } + break; + + case 0x6A : /* Remove Job from Queue OLD */ + case 0x80 : { /* Remove Job from Queue NEW */ + NETOBJ obj; + uint32 jobnr = (ufunc == 0x6A) + ? GET_BE16(rdata+4) + : GET_BE32(rdata+4); + obj.id = GET_BE32(rdata); + XDPRINTF((1, 0, "TODO:Remove Job=%ld from Queue Q=0x%lx", jobnr, obj.id)); + completition=0xd5; /* no Queue Job */ + }break; + + case 0x6B : { /* Get Queue Job List, old */ + /* !!!!!! TO DO */ + NETOBJ obj; + obj.id = GET_BE32(rdata); + XDPRINTF((1, 0, "TODO:GET QUEUE JOB LIST,old of Q=0x%lx", obj.id)); + completition=0xd5; /* no Queue Job */ + } + break; + + case 0x6C : { /* Get Queue Job Entry */ + /* !!!!!! TODO */ + NETOBJ obj; + obj.id = GET_BE32(rdata); + XDPRINTF((1, 0, "TODO: GET QUEUE JOB ENTRY of Q=0x%lx", obj.id)); + completition=0xd5; /* no Queue Job */ + } + break; + + case 0x68: /* creat queue job and file old */ + case 0x79: { /* creat queue job and file new */ + uint32 q_id = GET_BE32(rdata); + uint8 *dir_name = responsedata+1; + int result = nw_get_q_dirname(q_id, dir_name); + if (result > -1) { + *(dir_name-1) = result; + data_len = result+1; + } else completition = (uint8) -result; + } + break; + + case 0x69: /* close file and start queue old ?? */ + case 0x7f: { /* close file and start queue */ + uint32 q_id = GET_BE32(rdata); + uint8 *prc = responsedata+1; + int result = nw_get_q_prcommand(q_id, prc); + if (result > -1) { + *(prc-1) = result; + data_len = result+1; + } else completition = (uint8) -result; + } + break; + + + case 0x7d : { /* Read Queue Current Status, new */ + NETOBJ obj; + obj.id = GET_BE32(rdata); + XDPRINTF((1, 0, "TODO:READ QUEUE STATUS NEW of Q=0x%lx", obj.id)); + completition=0xd5; /* no Queue Job */ + }break; + + case 0xc8 : { /* CHECK CONSOLE PRIVILEGES */ + XDPRINTF((1, 0, "TODO: CHECK CONSOLE PRIV")); + /* !!!!!! TODO completition=0xc6 (no rights) */ + } break; + + case 0xc9 : { /* GET FILE SERVER DESCRIPTION STRINGs */ + char *company = "Mars :-)"; + char *revision = "Version %d.%d"; + char *revision_date = REVISION_DATE; + char *copyright = "(C)opyright Martin Stover"; + int k=strlen(company)+1; + int l; + memset(responsedata, 0, 512); + strcpy(responsedata, company); + + l = 1 + sprintf(responsedata+k, revision, + _VERS_H_, _VERS_L_ ); +#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); + k += (strlen(copyright)+1); + data_len = k; + } break; + + case 0xcd : { /* GET FILE SERVER LOGIN STATUS */ + struct XDATA { + uint8 login_allowed; /* 0 NO , 1 YES */ + } *xdata = (struct XDATA*) responsedata; + xdata->login_allowed = 1; + data_len = 1; + } + break; + + case 0xd1 : /* Send Console Broadcast (old) */ + { + uint8 *p = rdata; + int anz_conns = (int) *p++; + uint8 *co = p; + int msglen = (int) *(p+anz_conns); + char *msg = (char*) p+anz_conns+1; + int k = -1; + if (anz_conns) { + while (++k < anz_conns) { + int conn= (int) *co++; + if (conn == ncprequest->connection) { + strmaxcpy(c->message, msg, min(58, msglen)); + connect_status = 0x40; /* don't know why */ + } else if (conn && --conn < MAX_CONNECTIONS) { + CONNECTION *cc= &(connections[conn]); + if (cc->object_id) { /* if logged */ + strmaxcpy(cc->message, msg, min(58, msglen)); + nwserv_handle_msg(conn+1); + } + } + } + } else { + strmaxcpy(c->message, msg, min(58, msglen)); + connect_status = 0x40; /* don't know why */ + } + } + break; + + case 0xd3 : { /* down File Server */ + if (c->object_id == 1) { /* only SUPERVISOR */ + /* inform nwserv */ + nwserv_down_server(); + } else completition = 0xff; + } + break; + +#if 0 + case 0xfd : /* Send Console Broadcast (new) */ + return(-1); /* nicht erkannt */ + + break; +#endif + default : completition = 0xfb; /* not known here */ + } /* switch */ + } else if (func == 0x19) { /* logout */ + c->object_id = 0; /* not LOGIN */ + } else completition = 0xfb; + + U16_TO_BE16(0x3333, ncpresponse->type); + ncpresponse->sequence = ncprequest->sequence; + ncpresponse->connection = ncprequest->connection; + ncpresponse->reserved = 0; + ncpresponse->completition = completition; + + if (c->message[0]) connect_status |= 0x40; + ncpresponse->connect_status = connect_status; + data_len+=sizeof(NCPRESPONSE); + U16_TO_BE16(c->send_to_sock, my_addr.sock); + + 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 anz = %d", + (int)func, (int)ufunc, (int) completition, data_len)); +} + +static void handle_bind_calls(uint8 *p) +{ + int func = (int) *p; + p += 2; + switch (func) { + case 0x01 : + { /* insert NET_ADDRESS */ + NETOBJ obj; + obj.type = GET_BE16(p); + p += 2; + strmaxcpy(obj.name, p+1, *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)); + } + break; + + case 0x02 : + { /* delete complete Object */ + NETOBJ obj; + obj.type = GET_BE16(p); + p += 2; + strmaxcpy(obj.name, p+1, *p); + nw_delete_obj(&obj); /* also deletes all properties */ + } + break; + + default : break; + } +} + +static void reinit_nwbind(void) +{ + get_ini_debug(NWBIND); + (void)nw_fill_standard(NULL, NULL); + sync_dbm(); +} + +static int xread(IPX_DATA *ipxd, int *offs, uint8 *data, int size) +{ + if (*offs == 0) memcpy(ipxd, &ipx_in_data, ud.udata.len); + if (size > -1 && *offs + size > ipxd->owndata.d.size) { + errorp(1, "xread:", "prog error: *offs=%d + size=%d > d.size=%d", + *offs, size, ipxd->owndata.d.size); + size = -1; + } + if (size > -1) { + memcpy(data, ((uint8 *)&(ipxd->owndata.d.function)) + *offs, size); + *offs+=size; + } else { + errorp(1, "xread:", "readerror"); + } + return(size); +} + +static void handle_ctrl(void) +/* reads stdin pipe or packets from nwserv/ncpserv */ +{ + IPX_DATA ipxd; + int what; + int conn; + int offs=0; + int data_len = xread(&ipxd, &offs, (uint8*)&(what), sizeof(int)); + + if (data_len == sizeof(int)) { + XDPRINTF((2, 0, "GOT CTRL what=0x%x, len=%d", + what, ipxd.owndata.d.size)); + switch (what) { + + case 0x2222 : /* insert connection */ + if (sizeof (int) == + xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) { + int size = 0; + if (sizeof (int) == + xread(&ipxd, &offs, (uint8*)&(size), sizeof(int)) + && size == sizeof(ipxAddr_t) + sizeof(uint16)) { + uint8 buf[100]; + if (size == + xread(&ipxd, &offs, buf, size)) + open_clear_connection(conn, 1, buf); + } + } + break; + + case 0x3333 : /* special 'bindery' calls */ + if (sizeof (int) == + xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) { + uint8 *buff = (uint8*) xmalloc(conn+10); + XDPRINTF((2,0, "0x3333 len=%d", conn)); + if (conn == xread(&ipxd, &offs, buff, conn)) + handle_bind_calls(buff); + else + XDPRINTF((1, 1, "0x3333 protokoll error:len=%d", conn)); + xfree(buff); + } + break; + + case 0x5555 : /* clear connection */ + if (sizeof (int) == + xread(&ipxd, &offs, (uint8*)&(conn), sizeof(int))) + open_clear_connection(conn, 0, NULL); + break; + + case 0xeeee: + reinit_nwbind(); + break; + + case 0xffff : /* server down */ + data_len = xread(&ipxd, &offs, (char*)&conn, sizeof(int)); + if (sizeof(int) == data_len && conn == what) + sent_down_message(); + break; + + default : break; + } /* switch */ + } else { + errorp(1, "handle_ctrl", "wrong data len=%d", data_len); + } +} + +static int got_sig=0; +static void sig_handler(int isig) +{ + got_sig=isig; + signal(isig, sig_handler); +} + +static void set_sig(void) +{ + signal(SIGQUIT, sig_handler); + signal(SIGHUP, sig_handler); + signal(SIGTERM, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); +} + +int main(int argc, char *argv[]) +{ + int sock_nwbind; + if (argc != 4) { + fprintf(stderr, "usage nwbind nwname address nwbindsock\n"); + exit(1); + } + + init_tools(NWBIND, 0); + + memset(connections, 0, sizeof(connections)); + + strmaxcpy(my_nwname, argv[1], 47); + adr_to_ipx_addr(&my_addr, argv[2]); + + sscanf(argv[3], "%x", &sock_nwbind); + + if (nw_init_dbm(my_nwname, &my_addr) <0) { + errorp(1, "nw_init_dbm", NULL); + exit(1); + } + +#ifdef LINUX + set_emu_tli(); +#endif + + if (open_ipx_sockets()) { + errorp(1, "open_ipx_sockets", NULL); + exit(1); + } + + 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 */ + + ud.addr.len = sizeof(ipxAddr_t); + ud.addr.maxlen = sizeof(ipxAddr_t); + ud.addr.buf = (char*)&from_addr; + + ud.udata.len = IPX_MAX_DATA; + ud.udata.maxlen = IPX_MAX_DATA; + ud.udata.buf = (char*)&ipx_in_data; + set_sig(); + + while (got_sig != SIGQUIT) { + if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){ + time(&akttime); + XDPRINTF((10, 0, "NWBIND-LOOP from %s", visable_ipx_adr(&from_addr))); + if ( ncprequest->type[0] == 0x22 + && ncprequest->type[1] == 0x22) { + int conn = ((int)ncprequest->connection) - 1; + if (conn > -1 && conn < MAX_CONNECTIONS) { + CONNECTION *c=&(connections[conn]); + if (c->active && IPXCMPNODE(from_addr.node, my_addr.node) + && IPXCMPNET (from_addr.net, my_addr.net)) { + handle_fxx(c, ud.udata.len, (int)ncprequest->function); + } else { + XDPRINTF((1, 0, "NWBIND-LOOP addr of connection=%d is wrong", + conn+1)); + } + } else { + XDPRINTF((1, 0, "NWBIND-LOOP connection=%d is wrong", + conn+1)); + } + } else if ( ncprequest->type[0] == 0xee + && ncprequest->type[1] == 0xee + && IPXCMPNODE(from_addr.node, my_addr.node) + && IPXCMPNET (from_addr.net, my_addr.net)) { + /* comes from nwserv, i hope :) */ + handle_ctrl(); + } else { + XDPRINTF((1, 0, "NWBIND-LOOP got wrong type 0x%x func=0x%x", + (int) GET_BE16(ncprequest->type), (int) ncprequest->function)); + } + } + if (got_sig == SIGHUP) { + /* here I update some Bindery stuff from nwserv.conf */ + reinit_nwbind(); + got_sig = 0; + } + } + if (ncp_fd > -1) { + t_unbind(ncp_fd); + t_close(ncp_fd); + XDPRINTF((2,0, "LEAVE nwbind")); + if (ipx_out_fd > -1) { + t_unbind(ipx_out_fd); + t_close(ipx_out_fd); + } + } + sync_dbm(); + return(0); +} diff --git a/nwclient.c b/nwclient.c index b36d68d..4b3fe5c 100644 --- a/nwclient.c +++ b/nwclient.c @@ -201,7 +201,7 @@ ncp_request(0x2222, sequence, connection, 1, 0, \ static int get_conn_nr(void) { - ncp_request(0x1111, sequence, 0xff, 0, 0xff, 0, + ncp_request(0x1111, sequence, 2, 2, 0xff, 0, 0, "Get Connection Nr."); if (!handle_event()) { @@ -652,6 +652,16 @@ static void test2(void) } } +static void test3(void) +{ + uint8 data[] = {0xfe,0x0,0x0,0x0,0x0,0x0,0x2}; + RDATA(data, 0x3b, "test_3b ??"); + if (!handle_event()) { + ; + } +} + + static int do_5f(void) { uint8 data[] = {0x10, 0, 0, 0}; @@ -779,6 +789,7 @@ int main(int argc, char **argv) test1(); test2(); + test3(); get_connection_info(0); get_connection_info(1); diff --git a/nwconn.c b/nwconn.c index 5b2401a..fdf8c74 100644 --- a/nwconn.c +++ b/nwconn.c @@ -1,4 +1,4 @@ -/* nwconn.c 14-Mar-96 */ +/* nwconn.c 21-Mar-96 */ /* one process / connection */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany @@ -25,11 +25,13 @@ #include "connect.h" #include "namspace.h" + +#define FD_NCP_OUT 3 + static int father_pid = -1; static ipxAddr_t from_addr; static ipxAddr_t my_addr; static struct t_unitdata ud; -static int ipx_fd = -1; static uint8 ipx_pack_typ = PACKT_CORE; static int last_sequence = -9999; @@ -38,66 +40,80 @@ static NCPRESPONSE *ncpresponse=(NCPRESPONSE*)&ipxdata; static uint8 *responsedata=((uint8*)&ipxdata)+sizeof(NCPRESPONSE); static int requestlen; -static uint8 readbuff[IPX_MAX_DATA+500]; +static uint8 readbuff[IPX_MAX_DATA]; + +static uint8 saved_readbuff[IPX_MAX_DATA]; +static int saved_sequence=-1; static NCPREQUEST *ncprequest = (NCPREQUEST*)readbuff; static uint8 *requestdata = readbuff + sizeof(NCPREQUEST); static int ncp_type; - -static int open_ipx_socket(int wanted_sock) -{ - struct t_bind bind; - ipx_fd=t_open("/dev/ipx", O_RDWR, NULL); - if (ipx_fd < 0) { - if (nw_debug) t_error("t_open !Ok"); - return(-1); - } - U16_TO_BE16(wanted_sock, my_addr.sock); /* actual write socket */ - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)&my_addr; - bind.qlen = 0; /* allways */ - if (t_bind(ipx_fd, &bind, &bind) < 0){ - if (nw_debug) t_error("t_bind !OK"); - close(ipx_fd); - return(-1); - } - XDPRINTF((5, 0, "NWCONN OpenSocket: %s", - visable_ipx_adr((ipxAddr_t *) bind.addr.buf))); - return(0); -} +static int sock_nwbind=-1; static int req_printed=0; + static int ncp_response(int sequence, int completition, int data_len) - { ncpresponse->sequence = (uint8) sequence; ncpresponse->completition = (uint8) completition; - last_sequence = sequence; - if (req_printed) { - XDPRINTF((0,0, "NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x TO %s", - (int)ncpresponse->sequence, (int) ncpresponse->connection, (int)completition, - visable_ipx_adr((ipxAddr_t *) ud.addr.buf))); - } + ncpresponse->reserved = (uint8) 0; + last_sequence = sequence; + if (req_printed) { + XDPRINTF((0,0, "NWCONN NCP_RESP seq:%d, conn:%d, compl=0x%x task=%d TO %s", + (int)ncpresponse->sequence, (int) ncpresponse->connection, (int)completition, + (int)ncpresponse->task, visable_ipx_adr((ipxAddr_t *) ud.addr.buf))); + } ud.udata.len = ud.udata.maxlen = sizeof(NCPRESPONSE) + data_len; - if (t_sndudata(ipx_fd, &ud) < 0){ + if (t_sndudata(FD_NCP_OUT, &ud) < 0){ if (nw_debug) t_error("t_sndudata in NWCONN !OK"); return(-1); } return(0); } +static int call_nwbind(void) +{ + ipxAddr_t to_addr; + memcpy(&to_addr, &my_addr, sizeof(ipxAddr_t)); + U16_TO_BE16(sock_nwbind, to_addr.sock); + ud.udata.len = ud.udata.maxlen = sizeof(NCPREQUEST) + requestlen; + ud.udata.buf = (char*)&readbuff; + ud.addr.buf = (char*)&to_addr; + if (t_sndudata(FD_NCP_OUT, &ud) < 0){ + if (nw_debug) t_error("t_sndudata in NWCONN !OK"); + ud.addr.buf = (char*)&from_addr; + ud.udata.buf = (char*)&ipxdata; + return(-1); + } + ud.addr.buf = (char*)&from_addr; + ud.udata.buf = (char*)&ipxdata; + return(0); +} + static void pr_debug_request() { if (req_printed++) return; - XDPRINTF((0, 0, "NCP REQUEST:type:0x%x, seq:%d, task:%d, reserved:0x%x, func:0x%x", + if (ncp_type == 0x2222) { + int ufunc = 0; + switch (ncprequest->function) { + case 0x16 : + case 0x17 : ufunc = (int) *(requestdata+2); break; + default : break; + } /* switch */ + XDPRINTF((0, 0, "NCP REQUEST: func=0x%02x, ufunc=0x%02x, seq:%03d, task:%02d", + (int)ncprequest->function, ufunc, + (int)ncprequest->sequence, + (int)ncprequest->task)); + } else { + XDPRINTF((0, 0, "Got NCP:type:0x%x, seq:%d, task:%d, reserved:0x%x, func=0x%x", ncp_type, (int)ncprequest->sequence, (int)ncprequest->task, (int)ncprequest->reserved, (int)ncprequest->function)); + } if (requestlen > 0){ int j = requestlen; uint8 *p=requestdata; @@ -112,7 +128,7 @@ static void pr_debug_request() } static int test_handle = -1; -static void handle_ncp_serv() +static int handle_ncp_serv(void) { int function = (int)ncprequest->function; int completition = 0; /* first set */ @@ -122,11 +138,11 @@ static void handle_ncp_serv() if (last_sequence == (int)ncprequest->sequence && ncp_type != 0x1111){ /* send the same again */ - if (t_sndudata(ipx_fd, &ud) < 0){ + if (t_sndudata(FD_NCP_OUT, &ud) < 0){ if (nw_debug) t_error("t_sndudata !OK"); } XDPRINTF((2,0, "Sequence %d is written twice", (int)ncprequest->sequence)); - return; + return(0); } req_printed=0; @@ -633,7 +649,6 @@ static void handle_ncp_serv() } break; -#if 1 case 0x17 : { /* FILE SERVER ENVIRONMENT */ /* uint8 len = *(requestdata+1); */ uint8 ufunc = *(requestdata+2); @@ -652,23 +667,15 @@ static void handle_ncp_serv() xdata->nw_debug = (uint8)org_nw_debug; nw_debug = org_nw_debug = (int) *(rdata+1); data_len = 1; - } else completition=0xff; + } else return(-1); } break; #endif case 0x14: - case 0x18: { /* ncpserv have change the structure */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 div[3]; /* 0, len + ufunc */ - uint8 align[2]; /* alignment ncpserv */ - int gid; /* ncpserv */ - int uid; /* ncpserv */ - } *input = (struct INPUT *)ncprequest; - set_guid(input->gid, input->uid); - } - break; + case 0x18: + return(-2); /* nwbind must do prehandling */ + case 0x0f: { /* Scan File Information */ struct INPUT { @@ -687,7 +694,8 @@ static void handle_ncp_serv() struct OUTPUT { uint8 sequence[2]; /* next sequence */ - NW_FILE_INFO f; + /* NW_FILE_INFO f; */ + uint8 f[sizeof(NW_FILE_INFO)]; uint8 owner_id[4]; uint8 archive_date[2]; uint8 archive_time[2]; @@ -695,15 +703,15 @@ static void handle_ncp_serv() } *xdata = (struct OUTPUT*)responsedata; int len = input->len; int searchsequence; + NW_FILE_INFO f; memset(xdata, 0, sizeof(struct OUTPUT)); - - searchsequence = nw_search( (uint8*) &(xdata->f), + searchsequence = nw_search( (uint8*) &f, (int)input->dir_handle, (int) GET_BE16(input->sequence), (int) input->search_attrib, input->data, len); - 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 */ data_len = sizeof(struct OUTPUT); @@ -712,56 +720,40 @@ static void handle_ncp_serv() break; case 0x10: { /* Set File Information */ - completition = 0xfb; + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 div[3]; /* 0, len + ufunc */ + uint8 f[sizeof(NW_FILE_INFO) - 14]; /* no name */ + uint8 owner_id[4]; + uint8 archive_date[2]; + uint8 archive_time[2]; + uint8 reserved[56]; + uint8 dir_handle; + uint8 search_attrib; /* 0: NONE */ + /* 02: HIDDEN */ + /* 04: SYSTEM */ + /* 06: BOTH */ + /* 0x10: DIR */ + uint8 len; + uint8 data[2]; /* Name */ + } *input = (struct INPUT *)ncprequest; + NW_FILE_INFO f; + int result; + memcpy(((uint8*)&f)+14, input->f, sizeof(NW_FILE_INFO)-14); + result = nw_set_file_information((int)input->dir_handle, + input->data, + (int)input->len, + (int)input->search_attrib, &f); + /* no reply packet */ + if (result <0) completition = (uint8)-result; } break; case 0x68: /* create queue job and file old */ - case 0x79: { /* create queue job and file */ - /* some of this call is handled in ncpserv !! */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 packetlen[2]; /* low high */ - uint8 func; /* 0x79 or 0x68 */ - uint8 queue_id[4]; /* Queue ID */ - uint8 queue_job[280]; /* oldsize is 256 */ - /* this is added by ncpserv */ - uint8 dir_nam_len; /* len of dirname */ - uint8 dir_name[1]; - } *input = (struct INPUT *) (ncprequest); - int result = nw_creat_queue(ncpresponse->connection, - input->queue_id, - input->queue_job, - input->dir_name, - (int)input->dir_nam_len, - (ufunc == 0x68) ); - if (!result) { - data_len = (ufunc == 0x68) ? 54 : 78; - memcpy(responsedata, input->queue_job, data_len); - } else completition= (uint8)-result; - } - break; - - case 0x69: /* close file and start queue old ?? */ - case 0x7f: { /* close file and start queue */ - struct INPUT { - uint8 header[7]; /* Requestheader */ - uint8 packetlen[2]; /* low high */ - uint8 func; /* 0x7f or 0x6f */ - uint8 queue_id[4]; /* Queue ID */ - uint8 job_id[4]; /* result from creat queue */ - /* if 0x69 then only 2 byte ! */ - /* this is added by ncpserv */ - uint8 prc_len; /* len of printcommand */ - uint8 prc[1]; /* printcommand */ - } *input = (struct INPUT *) (ncprequest); - int result = nw_close_file_queue(input->queue_id, - input->job_id, - input->prc, - input->prc_len); - if (result < 0) completition = (uint8)-result; - } - break; + case 0x69: /* close file and start queue old ?? */ + case 0x79: /* create queue job and file */ + case 0x7f: /* close file and start queue */ + return(-2); /* nwbind must do prehandling */ case 0xf3: { /* Map Direktory Number TO PATH */ XDPRINTF((2,0, "TODO: Map Directory Number TO PATH")); @@ -775,12 +767,11 @@ static void handle_ncp_serv() } break; - default : completition = 0xfb; + default : return(-1); break; } /* switch (ufunc) */ } /* case 0x17 */ break; -#endif case 0x18 : /* End of Job */ nw_free_handles((ncprequest->task > 0) ? @@ -790,6 +781,7 @@ static void handle_ncp_serv() case 0x19 : /* logout, some of this call is handled in ncpserv. */ nw_free_handles(0); set_default_guid(); + return(-1); /* nwbind must do rest */ break; case 0x1a : /* lock file */ @@ -1266,7 +1258,11 @@ static void handle_ncp_serv() #endif - default : completition = 0xfb; /* unknown request */ +#if 0 + case 0x68 : /* NDS NCP, NDS Fragger Protokoll ?? */ +#endif + + default : completition = 0xfb; /* unknown request */ break; } /* switch function */ @@ -1294,8 +1290,87 @@ static void handle_ncp_serv() XDPRINTF((0,1, NULL)); } } +#if 0 + ncpresponse->task = ncprequest->task; +#endif ncp_response(ncprequest->sequence, completition, data_len); nw_debug = org_nw_debug; + return(0); +} + +static void handle_after_bind() +{ + NCPREQUEST *ncprequest = (NCPREQUEST*) saved_readbuff; + uint8 *requestdata = saved_readbuff + sizeof(NCPREQUEST); + uint8 *bindresponse = readbuff + sizeof(NCPRESPONSE); + int data_len = 0; + int completition = 0; + switch (ncprequest->function) { + case 0x17 : { /* FILE SERVER ENVIRONMENT */ + uint8 ufunc = *(requestdata+2); + uint8 *rdata = requestdata+3; + switch (ufunc) { + case 0x14: + case 0x18: { /* ncpserv have change the structure */ + set_guid(*((int*)bindresponse), *((int*)(bindresponse+sizeof(int)))); + } + break; + + case 0x68: /* create queue job and file old */ + case 0x79: { /* create queue job and file */ + /* nwbind must do prehandling */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 packetlen[2]; /* low high */ + uint8 func; /* 0x79 or 0x68 */ + uint8 queue_id[4]; /* Queue ID */ + uint8 queue_job[280]; /* oldsize is 256 */ + } *input = (struct INPUT *) (ncprequest); + struct RINPUT { + uint8 dir_nam_len; /* len of dirname */ + uint8 dir_name[1]; + } *rinput = (struct RINPUT *) (bindresponse); + int result = nw_creat_queue(ncpresponse->connection, + input->queue_id, + input->queue_job, + rinput->dir_name, + (int)rinput->dir_nam_len, + (ufunc == 0x68) ); + if (!result) { + data_len = (ufunc == 0x68) ? 54 : 78; + memcpy(responsedata, input->queue_job, data_len); + } else completition= (uint8)-result; + } + break; + + case 0x69: /* close file and start queue old ?? */ + case 0x7f: { /* close file and start queue */ + struct INPUT { + uint8 header[7]; /* Requestheader */ + uint8 packetlen[2]; /* low high */ + uint8 func; /* 0x7f or 0x6f */ + uint8 queue_id[4]; /* Queue ID */ + uint8 job_id[4]; /* result from creat queue */ + /* if 0x69 then only 2 byte ! */ + } *input = (struct INPUT *) (ncprequest); + struct RINPUT { + uint8 prc_len; /* len of printcommand */ + uint8 prc[1]; /* printcommand */ + } *rinput = (struct RINPUT *) (bindresponse); + int result = nw_close_file_queue(input->queue_id, + input->job_id, + rinput->prc, + rinput->prc_len); + if (result < 0) completition = (uint8)-result; + } + break; + default : completition = 0xfb; + } + } + break; + default : completition = 0xfb; + } /* switch */ + ncp_response(ncprequest->sequence, completition, data_len); } extern int t_errno; @@ -1304,12 +1379,7 @@ static void close_all(void) { nw_exit_connect(); close(0); - if (ipx_fd > -1){ - while (t_unbind(ipx_fd) < 0) { - if (t_errno != TOUTSTATE) break; - } - t_close(ipx_fd); - } + close(FD_NCP_OUT); } static int fl_get_int=0; @@ -1349,39 +1419,39 @@ int main(int argc, char **argv) ipxAddr_t client_addr; struct t_unitdata iud; #endif - int wanted_sock = (argc==5) ? atoi(*(argv+4)) : 0; - if (argc == 5) argc--; - if (argc != 4) { - fprintf(stderr, "usage nwconn PID FROM_ADDR Connection [sock]\n"); + if (argc != 5) { + fprintf(stderr, "usage nwconn PID FROM_ADDR Connection nwbindsock\n"); exit(1); } else father_pid = atoi(*(argv+1)); setuid(0); setgid(0); init_tools(NWCONN, atoi(*(argv+3))); + memset(saved_readbuff, 0, sizeof(saved_readbuff)); XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s", father_pid, *(argv+2), *(argv+3))); adr_to_ipx_addr(&from_addr, *(argv+2)); + #if CALL_NWCONN_OVER_SOCKET adr_to_ipx_addr(&client_addr, *(argv+2)); #endif if (nw_init_connect()) exit(1); + sscanf(argv[4], "%x", &sock_nwbind); + #ifdef LINUX set_emu_tli(); #endif last_sequence = -9999; -#if !CALL_NWCONN_OVER_SOCKET - if (open_ipx_socket(wanted_sock)) exit(1); -#else - ipx_fd =0; + if (get_ipx_addr(&my_addr)) exit(1); +#if CALL_NWCONN_OVER_SOCKET # if 1 # ifdef SIOCIPXNCPCONN { int conn = atoi(*(argv+3)); - int result = ioctl(ipx_fd, SIOCIPXNCPCONN, &conn); + int result = ioctl(0, SIOCIPXNCPCONN, &conn); XDPRINTF((2, 0, "ioctl:SIOCIPXNCPCONN result=%d", result)); } # endif @@ -1422,7 +1492,7 @@ int main(int argc, char **argv) while (1) { #if CALL_NWCONN_OVER_SOCKET int rcv_flags = 0; - int data_len = (t_rcvudata(ipx_fd, &iud, &rcv_flags) > -1) + int data_len = (t_rcvudata(0, &iud, &rcv_flags) > -1) ? iud.udata.len : -1; #else int data_len = read(0, readbuff, sizeof(readbuff)); @@ -1437,28 +1507,32 @@ int main(int argc, char **argv) if (data_len > 0) { XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len)); if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) { - /* OK for direct sending */ data_len -= sizeof(NCPRESPONSE); - XDPRINTF((99,0, "NWCONN:direct sending:type 0x3333, completition=0x%x, len=%d", + if (saved_sequence > -1 && ((int)(ncprequest->sequence) == saved_sequence) + && !ncprequest->function) { + handle_after_bind(); + } else { + /* OK for direct sending */ + XDPRINTF((6,0, "NWCONN:direct sending:type 0x3333, completition=0x%x, len=%d", (int)(ncprequest->function), data_len)); - if (data_len) memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len); - ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status; - ncp_response((int)(ncprequest->sequence), (int)(ncprequest->function), data_len); + if (data_len) + memcpy(responsedata, readbuff+sizeof(NCPRESPONSE), data_len); + ncpresponse->connect_status = ((NCPRESPONSE*)readbuff)->connect_status; + ncp_response((int)(ncprequest->sequence), + (int)(ncprequest->function), data_len); + } + saved_sequence = -1; } else { /* this calls I must handle */ - requestlen = data_len - sizeof(NCPREQUEST); -#if 0 /* CALL_NWCONN_OVER_SOCKET */ -#ifdef SIOCIPXNCPCONN - if (ncp_type == 0x2222 && - (0x17 == ncprequest->function || 0x15 == ncprequest->function) - && IPXCMPSOCK (from_addr.sock, client_addr.sock) - && IPXCMPNODE (from_addr.node, client_addr.node) - && IPXCMPNET (from_addr.net, client_addr.net) { - /* this call must be prehandled by ncpserv */ - XDPRINTF((2,0, "SEND TO NCPSERV")); - } else -#endif -#endif - handle_ncp_serv(); + int result; + requestlen = data_len - sizeof(NCPREQUEST); + if (0 != (result = handle_ncp_serv()) ) { + if (result == -2) { /* here the actual call must be saved */ + memcpy(saved_readbuff, readbuff, data_len); + saved_sequence = (int)(ncprequest->sequence); + } else saved_sequence = -1; + /* this call must go to nwbind */ + call_nwbind(); + } } } } /* while */ diff --git a/nwdbm.c b/nwdbm.c index 6e96b2b..39ec1aa 100644 --- a/nwdbm.c +++ b/nwdbm.c @@ -1,4 +1,4 @@ -/* nwdbm.c 22-Feb-96 data base for mars_nwe */ +/* nwdbm.c 20-Mar-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 @@ -1033,9 +1033,11 @@ int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key) return (memcmp(akt_key, keybuff, sizeof(keybuff)) ? -0xff : 0); } else { if (password_scheme & PW_SCHEME_LOGIN) { - MYPASSWD *pw = nw_getpwnam(obj_id); - if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd)) - return(-0xff); + if (!(password_scheme & PW_SCHEME_ALLOW_EMPTY_PW)) { + MYPASSWD *pw = nw_getpwnam(obj_id); + if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd)) + return(-0xff); + } if (obj_id == 1) return(-0xff); } return(0); /* no password */ @@ -1242,7 +1244,7 @@ static void add_group(char *name, char *unname, char *password) static int get_sys_unixname(uint8 *unixname, uint8 *sysentry) { uint8 sysname[256]; - char optionstr[256]; + uint8 optionstr[256]; int founds = sscanf((char*)sysentry, "%s %s %s",sysname, unixname, optionstr); if (founds > 1 && *unixname) { struct stat statb; @@ -1324,14 +1326,15 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr) while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { if (1 == what && !*sysentry) { xstrcpy(sysentry, buff); - } if (6 == what) { /* Server Version */ + } else if (6 == what) { /* Server Version */ tells_server_version = atoi(buff); } else if (7 == what) { /* password_scheme */ int pwscheme = atoi(buff); password_scheme = 0; switch (pwscheme) { case 9 : password_scheme |= PW_SCHEME_GET_KEY_FAIL; - case 8 : password_scheme |= PW_SCHEME_LOGIN; + case 8 : password_scheme |= PW_SCHEME_ALLOW_EMPTY_PW; + case 7 : password_scheme |= PW_SCHEME_LOGIN; case 1 : password_scheme |= PW_SCHEME_CHANGE_PW; break; default : password_scheme = 0; diff --git a/nwdbm.h b/nwdbm.h index 65a03ef..8dcb8f1 100644 --- a/nwdbm.h +++ b/nwdbm.h @@ -63,9 +63,11 @@ typedef struct { extern int tells_server_version; extern int password_scheme; -#define PW_SCHEME_CHANGE_PW 1 -#define PW_SCHEME_LOGIN 2 -#define PW_SCHEME_GET_KEY_FAIL 4 +#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 + extern void sync_dbm(void); diff --git a/nwserv.c b/nwserv.c index b75cdeb..8c9c359 100644 --- a/nwserv.c +++ b/nwserv.c @@ -1,4 +1,4 @@ -/* nwserv.c 10-Mar-96 */ +/* nwserv.c 20-Mar-96 */ /* (C)opyright (C) 1993,1996 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -58,9 +58,9 @@ uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */ #define NEEDED_SOCKETS (sizeof(ipx_sock_nummern) / sizeof(uint16)) #if FILE_SERVER_INACTIV -# define NEEDED_POLLS (NEEDED_SOCKETS) -#else # define NEEDED_POLLS (NEEDED_SOCKETS+1) +#else +# define NEEDED_POLLS (NEEDED_SOCKETS+2) #endif static uint16 sock_nummern [NEEDED_SOCKETS]; @@ -75,10 +75,11 @@ static int nw386_found = 0; static int client_mode = 0; static int ipxdebug = 0; static int pid_ncpserv = -1; -#if !CALL_NCPSERV_OVER_SOCKET -static int fd_ncpserv_out = -1; /* ctrl-pipe out to ncpserv */ -#endif -static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */ +static int fd_ncpserv_in = -1; /* ctrl-pipe in from ncpserv */ + +static int pid_nwbind = -1; +static int sock_nwbind = -1; +static int fd_nwbind_in = -1; /* ctrl-pipe in from nnwbind */ static time_t akttime_stamp = 0; static int broadmillisecs = 2000; /* 2 sec */ @@ -90,45 +91,41 @@ static int save_ipx_routes = 0; static uint8 *station_fn=NULL; static int nearest_request_flag=0; -#if !FILE_SERVER_INACTIV static void add_wdata(IPX_DATA *d, char *data, int size) { memcpy(d->owndata.d.data+d->owndata.d.size, data, size); d->owndata.d.size+=size; } -static void write_wdata(IPX_DATA *d, int what) +static void write_wdata(IPX_DATA *d, int what, int sock) { -#if CALL_NCPSERV_OVER_SOCKET ipxAddr_t toaddr; -#endif d->owndata.d.function=what; d->owndata.d.size +=sizeof(int); -#if CALL_NCPSERV_OVER_SOCKET - memset(d->owndata.type, 0xee, 4); + memset(d->owndata.type, 0xee, 2); + d->owndata.sequence = 0; + d->owndata.connection = 0; memcpy(&toaddr, &my_server_adr, sizeof(ipxAddr_t)); - U16_TO_BE16(SOCK_NCP, toaddr.sock); + U16_TO_BE16(sock, toaddr.sock); send_ipx_data(-1, 17, - 4 + sizeof(int)+d->owndata.d.size, (char*)d, - &toaddr, "TO NCPSERV"); -#else - write(fd_ncpserv_out, (char*) &(d->owndata.d), - sizeof(int)+d->owndata.d.size); -#endif + OWN_DATA_IPX_BASE_SIZE + sizeof(int)+d->owndata.d.size, (char*)d, + &toaddr, (sock == SOCK_NCP) ? "NCPSERV" : "NWBIND" ); d->owndata.d.size=0; } -static void write_to_ncpserv(int what, int connection, - char *data, int data_size) +static void write_to_sons(int what, int connection, + char *data, int data_size, int sock) { IPX_DATA ipxd; ipxd.owndata.d.size = 0; - XDPRINTF((2, 0, "write_to_ncpserv what=0x%x, conn=%d, data_size=%d", + XDPRINTF((2, 0, "write_to_sons what=0x%x, conn=%d, data_size=%d", what, connection, data_size)); switch (what) { - case 0x5555 : /* kill connection */ + case 0x2222 : /* insert connection */ add_wdata(&ipxd, (char*) &connection, sizeof(int)); + add_wdata(&ipxd, (char*) &data_size, sizeof(int)); + add_wdata(&ipxd, data, data_size); break; case 0x3333 : /* 'bindery' calls */ @@ -136,6 +133,10 @@ static void write_to_ncpserv(int what, int connection, add_wdata(&ipxd, data, data_size); break; + case 0x5555 : /* kill connection */ + add_wdata(&ipxd, (char*) &connection, sizeof(int)); + break; + case 0xeeee : /* hup, read init */ break; @@ -143,18 +144,21 @@ static void write_to_ncpserv(int what, int connection, add_wdata(&ipxd, (char*) &what, sizeof(int)); break; - default : return; + default : return; } - write_wdata(&ipxd, what); + write_wdata(&ipxd, what, sock); } + +#if !FILE_SERVER_INACTIV +# define write_to_ncpserv(what, connection, data, data_size) \ + write_to_sons((what), (connection), (data), (data_size), SOCK_NCP) #else -static void write_to_ncpserv(int what, int connection, - char *data, int data_size) -{ -;; /* dummy */ -} +# define write_to_ncpserv(what, connection, data, data_size) /* */ #endif +#define write_to_nwbind(what, connection, data, data_size) \ + write_to_sons((what), (connection), (data), (data_size), sock_nwbind) + void ins_del_bind_net_addr(uint8 *name, int styp, ipxAddr_t *adr) { uint8 buf[1024]; @@ -179,7 +183,7 @@ void ins_del_bind_net_addr(uint8 *name, int styp, ipxAddr_t *adr) strmaxcpy(p+1, name, *p); len += (*p+1); p+=(*p + 1); } - write_to_ncpserv(0x3333, 0, (char *)buf, len); + write_to_nwbind(0x3333, 0, (char *)buf, len); } static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode) @@ -212,14 +216,8 @@ static int open_ipx_socket(uint16 sock_nr, int nr, int open_mode) static int start_ncpserv(char *nwname, ipxAddr_t *addr) { #if !FILE_SERVER_INACTIV -#if !CALL_NCPSERV_OVER_SOCKET - int fds_out[2]; -#endif int fds_in[2]; int pid; -#if !CALL_NCPSERV_OVER_SOCKET - if (pipe(fds_out) < 0) return(-1); -#endif if (pipe(fds_in) < 0) return(-1); switch (pid=fork()) { @@ -227,43 +225,104 @@ static int start_ncpserv(char *nwname, ipxAddr_t *addr) char *progname="ncpserv"; char addrstr[100]; char pathname[300]; + char nwbindsock[20]; int j = FD_NWSERV; -#if !CALL_NCPSERV_OVER_SOCKET - close(fds_out[1]); /* no need to write */ - dup2(fds_out[0], 0); /* becommes stdin */ - close(fds_out[0]); /* no longer needed */ -#endif close(fds_in[0]); /* no need to read */ dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */ close(fds_in[1]); /* no longer needed */ while (j++ < 100) close(j); /* close all > 4 */ + U16_TO_BE16(SOCK_NCP, addr->sock); ipx_addr_to_adr(addrstr, addr); + sprintf(nwbindsock, "%04x", sock_nwbind); execl(get_exec_path(pathname, progname), progname, - nwname, addrstr, NULL); + nwname, addrstr, nwbindsock, NULL); exit(1); } break; case -1: -#if !CALL_NCPSERV_OVER_SOCKET - close(fds_out[0]); - close(fds_out[1]); -#endif close(fds_in[0]); close(fds_in[1]); return(-1); /* error */ } -#if !CALL_NCPSERV_OVER_SOCKET - fds_out[0] = -1; - fd_ncpserv_out = fds_out[1]; -#endif - fds_in[1] = -1; + close(fds_in[1]); fd_ncpserv_in = fds_in[0]; pid_ncpserv = pid; #endif + U16_TO_BE16(SOCK_NCP, addr->sock); return(0); /* OK */ } +static int start_nwbind(char *nwname, ipxAddr_t *addr) +{ +#if !FILE_SERVER_INACTIV + int fds_in[2]; + int pid; + struct t_bind bind; + int ipx_fd=t_open("/dev/ipx", O_RDWR, NULL); + if (ipx_fd < 0) { + errorp(1, "start_nwbind", "t_open"); + return(-1); + } + U16_TO_BE16(SOCK_AUTO, addr->sock); + bind.addr.len = sizeof(ipxAddr_t); + bind.addr.maxlen = sizeof(ipxAddr_t); + bind.addr.buf = (char*)addr; + bind.qlen = 0; /* allways */ + if (t_bind(ipx_fd, &bind, &bind) < 0){ + errorp(1, "start_nwbind", "t_bind"); + t_close(ipx_fd); + return(-1); + } + if (pipe(fds_in) < 0){ + errorp(1, "start_nwbind", "pipe"); + t_close(ipx_fd); + return(-1); + } + sock_nwbind = (int) GET_BE16(addr->sock); + + switch (pid=fork()) { + case 0 : { /* new Process */ + char *progname="nwbind"; + char addrstr[100]; + char pathname[300]; + char nwbindsock[20]; + int j = FD_NWSERV; + + close(fds_in[0]); /* no need to read */ + if (fds_in[1] != FD_NWSERV) { + dup2(fds_in[1], FD_NWSERV); /* becommes fd FD_NWSERV */ + close(fds_in[1]); /* no longer needed */ + } + dup2(ipx_fd, 0); /* stdin */ + close(ipx_fd); + + while (j++ < 100) close(j); /* close all > FD_NWSERV */ + U16_TO_BE16(SOCK_NCP, addr->sock); + ipx_addr_to_adr(addrstr, addr); + sprintf(nwbindsock, "%04x", sock_nwbind); + + execl(get_exec_path(pathname, progname), progname, + nwname, addrstr, nwbindsock, NULL); + exit(1); + } + break; + + case -1: close(fds_in[0]); + close(fds_in[1]); + t_close(ipx_fd); + errorp(1, "start_nwbind", "t_bind"); + return(-1); /* error */ + } + close(fds_in[1]); + close(ipx_fd); + fd_nwbind_in = fds_in[0]; + pid_nwbind = pid; +#endif + return(0); /* OK */ +} + + static int start_nwclient(void) { switch (fork()){ @@ -459,16 +518,16 @@ static int find_station_match(int entry, ipxAddr_t *addr) { int matched = 0; if (station_fn && *station_fn) { - FILE *f=fopen(station_fn, "r"); + FILE *f=fopen((char*)station_fn, "r"); if (f) { - char buff[200]; - char addrstring[100]; + uint8 buff[200]; + uint8 addrstring[100]; int what; - ipx_addr_to_adr(addrstring, addr); + ipx_addr_to_adr((char*)addrstring, addr); upstr(addrstring); while (0 != (what = get_ini_entry(f, 0, buff, sizeof(buff)))){ if (what == entry) { - char *p = buff + strlen(buff); + uint8 *p = buff + strlen((char*)buff); while (p-- > buff && *p==32) *p='\0'; upstr(buff); if (name_match(addrstring, buff)) { @@ -730,54 +789,6 @@ static void handle_event(int fd, uint16 socknr, int slot) } } -#if 0 -static int get_ipx_addr(ipxAddr_t *addr) -{ - int fd=t_open("/dev/ipx", O_RDWR, NULL); - struct t_optmgmt optb; - int result = -1; - if (fd < 0) { - t_error("t_open !Ok"); - return(-1); - } - optb.opt.maxlen = optb.opt.len = sizeof(ipxAddr_t); - optb.opt.buf = (char*)addr; - optb.flags = 0; - result = t_optmgmt(fd, &optb, &optb); - if (result < 0) t_error("t_optmgmt !Ok"); - else result=0; - t_close(fd); - return(result); -} -#else - -static int get_ipx_addr(ipxAddr_t *addr) -{ - int fd=t_open("/dev/ipx", O_RDWR, NULL); - struct t_bind bind; - int result = -1; - if (fd < 0) { - t_error("t_open !Ok"); - return(-1); - } - bind.addr.len = sizeof(ipxAddr_t); - bind.addr.maxlen = sizeof(ipxAddr_t); - bind.addr.buf = (char*)addr; - bind.qlen = 0; /* ever */ - memset(addr, 0, sizeof(ipxAddr_t)); - - if (t_bind(fd, &bind, &bind) < 0) - t_error("tbind:get_ipx_addr"); - else { - result=0; - t_unbind(fd); - } - t_close(fd); - return(result); -} -#endif - - static void get_ini(int full) { FILE *f = open_nw_ini(); @@ -788,9 +799,9 @@ static void get_ini(int full) upstr((uint8*)my_nwname); } if (f){ - char buff[500]; + uint8 buff[500]; int what; - while (0 != (what=get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { + while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { char inhalt[500]; char inhalt2[500]; char inhalt3[500]; @@ -956,12 +967,6 @@ static void close_all(void) if (pid_ncpserv > 0) { int status; -#if !CALL_NCPSERV_OVER_SOCKET - if (fd_ncpserv_out > -1) { - close(fd_ncpserv_out); - fd_ncpserv_out =-1; - } -#endif if (fd_ncpserv_in > -1) { close(fd_ncpserv_in); fd_ncpserv_in = -1; @@ -971,6 +976,17 @@ static void close_all(void) kill(pid_ncpserv, SIGKILL); /* kill ncpserv */ } + if (pid_nwbind > 0) { + int status; + if (fd_nwbind_in > -1) { + close(fd_nwbind_in); + fd_nwbind_in = -1; + } + kill(pid_nwbind, SIGQUIT); /* terminate ncpserv */ + waitpid(pid_nwbind, &status, 0); + kill(pid_nwbind, SIGKILL); /* kill ncpserv */ + } + #ifdef LINUX # if INTERNAL_RIP_SAP if (!save_ipx_routes) { @@ -990,6 +1006,7 @@ 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); fprintf(stderr, "\007"); @@ -1020,6 +1037,7 @@ static void handle_hup_reqest(void) XDPRINTF((2,0, "Got HUP, reading ini.")); get_ini(0); write_to_ncpserv(0xeeee, 0, NULL, 0); /* inform ncpserv */ + write_to_nwbind( 0xeeee, 0, NULL, 0); /* inform nwbind */ fl_get_int=0; } @@ -1069,17 +1087,18 @@ int main(int argc, char **argv) polls[j].fd = -1; } } - U16_TO_BE16(SOCK_NCP, my_server_adr.sock); - if (!start_ncpserv(my_nwname, &my_server_adr)) { + 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 !FILE_SERVER_INACTIV { ipxAddr_t server_adr_sap; - polls[NEEDED_SOCKETS].fd = fd_ncpserv_in; + polls[NEEDED_SOCKETS+1].fd = fd_ncpserv_in; U16_TO_BE16(SOCK_NCP, my_server_adr.sock); memcpy(&server_adr_sap, &my_server_adr, sizeof(ipxAddr_t)); U16_TO_BE16(SOCK_SAP, server_adr_sap.sock); @@ -1110,45 +1129,56 @@ int main(int argc, char **argv) if (p->revents & ~POLLIN) errorp(0, "STREAM error", "revents=0x%x", p->revents ); else { - if (p->fd == fd_ncpserv_in) { + if (p->fd > -1) { int what; int conn; int size; - ipxAddr_t adr; - if (sizeof(int) == read(fd_ncpserv_in, + uint8 buf[200]; + if (sizeof(int) == read(p->fd, (char*)&what, sizeof(int))) { - XDPRINTF((2, 0, "GOT ncpserv_in what=0x%x", what)); + XDPRINTF((2, 0, "GOT %s_in what=0x%x", + (p->fd == fd_ncpserv_in) ? "ncpserv" : "nwbind" , what)); switch (what) { case 0x2222 : /* insert wdog connection */ - if (sizeof(int) == read(fd_ncpserv_in, + if (sizeof(int) == read(p->fd, (char*)&conn, sizeof(int)) - && sizeof(int) == read(fd_ncpserv_in, + && sizeof(int) == read(p->fd, (char*)&size, sizeof(int)) - && sizeof(ipxAddr_t) == read(fd_ncpserv_in, - (char*)&adr, size)) - insert_wdog_conn(conn, &adr); + && sizeof(ipxAddr_t) + sizeof(uint16) + == read(p->fd, + (char*)buf, size)) { + insert_wdog_conn(conn, (ipxAddr_t*)buf); + write_to_nwbind(what, conn, (char*)buf, size); + } break; case 0x4444 : /* reset wdog connection = 0 */ /* force test wdog conn 1 = 1 */ /* force test wdog conn 2 = 2 */ /* remove wdog = 99 */ - if (sizeof(int) == read(fd_ncpserv_in, + if (sizeof(int) == read(p->fd, (char*)&conn, sizeof(int)) - && sizeof(int) == read(fd_ncpserv_in, + && sizeof(int) == read(p->fd, (char*)&what, sizeof(what))) modify_wdog_conn(conn, what); if (what > 0 && what < 99) call_wdog++; break; + case 0x5555 : /* close connection */ + if (sizeof(int) == read(p->fd, + (char*)&conn, sizeof(int))) + modify_wdog_conn(conn, 99); + write_to_nwbind(what, conn, NULL, 0); + break; + case 0x6666 : /* bcast message */ - if (sizeof(int) == read(fd_ncpserv_in, + if (sizeof(int) == read(p->fd, (char*)&conn, sizeof(int))) send_bcasts(conn); break; case 0xffff : /* down file server */ - if (sizeof(int) == read(fd_ncpserv_in, + if (sizeof(int) == read(p->fd, (char*)&conn, sizeof(int)) && conn == what) { down_server(); diff --git a/nwvolume.c b/nwvolume.c index d9d60ee..0190109 100644 --- a/nwvolume.c +++ b/nwvolume.c @@ -1,4 +1,4 @@ -/* nwvolume.c 07-Feb-96 */ +/* nwvolume.c 20-Mar-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -53,8 +53,8 @@ void nw_init_volumes(FILE *f) } rewind(f); used_nw_volumes = 0; - while (0 != (what = get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { - if ( what == 1 && used_nw_volumes < MAX_NW_VOLS && strlen(buff) > 3){ + 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]; uint8 unixname[256]; char optionstr[256]; @@ -63,7 +63,7 @@ void nw_init_volumes(FILE *f) int founds = sscanf((char*)buff, "%s %s %s",sysname, unixname, optionstr); if (founds > 1) { new_str(nw_volumes[used_nw_volumes].sysname, sysname); - len = strlen(unixname); + len = strlen((char*)unixname); if (unixname[len-1] != '/') { unixname[len++] = '/'; unixname[len] = '\0'; @@ -164,10 +164,10 @@ int nw_get_volume_number(uint8 *volname, int namelen) int result = -0x98; /* Volume not exist */ uint8 vname[255]; int j = used_nw_volumes; - strmaxcpy((char*)vname, (char*)volname, namelen); + strmaxcpy(vname, volname, namelen); upstr(vname); while (j--) { - if (!strcmp(nw_volumes[j].sysname, vname)) { + if (!strcmp((char*)nw_volumes[j].sysname, (char*)vname)) { result = j; break; } @@ -182,9 +182,9 @@ int nw_get_volume_name(int volnr, uint8 *volname) int result = -0x98; /* Volume not exist */; if (volnr > -1 && volnr < used_nw_volumes) { if (volname != NULL) { - strcpy(volname, nw_volumes[volnr].sysname); - result = strlen(volname); - } else result= strlen(nw_volumes[volnr].sysname); + strcpy((char*)volname, (char*)nw_volumes[volnr].sysname); + result = strlen((char*)volname); + } else result= strlen((char*)nw_volumes[volnr].sysname); } else { if (NULL != volname) *volname = '\0'; if (volnr < MAX_NW_VOLS) result=0; @@ -233,7 +233,7 @@ int nw_get_fs_usage(uint8 *volname, struct fs_usage *fsu) /* returns 0 if OK, else errocode < 0 */ { int volnr = nw_get_volume_number(volname, strlen((char*)volname)); - return((volnr>-1 && !get_fs_usage(nw_volumes[volnr].unixname, fsu)) ? 0 : -1); + return((volnr>-1 && !get_fs_usage((char*)nw_volumes[volnr].unixname, fsu)) ? 0 : -1); } int get_volume_options(int volnr, int mode) diff --git a/tools.c b/tools.c index 5d98636..9504a9f 100644 --- a/tools.c +++ b/tools.c @@ -1,4 +1,4 @@ -/* tools.c 09-Mar-96 */ +/* tools.c 20-Mar-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * * This program is free software; you can redistribute it and/or modify @@ -38,7 +38,8 @@ static char *modnames[] = "NWSERV ", "NCPSERV", "NWCONN ", - "NWCLIEN" }; + "NWCLIEN", + "NWBIND " }; static char *get_modstr(void) { @@ -148,7 +149,7 @@ FILE *open_nw_ini(void) return(f); } -int get_ini_entry(FILE *f, int entry, char *str, int strsize) +int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize) /* returns ini_entry or 0 if nothing found */ { char buff[512]; @@ -200,10 +201,10 @@ char *get_exec_path(char *buff, char *progname) int get_ini_int(int what) { - char buff[30]; + uint8 buff[30]; int i; if (get_ini_entry(NULL, what, buff, sizeof(buff)) - && 1==sscanf(buff, "%d", &i) ) return(i); + && 1==sscanf((char*)buff, "%d", &i) ) return(i); return(-1); } @@ -225,12 +226,14 @@ static void sig_segv(int isig) XDPRINTF((0, 0, s, my_pid)); fprintf(stderr, "\n"); fprintf(stderr, s, my_pid); +#if 1 (*sigsegv_func)(isig); +#endif } void init_tools(int module, int conn) { - char buff[300]; + uint8 buff[300]; char logfilename[300]; FILE *f=open_nw_ini(); int withlog=0; @@ -241,13 +244,13 @@ void init_tools(int module, int conn) if (f) { int what; while (0 != (what=get_ini_entry(f, 0, buff, sizeof(buff)))) { /* daemonize */ - if (200 == what) dodaemon = atoi(buff); + if (200 == what) dodaemon = atoi((char*)buff); else if (201 == what) { strmaxcpy((uint8*)logfilename, (uint8*)buff, sizeof(logfilename)-1); withlog++; } else if (202 == what) { - new_log = atoi(buff); - } else if (100+module == what) nw_debug=atoi(buff); + new_log = atoi((char*)buff); + } else if (100+module == what) nw_debug=atoi((char*)buff); } fclose(f); } @@ -268,7 +271,8 @@ void init_tools(int module, int conn) } if (NWSERV == module) setsid(); } - if (NWSERV == module || NCPSERV == module) { + if (NWSERV == module || NCPSERV == module || NWBIND == module || + nw_debug > 1) { XDPRINTF((1, 0, "Starting Version: %d.%02dpl%d", _VERS_H_, _VERS_L_, _VERS_P_ )); } diff --git a/tools.h b/tools.h index 970445c..1066780 100644 --- a/tools.h +++ b/tools.h @@ -1,4 +1,4 @@ -/* tools.h : 10-Mar-96 */ +/* tools.h : 20-Mar-96 */ /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany * @@ -20,10 +20,11 @@ #define _TOOLS_H_ /* processes which need tools */ -#define NWSERV 1 -#define NCPSERV 2 -#define NWCONN 3 -#define NWCLIENT 4 +#define NWSERV 1 +#define NCPSERV 2 +#define NWCONN 3 +#define NWCLIENT 4 +#define NWBIND 5 extern FILE *logfile; extern void x_x_xfree(char **p); @@ -42,7 +43,7 @@ extern void dprintf(char *p, ...); extern void xdprintf(int dlevel, int mode, char *p, ...); extern void errorp(int mode, char *what, char *p, ...); extern FILE *open_nw_ini(void); -extern int get_ini_entry(FILE *f, int entry, char *str, int strsize); +extern int get_ini_entry(FILE *f, int entry, uint8 *str, int strsize); extern char *get_exec_path(char *buff, char *progname); extern int get_ini_int(int what); extern void get_ini_debug(int what);