mars_nwe-0.97.pl07

This commit is contained in:
Mario Fetka 2011-11-13 00:38:57 +01:00
parent a051279129
commit 07843f212b
22 changed files with 465 additions and 170 deletions

View File

@ -132,6 +132,10 @@ static int new_dir_handle(ino_t inode, NW_PATH *nwpath)
fh->vol_options = nw_volumes[fh->volume].options; fh->vol_options = nw_volumes[fh->volume].options;
fh->inode = inode; fh->inode = inode;
fh->timestamp = akttime; fh->timestamp = akttime;
fh->sequence = 0;
fh->dirpos = (off_t)0;
if (fh->vol_options & VOL_OPTION_REMOUNT) { if (fh->vol_options & VOL_OPTION_REMOUNT) {
closedir(fh->f); closedir(fh->f);
fh->f = NULL; fh->f = NULL;
@ -219,10 +223,11 @@ static int x_str_match(uint8 *s, uint8 *p)
switch (state){ switch (state){
case 0 : case 0 :
switch (pc) { switch (pc) {
case 255: if (*p == '*' || *p == '?' || *p==0xaa || *p==0xae) continue; case 255: if (*p == '*' || *p == '?'
|| *p==0xaa || *p==0xae || *p=='.') continue;
break; break;
case '\\': /* beliebiges Folgezeichen */ case '\\': /* any following char */
if (*p++ != *s++) return(0); if (*p++ != *s++) return(0);
break; break;
@ -394,7 +399,8 @@ static int get_dir_entry(NW_PATH *nwpath,
char xkpath[256]; char xkpath[256];
uint8 entry[256]; uint8 entry[256];
int volume = nwpath->volume; int volume = nwpath->volume;
int soptions; int soptions;
int akt_sequence=0;
if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */ if (volume < 0 || volume >= used_nw_volumes) return(0); /* something wrong */
else soptions = nw_volumes[volume].options; else soptions = nw_volumes[volume].options;
strcpy((char*)entry, (char*)nwpath->fn); strcpy((char*)entry, (char*)nwpath->fn);
@ -409,10 +415,17 @@ static int get_dir_entry(NW_PATH *nwpath,
char *kpath=xkpath+strlen(xkpath); char *kpath=xkpath+strlen(xkpath);
*kpath++ = '/'; *kpath++ = '/';
if (*sequence == MAX_U16) *sequence = 0; if (*sequence == MAX_U16) *sequence = 0;
else seekdir(f, (long)*sequence);
while (akt_sequence++ < *sequence) {
if (NULL == readdir(f)) {
closedir(f);
return(0);
}
}
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
okflag = 0; okflag = 0;
(*sequence)++;
if (dirbuff->d_ino) { if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name); uint8 *name=(uint8*)(dirbuff->d_name);
okflag = (name[0] != '.' && okflag = (name[0] != '.' &&
@ -436,7 +449,6 @@ static int get_dir_entry(NW_PATH *nwpath,
XDPRINTF((6,0, "NAME=:%s: OKFLAG %d", name, okflag)); XDPRINTF((6,0, "NAME=:%s: OKFLAG %d", name, okflag));
} /* if */ } /* if */
} /* while */ } /* while */
*sequence = (int) telldir(f);
closedir(f); closedir(f);
} /* if */ } /* if */
return(okflag); return(okflag);
@ -477,13 +489,30 @@ static int get_dh_entry(DIR_HANDLE *dh,
if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry); if (dh->vol_options & VOL_OPTION_DOWNSHIFT) downstr(entry);
if ( (uint16)*sequence == MAX_U16) *sequence = 0; if ( (uint16)*sequence == MAX_U16) *sequence = 0;
seekdir(f, (long) *sequence);
XDPRINTF((5,0,"get_dh_entry attrib=0x%x path:%s:, entry:%s:", if (*sequence < dh->sequence) {
attrib, dh->unixname, entry)); dh->dirpos = (off_t)0;
dh->sequence = 0;
}
seekdir(f, dh->dirpos);
if (dh->sequence != *sequence) {
while (dh->sequence < *sequence) {
if (NULL == readdir(f)) {
dh->dirpos = telldir(f);
release_dh_f(dh);
return(0);
}
dh->sequence++;
}
dh->dirpos = telldir(f);
}
XDPRINTF((5,0,"get_dh_entry seq=x%x, attrib=0x%x path:%s:, entry:%s:",
*sequence, attrib, dh->unixname, entry));
while ((dirbuff = readdir(f)) != (struct dirent*)NULL){ while ((dirbuff = readdir(f)) != (struct dirent*)NULL){
okflag = 0; okflag = 0;
dh->sequence++;
if (dirbuff->d_ino) { if (dirbuff->d_ino) {
uint8 *name=(uint8*)(dirbuff->d_name); uint8 *name=(uint8*)(dirbuff->d_name);
okflag = (name[0] != '.' && ( okflag = (name[0] != '.' && (
@ -508,9 +537,12 @@ static int get_dh_entry(DIR_HANDLE *dh,
} }
} /* if */ } /* if */
} /* while */ } /* while */
dh->kpath[0] = '\0'; dh->kpath[0] = '\0';
*sequence = (int) telldir(f); *sequence = dh->sequence;
dh->dirpos = telldir(f);
release_dh_f(dh); release_dh_f(dh);
} /* if */ } /* if */
return(okflag); return(okflag);
} }
@ -1294,7 +1326,7 @@ int nw_open_dir_handle( int dir_handle,
*volume = fh->volume; *volume = fh->volume;
*dir_id = completition; *dir_id = completition;
*searchsequence = MAX_U16; *searchsequence = MAX_U16;
completition = 0xff; /* Alle Rechte */ completition = 0xff; /* all rights */
} }
XDPRINTF((5,0,"NW_OPEN_DIR_2: completition = 0x%x", XDPRINTF((5,0,"NW_OPEN_DIR_2: completition = 0x%x",
completition)); completition));
@ -1414,7 +1446,6 @@ static int s_nw_scan_dir_info(int dir_handle,
if (rights > -1) { if (rights > -1) {
DIR_HANDLE *dh = &(dir_handles[dir_id-1]); DIR_HANDLE *dh = &(dir_handles[dir_id-1]);
struct stat stbuff; struct stat stbuff;
int searchsequence = MAX_U16;
uint16 dirsequenz = GET_BE16(subnr); uint16 dirsequenz = GET_BE16(subnr);
uint16 aktsequenz = 0; uint16 aktsequenz = 0;
uint8 dirname[256]; uint8 dirname[256];

View File

@ -7,8 +7,11 @@ typedef struct {
ino_t inode; /* Unix Inode */ ino_t inode; /* Unix Inode */
time_t timestamp; /* f<>r letzte Allocierung */ time_t timestamp; /* f<>r letzte Allocierung */
char *kpath; /* Ein Zeichen nach unixname */ char *kpath; /* Ein Zeichen nach unixname */
int vol_options; /* Suchoptions */ int vol_options; /* searchoptions */
int volume; /* Volume Number */ int volume; /* Volume Number */
int sequence; /* Search sequence */
off_t dirpos; /* Current pos in unix dir */
} DIR_HANDLE; } DIR_HANDLE;
typedef struct { typedef struct {

View File

@ -1,5 +1,5 @@
Sorry, this is in German only. Sorry, this is in German only.
Aenderungen in mars_nwe bis zum : 07-May-96 Aenderungen in mars_nwe bis zum : 20-Jun-96
-------------------------------- --------------------------------
Erste 'oeffentliche' Version Erste 'oeffentliche' Version
^^^^^^^^^^ VERSION 0.94 ^^^^^^^^ ^^^^^^^^^^ VERSION 0.94 ^^^^^^^^
@ -127,6 +127,17 @@ Erste 'oeffentliche' Version
- Zugriffsrechte Bindery erweitert und korrigiert. - Zugriffsrechte Bindery erweitert und korrigiert.
- Volume option -r fuer readonly eingebaut. - Volume option -r fuer readonly eingebaut.
<----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <----- ^^^^^^^^^^ pl4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- setgroups u. initgroups in set_guid() eingebaut.
<----- ^^^^^^^^^^ pl5 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- SIG_PIPE wird nun in nwconn abgefangen.
<----- ^^^^^^^^^^ pl6 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Die Message Calls unter optimierten Kernel Mode wieder
zum Laufen gebracht.
- Routine 'get vol restriction' korrigiert.
Lieferte immer 0 als freien Userspeicherplatz zurueck.
- Bug beim Listen von grossen Direktories korrigiert. (Fritz Elfert)
- CRYPTED CHANGE PASSWORD Routine implementiert. (Guntram Blohm)
<----- ^^^^^^^^^^ pl7 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -5,6 +5,7 @@ Michael Beddow <m.beddow@servelan.co.uk>
Guntram Blohm <gbl%th7csun1@str.daimler-benz.com> Guntram Blohm <gbl%th7csun1@str.daimler-benz.com>
testing router code on token ring testing router code on token ring
wrote the 'crypted change password' routines !
Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de> Uwe Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
many testings+notes many testings+notes
@ -15,6 +16,9 @@ Hardy Buchholz <hardy@kool.f.eunet.de>
Ales Dryak <A.Dryak@sh.cvut.cz> Ales Dryak <A.Dryak@sh.cvut.cz>
his linware gave the kick his linware gave the kick
Fritz Elfert <fritz@wuemaus.franken.de>
gives Bugreport and Patches
Volker Lendecke <lendecke@math.uni-goettingen.de> Volker Lendecke <lendecke@math.uni-goettingen.de>
helps distributing helps distributing
@ -27,3 +31,4 @@ Jiri A. Randus <Jiri.Randus@vslib.cz>
Winfried Truemper <truemper@mi.uni-koeln.de>: Winfried Truemper <truemper@mi.uni-koeln.de>:
re-wrote `INSTALL' and added explanations to `nw.ini' re-wrote `INSTALL' and added explanations to `nw.ini'

View File

@ -1,7 +1,7 @@
Begin3 Begin3
Title: mars_nwe Title: mars_nwe
Version: 0.97.pl6 Version: 0.97.pl7
Entered-date: 21-May-96 Entered-date: 20-Jun-96
Description: Full netware-emulator (src), beta. Description: Full netware-emulator (src), beta.
Supports file-services, bindery-services, Supports file-services, bindery-services,
printing-services, routing-services. printing-services, routing-services.
@ -9,7 +9,7 @@ Keywords: novell, netware, server, ipx, ncp, tli
Author: mstover@freeway.de (Martin Stover) Author: mstover@freeway.de (Martin Stover)
Maintained-by: mstover@freeway.de (Martin Stover) Maintained-by: mstover@freeway.de (Martin Stover)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
140kB mars_nwe-0.97.pl6.tgz 160kB mars_nwe-0.97.pl7.tgz
Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware Alternate-site: ftp.uni-duisburg.de /pub/linux/ipxware
Platforms: Linux (1.2.xx, 1.3.xx), UnixWare 2.0x Platforms: Linux (1.2.xx, 1.3.xx), UnixWare 2.0x
Copying-policy: GNU Copying-policy: GNU

View File

@ -26,6 +26,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/config.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include "net.h" #include "net.h"
#include <linux/if.h> #include <linux/if.h>
@ -61,7 +62,7 @@ void ipx2sockadr(struct sockaddr_ipx *so, ipxAddr_t *i)
memcpy(&so->sipx_port, i->sock, 2); memcpy(&so->sipx_port, i->sock, 2);
} }
void set_emu_tli() void set_emu_tli(void)
{ {
int i = get_ini_int(100); int i = get_ini_int(100);
if (i > -1) locipxdebug = i; if (i > -1) locipxdebug = i;

View File

@ -33,6 +33,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/config.h>
#include <linux/sockios.h> #include <linux/sockios.h>
#include "net.h" #include "net.h"
#include <linux/if.h> #include <linux/if.h>
@ -243,7 +244,8 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug)
# endif # endif
#endif #endif
if ((sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0) { if ((sock = socket(AF_IPX, SOCK_DGRAM, AF_IPX)) < 0) {
errorp(1, "EMUTLI:init_ipx", NULL); errorp(1, "EMUTLI:init_ipx", NULL);
errorp(10, "Problem", "probably kernel-IPX is not setup correctly");
exit(1); exit(1);
} else { } else {
ipx_config_data cfgdata; ipx_config_data cfgdata;
@ -252,7 +254,7 @@ int init_ipx(uint32 network, uint32 node, int ipx_debug)
auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces; auto_interfaces = cfgdata.ipxcfg_auto_create_interfaces;
set_sock_debug(sock); set_sock_debug(sock);
result=0; result=0;
/* makes new internal net */ /* build new internal net */
if (network) { if (network) {
struct sockaddr_ipx ipxs; struct sockaddr_ipx ipxs;
memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx)); memset((char*)&ipxs, 0, sizeof(struct sockaddr_ipx));

View File

@ -9,7 +9,7 @@ C=.c
V_H=0 V_H=0
V_L=97 V_L=97
P_L=6 P_L=7
#define D_P_L 1 #define D_P_L 1
DISTRIB=mars_nwe DISTRIB=mars_nwe

View File

@ -143,8 +143,9 @@ static int open_ipx_sockets(void)
} }
typedef struct { typedef struct {
int fd; /* writepipe */ int fd; /* writepipe */
/* or if CALL_NWCONN_OVER_SOCKET then sock_nr of nwconn */ /* or if CALL_NWCONN_OVER_SOCKET */
/* then sock_nr of nwconn */
int pid; /* pid from son */ int pid; /* pid from son */
ipxAddr_t client_adr; /* address client */ ipxAddr_t client_adr; /* address client */
int sequence; /* previous sequence */ int sequence; /* previous sequence */
@ -499,6 +500,8 @@ static void handle_ncp_request(void)
{ {
if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){ if (t_rcvudata(ncp_fd, &ud, &rcv_flags) > -1){
int type; int type;
int compl;
int cstat;
in_len = ud.udata.len; in_len = ud.udata.len;
time(&akttime); time(&akttime);
XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr))); XDPRINTF((20, 0, "NCPSERV-LOOP von %s", visable_ipx_adr(&from_addr)));
@ -518,6 +521,7 @@ static void handle_ncp_request(void)
if (diff_time > 50) /* after max. 50 seconds */ if (diff_time > 50) /* after max. 50 seconds */
nwserv_reset_wdog(connection); nwserv_reset_wdog(connection);
/* tell the wdog there's no need to look */ /* tell the wdog there's no need to look */
#if !CALL_NWCONN_OVER_SOCKET #if !CALL_NWCONN_OVER_SOCKET
if (ncprequest->sequence == c->sequence if (ncprequest->sequence == c->sequence
&& !c->retry++) { && !c->retry++) {
@ -568,13 +572,23 @@ static void handle_ncp_request(void)
XDPRINTF((1,0, "GOT 0x%x connection=%d of %d conns not OK", XDPRINTF((1,0, "GOT 0x%x connection=%d of %d conns not OK",
type, ncprequest->connection, anz_connect)); type, ncprequest->connection, anz_connect));
if (type == 0x5555 || (type == 0x2222 && ncprequest->function == 0x19)) {
compl = 0;
cstat = 0;
} else {
compl = 0;
cstat = 1;
}
ncp_response(0x3333, ncprequest->sequence, ncp_response(0x3333, ncprequest->sequence,
ncprequest->connection, ncprequest->connection,
0, /* task */ 1, /* task */
0xfe, /* completition */ compl, /* completition */
0xf0, /* conn status */ cstat, /* conn status */
0); 0);
#if !CALL_NWCONN_OVER_SOCKET #if !CALL_NWCONN_OVER_SOCKET
/* here comes a call from nwbind */ /* here comes a call from nwbind */
} else if (type == 0x3333 } else if (type == 0x3333
@ -615,6 +629,13 @@ static void handle_ncp_request(void)
&& IPXCMPNET (from_addr.net, my_addr.net)) { && IPXCMPNET (from_addr.net, my_addr.net)) {
/* comes from nwserv */ /* comes from nwserv */
handle_ctrl(); handle_ctrl();
#if _MAR_TESTS_
} else if (type == 0xc000) {
/* rprinter */
int connection = (int)ncprequest->connection;
int sequence = (int)ncprequest->sequence;
ncp_response(0x3333, sequence, connection, 1, 0x0, 0, 0);
#endif
} else { } else {
int connection = (int)ncprequest->connection; int connection = (int)ncprequest->connection;
int sequence = (int)ncprequest->sequence; int sequence = (int)ncprequest->sequence;

14
net.h
View File

@ -36,6 +36,7 @@
#include <time.h> #include <time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <utmp.h> #include <utmp.h>
#include <grp.h>
#include <sys/errno.h> #include <sys/errno.h>
extern int errno; extern int errno;
@ -211,6 +212,18 @@ extern int errno;
# define IPX_MAX_DATA 546 # define IPX_MAX_DATA 546
#endif #endif
#ifndef DO_TESTING
# define DO_TESTING 0
#endif
#if !DO_TESTING
# undef _MAR_TESTS_
#endif
#ifndef _MAR_TESTS_
# define _MAR_TESTS_ 0
#endif
#ifdef LINUX #ifdef LINUX
# ifdef IN_NWROUTED # ifdef IN_NWROUTED
# undef INTERNAL_RIP_SAP # undef INTERNAL_RIP_SAP
@ -362,6 +375,7 @@ typedef struct S_OWN_DATA OWN_DATA;
#define SOCK_RIP 0x0453 /* Routing Information Packet */ #define SOCK_RIP 0x0453 /* Routing Information Packet */
#define SOCK_NETBIOS 0x0455 /* NET BIOS Packet */ #define SOCK_NETBIOS 0x0455 /* NET BIOS Packet */
#define SOCK_DIAGNOSE 0x0456 /* Diagnostic Packet */ #define SOCK_DIAGNOSE 0x0456 /* Diagnostic Packet */
#define SOCK_PSERVER 0x8060 /* Print Server's Socket */
#define SOCK_NVT 0x8063 /* NVT (Network Virtual Terminal) */ #define SOCK_NVT 0x8063 /* NVT (Network Virtual Terminal) */
/* PACKET TYPES */ /* PACKET TYPES */

View File

@ -1,5 +1,5 @@
/* nwbind.c */ /* nwbind.c */
#define REVISION_DATE "08-May-96" #define REVISION_DATE "19-Jun-96"
/* NCP Bindery SUB-SERVER */ /* NCP Bindery SUB-SERVER */
/* authentification and some message handling */ /* authentification and some message handling */
@ -374,20 +374,20 @@ static void handle_fxx(int gelen, int func)
uint8 maxconnections[2]; uint8 maxconnections[2];
uint8 connection_in_use[2]; uint8 connection_in_use[2];
uint8 max_volumes[2]; uint8 max_volumes[2];
uint8 os_revision; uint8 os_revision; /* 0 */
uint8 sft_level; uint8 sft_level; /* 2 */
uint8 tts_level; uint8 tts_level; /* 1 */
uint8 peak_connection[2]; uint8 peak_connection[2];
uint8 accounting_version; uint8 accounting_version; /* 1 */
uint8 vap_version; uint8 vap_version; /* 1 */
uint8 queuing_version; uint8 queuing_version; /* 1 */
uint8 print_server_version; uint8 print_server_version; /* 0 */
uint8 virtual_console_version; uint8 virtual_console_version; /* 1 */
uint8 security_level; uint8 security_level; /* 1 */
uint8 internet_bridge_version; uint8 internet_bridge_version; /* 1 */
uint8 reserved[60]; uint8 reserved[60];
} *xdata = (struct XDATA*) responsedata; } *xdata = (struct XDATA*) responsedata;
int k, i; int k, i, h;
memset(xdata, 0, sizeof(struct XDATA)); memset(xdata, 0, sizeof(struct XDATA));
strcpy(xdata->servername, my_nwname); strcpy(xdata->servername, my_nwname);
if (!tells_server_version) { if (!tells_server_version) {
@ -401,13 +401,30 @@ static void handle_fxx(int gelen, int func)
} }
i=0; i=0;
h=0;
for (k=0; k < MAX_CONNECTIONS; k++) { for (k=0; k < MAX_CONNECTIONS; k++) {
if (connections[k].active) i++; if (connections[k].active) {
i++;
h = k+1;
}
} }
U16_TO_BE16(i, xdata->connection_in_use); U16_TO_BE16(i, xdata->connection_in_use);
U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections); U16_TO_BE16(MAX_CONNECTIONS, xdata->maxconnections);
U16_TO_BE16(MAX_CONNECTIONS, xdata->peak_connection); U16_TO_BE16(h, xdata->peak_connection);
U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes); U16_TO_BE16(MAX_NW_VOLS, xdata->max_volumes);
#ifdef _MAR_TESTS_1
xdata->security_level=1;
xdata->sft_level=2;
xdata->tts_level=1;
xdata->accounting_version=1;
xdata->vap_version=1;
xdata->queuing_version=1;
xdata->virtual_console_version=1;
xdata->security_level=1;
xdata->internet_bridge_version=1;
#endif
data_len = sizeof(struct XDATA); data_len = sizeof(struct XDATA);
} }
break; break;
@ -539,12 +556,8 @@ static void handle_fxx(int gelen, int func)
uint8 *p = act_c->crypt_key; uint8 *p = act_c->crypt_key;
uint8 *pp = responsedata; uint8 *pp = responsedata;
data_len = k; data_len = k;
while (k--) *pp++ = *p++ = while (k--) *pp++ = *p++ = (uint8) rand();
#ifndef _MAR_TESTS_
(uint8) rand();
#else
(uint8) k;
#endif
/* if all here are same (1 or 2) then the resulting key is */ /* if all here are same (1 or 2) then the resulting key is */
/* 00000000 */ /* 00000000 */
if (password_scheme & PW_SCHEME_GET_KEY_FAIL) if (password_scheme & PW_SCHEME_GET_KEY_FAIL)
@ -1030,7 +1043,6 @@ static void handle_fxx(int gelen, int func)
} }
break; break;
#ifdef _CHANGE_PASSWD_TESTING_
case 0x4b : { /* keyed change pasword */ case 0x4b : { /* keyed change pasword */
uint8 *p = rdata+sizeof(act_c->crypt_key); uint8 *p = rdata+sizeof(act_c->crypt_key);
NETOBJ obj; NETOBJ obj;
@ -1039,26 +1051,21 @@ static void handle_fxx(int gelen, int func)
p+=2; p+=2;
strmaxcpy((char*)obj.name, (char*)(p+1), *p); strmaxcpy((char*)obj.name, (char*)(p+1), *p);
upstr(obj.name); upstr(obj.name);
p += (*p+1); /* here is now password-type ?? 0x60,0x66 */
/* from Guntram Blohm */
p += (*p+1); /* here is crypted password length */
if (0 == (result = find_obj_id(&obj, 0))) { if (0 == (result = find_obj_id(&obj, 0))) {
internal_act = 1; internal_act=1;
result=nw_test_passwd(obj.id, act_c->crypt_key, rdata); result=nw_keychange_passwd(obj.id, act_c->crypt_key,
internal_act = 0; rdata, (int)*p, p+1, act_c->object_id);
} internal_act = 0;
#if 0 }
if (result > -1) {
internal_act = 1;
result=nw_set_enpasswd(obj.id, p+1);
internal_act = 0;
}
#endif
if (result< 0) completition = (uint8) -result; if (result< 0) completition = (uint8) -result;
XDPRINTF((1, 0, "Keyed Change PW from OBJECT='%s', result=0x%x", XDPRINTF((2, 0, "Keyed Change PW from OBJECT='%s', result=0x%x",
obj.name, result)); obj.name, result));
} }
break; break;
#endif
case 0x4c : { /* List Relations of an Object */ case 0x4c : { /* List Relations of an Object */
XDPRINTF((1, 0, "TODO:List Relations of an Object")); XDPRINTF((1, 0, "TODO:List Relations of an Object"));

View File

@ -221,6 +221,9 @@ static int handle_ncp_serv(void)
} }
break; break;
case 0x15 :
return(-1); /* nwbind must do this call */
case 0x16 : { case 0x16 : {
/* uint8 len = *(requestdata+1); */ /* uint8 len = *(requestdata+1); */
@ -330,7 +333,7 @@ static int handle_ncp_serv(void)
int result = nw_get_volume_name((int)*(p+1), xdata->name); int result = nw_get_volume_name((int)*(p+1), xdata->name);
if (result > -1) { if (result > -1) {
xdata->namelen = (uint8) result; xdata->namelen = (uint8) result;
data_len = sizeof(struct XDATA); data_len = result+1;
} else completition = (uint8) -result; } else completition = (uint8) -result;
} else if (*p == 0xa){ /* legt Verzeichnis an */ } else if (*p == 0xa){ /* legt Verzeichnis an */
/******** Create Dir *********************/ /******** Create Dir *********************/
@ -575,11 +578,13 @@ static int handle_ncp_serv(void)
uint8 volnr = *(p+1); uint8 volnr = *(p+1);
uint32 id = GET_BE32(p+2); uint32 id = GET_BE32(p+2);
struct XDATA { struct XDATA {
uint8 weisnicht[8]; /* ?????? */ uint8 restriction[4];
uint8 inuse[4];
} *xdata = (struct XDATA*) responsedata; } *xdata = (struct XDATA*) responsedata;
XDPRINTF((5,0, "Get vol restriction vol=%d, id=0x%lx", XDPRINTF((5,0, "Get vol restriction vol=%d, id=0x%lx",
(int)volnr, id)); (int)volnr, id));
memset(xdata, 0, sizeof(struct XDATA)); U32_TO_32(0x40000000, xdata->restriction);
U32_TO_32(0x0, xdata->inuse);
data_len=sizeof(struct XDATA); data_len=sizeof(struct XDATA);
} else if (*p == 0x2a){ } else if (*p == 0x2a){
/* Get Eff. Rights of DIR's and Files ??*/ /* Get Eff. Rights of DIR's and Files ??*/
@ -795,6 +800,7 @@ static int handle_ncp_serv(void)
case 0x18 : /* End of Job */ case 0x18 : /* End of Job */
nw_free_handles((ncprequest->task > 0) ? nw_free_handles((ncprequest->task > 0) ?
(int) (ncprequest->task) : 1); (int) (ncprequest->task) : 1);
break; break;
case 0x19 : /* logout, some of this call is handled in ncpserv. */ case 0x19 : /* logout, some of this call is handled in ncpserv. */
@ -1296,7 +1302,7 @@ static int handle_ncp_serv(void)
break; break;
#endif #endif
#ifdef _MAR_TESTS_ #ifdef _MAR_TESTS_XX
case 0x5f : { /* ????????????? UNIX Client */ case 0x5f : { /* ????????????? UNIX Client */
struct INPUT { struct INPUT {
uint8 header[7]; /* Requestheader */ uint8 header[7]; /* Requestheader */
@ -1480,12 +1486,6 @@ static void set_sig(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
#if CALL_NWCONN_OVER_SOCKET
uint8 i_ipx_pack_typ;
ipxAddr_t x_from_addr;
ipxAddr_t client_addr;
struct t_unitdata iud;
#endif
if (argc != 5) { if (argc != 5) {
fprintf(stderr, "usage nwconn PID FROM_ADDR Connection nwbindsock\n"); fprintf(stderr, "usage nwconn PID FROM_ADDR Connection nwbindsock\n");
exit(1); exit(1);
@ -1496,14 +1496,11 @@ int main(int argc, char **argv)
init_tools(NWCONN, atoi(*(argv+3))); init_tools(NWCONN, atoi(*(argv+3)));
memset(saved_readbuff, 0, sizeof(saved_readbuff)); memset(saved_readbuff, 0, sizeof(saved_readbuff));
XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s", father_pid, *(argv+2), *(argv+3))); XDPRINTF((2, 0, "FATHER PID=%d, ADDR=%s CON:%s",
father_pid, *(argv+2), *(argv+3)));
adr_to_ipx_addr(&from_addr, *(argv+2)); 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); if (nw_init_connect()) exit(1);
sscanf(argv[4], "%x", &sock_nwbind); sscanf(argv[4], "%x", &sock_nwbind);
@ -1513,6 +1510,7 @@ int main(int argc, char **argv)
#endif #endif
last_sequence = -9999; last_sequence = -9999;
if (get_ipx_addr(&my_addr)) exit(1); if (get_ipx_addr(&my_addr)) exit(1);
#if CALL_NWCONN_OVER_SOCKET #if CALL_NWCONN_OVER_SOCKET
# if 1 # if 1
# ifdef SIOCIPXNCPCONN # ifdef SIOCIPXNCPCONN
@ -1535,35 +1533,19 @@ int main(int argc, char **argv)
ud.addr.maxlen = sizeof(ipxAddr_t); ud.addr.maxlen = sizeof(ipxAddr_t);
ud.addr.buf = (char*)&from_addr; ud.addr.buf = (char*)&from_addr;
ud.udata.buf = (char*)&ipxdata; ud.udata.buf = (char*)&ipxdata;
U16_TO_BE16(0x3333, ncpresponse->type); U16_TO_BE16(0x3333, ncpresponse->type);
ncpresponse->task = (uint8) 1; /* allways 1 */ ncpresponse->task = (uint8) 1; /* allways 1 */
ncpresponse->reserved = (uint8) 0; /* allways 0 */ ncpresponse->reserved = (uint8) 0; /* allways 0 */
ncpresponse->connection = (uint8) atoi(*(argv+3)); ncpresponse->connection = (uint8) atoi(*(argv+3));
#if CALL_NWCONN_OVER_SOCKET
iud.opt.len = sizeof(i_ipx_pack_typ);
iud.opt.maxlen = sizeof(i_ipx_pack_typ);
iud.opt.buf = (char*)&i_ipx_pack_typ; /* gets actual Typ */
iud.addr.len = sizeof(ipxAddr_t);
iud.addr.maxlen = sizeof(ipxAddr_t);
iud.addr.buf = (char*)&x_from_addr;
iud.udata.len = IPX_MAX_DATA;
iud.udata.maxlen = IPX_MAX_DATA;
iud.udata.buf = (char*)readbuff;
#endif
set_sig(); set_sig();
while (1) { while (1) {
#if CALL_NWCONN_OVER_SOCKET
int rcv_flags = 0;
int data_len = (t_rcvudata(0, &iud, &rcv_flags) > -1)
? iud.udata.len : -1;
#else
int data_len = read(0, readbuff, sizeof(readbuff)); int data_len = read(0, readbuff, sizeof(readbuff));
#endif /* this read is a pipe or a socket read,
* depending on CALL_NWCONN_OVER_SOCKET
*/
ncpresponse->connect_status = (uint8) 0; ncpresponse->connect_status = (uint8) 0;
if (fl_get_int) { if (fl_get_int) {
@ -1574,9 +1556,12 @@ int main(int argc, char **argv)
if (data_len > 0) { if (data_len > 0) {
XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len)); XDPRINTF((99, 0, "NWCONN GOT DATA len = %d",data_len));
if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) { if ((ncp_type = (int)GET_BE16(ncprequest->type)) == 0x3333) {
/* this is a response packet */
data_len -= sizeof(NCPRESPONSE); data_len -= sizeof(NCPRESPONSE);
if (saved_sequence > -1 && ((int)(ncprequest->sequence) == saved_sequence) if (saved_sequence > -1
&& ((int)(ncprequest->sequence) == saved_sequence)
&& !ncprequest->function) { && !ncprequest->function) {
/* comes from nwbind */
handle_after_bind(); handle_after_bind();
} else { } else {
/* OK for direct sending */ /* OK for direct sending */
@ -1589,11 +1574,15 @@ int main(int argc, char **argv)
(int)(ncprequest->function), data_len); (int)(ncprequest->function), data_len);
} }
saved_sequence = -1; saved_sequence = -1;
} else { /* this calls I must handle */ } else { /* this calls I must handle, it is a request */
int result; int result;
requestlen = data_len - sizeof(NCPREQUEST); requestlen = data_len - sizeof(NCPREQUEST);
if (0 != (result = handle_ncp_serv()) ) { if (0 != (result = handle_ncp_serv()) ) {
if (result == -2) { /* here the actual call must be saved */ if (result == -2) {
/* here the actual call must be saved
* because we need it later, when the request to nwbind
* returns.
*/
memcpy(saved_readbuff, readbuff, data_len); memcpy(saved_readbuff, readbuff, data_len);
saved_sequence = (int)(ncprequest->sequence); saved_sequence = (int)(ncprequest->sequence);
} else saved_sequence = -1; } else saved_sequence = -1;

View File

@ -211,3 +211,89 @@ nw_encrypt(unsigned char *fra,unsigned char *buf,unsigned char *til)
} }
/* =========== next is from Guntram Blohm ! =============== */
char newshuffle[256+16] = {
0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08,
};
int nw_decrypt_newpass(char *oldpwd, char *newpwd, char *undecr)
{
int i, j, n;
unsigned char ch, cl;
char invshuffle[256+16];
char copy[8];
for (i=0; i<256+16; i+=16)
for (j=0; j<16; j++)
invshuffle[i+newshuffle[i+j]]=j;
for (i=0; i<16; i++)
{
memset(copy, '\0', 8);
for (j=0; j<16; j++)
{
n=newshuffle[j+0x100];
ch=(j&1 ? (newpwd[j/2]>>4)&0x0f : newpwd[j/2]&0x0f);
copy[n/2]|=(n&1) ? (ch<<4) : ch;
}
ch=(oldpwd[0]<<4);
for (j=0; j<7; j++)
oldpwd[j]=(oldpwd[j+1]<<4)|((oldpwd[j]>>4)&0x0f);
oldpwd[7]=ch|((oldpwd[7]>>4)&0x0f);
for (j=0; j<8; j++)
{
cl=invshuffle[((copy[j] )&0x0f)+j*32 ] ;
ch=invshuffle[((copy[j]>>4)&0x0f)+j*32+16]<<4;
copy[j]=(ch|cl)^oldpwd[j];
}
memcpy(newpwd, copy, 8);
}
memcpy(undecr, copy, 8);
}

View File

@ -1,7 +1,11 @@
/* nwcrypt.h */ /* nwcrypt.h 19-Jun-96 */
extern void shuffle(unsigned char *lon, extern void shuffle(unsigned char *lon,
const unsigned char *buf, int buflen, const unsigned char *buf, int buflen,
unsigned char *target); unsigned char *target);
extern void nw_encrypt(unsigned char *fra, extern void nw_encrypt(unsigned char *fra,
unsigned char *buf,unsigned char *til); unsigned char *buf,unsigned char *til);
extern int nw_decrypt_newpass(char *oldpwd, char *newpwd, char *undecr);

160
nwdbm.c
View File

@ -1,4 +1,4 @@
/* nwdbm.c 13-May-96 data base for mars_nwe */ /* nwdbm.c 20-Jun-96 data base for mars_nwe */
/* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany /* (C)opyright (C) 1993,1995 Martin Stover, Marburg, Germany
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -17,7 +17,7 @@
*/ */
/* /*
* This code is only called from the process 'ncpserv' * This code is only called from the process 'nwbind'
* So, there is no need for locking or something else. * So, there is no need for locking or something else.
*/ */
@ -41,8 +41,8 @@
#define DBM_REMAINS_OPEN 1 #define DBM_REMAINS_OPEN 1
int tells_server_version=0; int tells_server_version=0;
int password_scheme=PW_SCHEME_CHANGE_PW; int password_scheme=PW_SCHEME_CHANGE_PW;
static datum key; static datum key;
static datum data; static datum data;
@ -174,7 +174,10 @@ int find_obj_id(NETOBJ *o, uint32 last_obj_id)
return(result); return(result);
} }
static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id) static int loc_delete_property(uint32 obj_id,
uint8 *prop_name,
uint8 prop_id,
int ever) /* ever means no access tests */
/* deletes Object property or properties */ /* deletes Object property or properties */
/* wildcards allowed in property name */ /* wildcards allowed in property name */
{ {
@ -191,7 +194,7 @@ static int loc_delete_property(uint32 obj_id, uint8 *prop_name, uint8 prop_id)
p = (NETPROP*)data.dptr; p = (NETPROP*)data.dptr;
if (p != NULL && name_match(p->name, prop_name)){ if (p != NULL && name_match(p->name, prop_name)){
XDPRINTF((2,0, "found prop: %s, id=%d for deleting", p->name, (int)p->id)); XDPRINTF((2,0, "found prop: %s, id=%d for deleting", p->name, (int)p->id));
if (!b_acc(obj_id, p->security, 0x13)) { if (ever || !b_acc(obj_id, p->security, 0x13)) {
if ((int)(p->id) > result) result = (int)(p->id); if ((int)(p->id) > result) result = (int)(p->id);
xset[p->id]++; xset[p->id]++;
} else if (result < 0) result = -0xf6; /* no delete priv. */ } else if (result < 0) result = -0xf6; /* no delete priv. */
@ -252,7 +255,7 @@ static int loc_delete_obj(uint32 objid, int security)
{ {
int result = b_acc(objid, 0x33, 0x03); /* only supervisor or intern */ int result = b_acc(objid, 0x33, 0x03); /* only supervisor or intern */
if (result) return(result); /* no object delete priv */ if (result) return(result); /* no object delete priv */
(void)loc_delete_property(objid, (uint8*)"*", 0); (void)loc_delete_property(objid, (uint8*)"*", 0, 1);
if (!dbminit(FNOBJ)){ if (!dbminit(FNOBJ)){
key.dptr = (char*)&objid; key.dptr = (char*)&objid;
key.dsize = NETOBJ_KEY_SIZE; key.dsize = NETOBJ_KEY_SIZE;
@ -633,7 +636,7 @@ int nw_delete_property(int object_type,
obj.name, prop_name_x, object_type)); obj.name, prop_name_x, object_type));
obj.type = (uint16) object_type; obj.type = (uint16) object_type;
if ((result = find_obj_id(&obj, 0)) == 0){ if ((result = find_obj_id(&obj, 0)) == 0){
result = loc_delete_property(obj.id, prop_name_x, 0); result = loc_delete_property(obj.id, prop_name_x, 0, 0);
} }
return(result); return(result);
} }
@ -875,6 +878,7 @@ int nw_obj_has_prop(NETOBJ *obj)
static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop) static int nw_create_obj_prop(NETOBJ *obj, NETPROP *prop)
{ {
int result = b_acc(obj->id, obj->security, 0x12); int result = b_acc(obj->id, obj->security, 0x12);
XDPRINTF((3, 0, "create property='%s' objid=0x%x", prop->name, obj->id));
if (result) return(result); if (result) return(result);
if (!dbminit(FNPROP)){ if (!dbminit(FNPROP)){
uint8 founds[256]; uint8 founds[256];
@ -997,7 +1001,7 @@ static MYPASSWD *nw_getpwnam(uint32 obj_id)
if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){ if (nw_get_prop_val_str(obj_id, "UNIX_USER", buff) > 0){
struct passwd *pw = getpwnam(buff); struct passwd *pw = getpwnam(buff);
if (NULL != pw) { if (NULL != pw) {
if (obj_id != 1 && pw->pw_uid == 1) if (obj_id != 1 && !pw->pw_uid)
return(NULL); /* only supervisor -> root */ return(NULL); /* only supervisor -> root */
pwstat.pw_uid = pw->pw_uid; pwstat.pw_uid = pw->pw_uid;
pwstat.pw_gid = pw->pw_gid; pwstat.pw_gid = pw->pw_gid;
@ -1064,26 +1068,42 @@ static int crypt_pw_ok(uint8 *password, char *passwd)
return( (strcmp(p, passwd)) ? 0 : 1 ); return( (strcmp(p, passwd)) ? 0 : 1 );
} }
static int loc_nw_test_passwd(uint8 *keybuff, uint8 *stored_passwd,
uint32 obj_id, uint8 *vgl_key, uint8 *akt_key)
{
if (nw_get_prop_val_str(obj_id, "PASSWORD", stored_passwd) > 0) {
nw_encrypt(vgl_key, stored_passwd, keybuff);
return (memcmp(akt_key, keybuff, 8) ? -0xff : 0);
} else { /* now we build an empty password */
uint8 buf[8];
uint8 s_uid[4];
U32_TO_BE32(obj_id, s_uid);
shuffle(s_uid, buf, 0, stored_passwd);
nw_encrypt(vgl_key, stored_passwd, keybuff);
return(1);
}
}
int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key) int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key)
/* returns 0, if password ok and -0xff if not ok */ /* returns 0, if password ok and -0xff if not ok */
{ {
char buf[200]; uint8 keybuff[8];
if (nw_get_prop_val_str(obj_id, "PASSWORD", buf) > 0) { uint8 stored_passwd[200];
uint8 keybuff[8]; int result=loc_nw_test_passwd(keybuff, stored_passwd,
memcpy(keybuff, vgl_key, sizeof(keybuff)); obj_id, vgl_key, akt_key);
nw_encrypt(keybuff, buf, keybuff); if (result < 1) return(result);
return (memcmp(akt_key, keybuff, sizeof(keybuff)) ? -0xff : 0);
} else { if (obj_id == 1) return(-0xff); /* SUPERVISOR */
if (obj_id == 1) return(-0xff);
if (password_scheme & PW_SCHEME_LOGIN) { if (password_scheme & PW_SCHEME_LOGIN) {
if (!(password_scheme & PW_SCHEME_ALLOW_EMPTY_PW)) { if (!(password_scheme & PW_SCHEME_ALLOW_EMPTY_PW)) {
MYPASSWD *pw = nw_getpwnam(obj_id); MYPASSWD *pw = nw_getpwnam(obj_id);
if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd)) if (pw && *(pw->pw_passwd) && !crypt_pw_ok(NULL, pw->pw_passwd))
return(-0xff); return(-0xff);
}
} }
return(0); /* no password */
} }
return(0); /* no password */
} }
int nw_test_unenpasswd(uint32 obj_id, uint8 *password) int nw_test_unenpasswd(uint32 obj_id, uint8 *password)
@ -1122,7 +1142,7 @@ static int nw_set_enpasswd(uint32 obj_id, uint8 *passwd, int dont_ch)
prop_name, P_FL_STAT|P_FL_ITEM, 0x44, prop_name, P_FL_STAT|P_FL_ITEM, 0x44,
passwd, 16); passwd, 16);
} else if (!dont_ch) } else if (!dont_ch)
(void)loc_delete_property(obj_id, prop_name, 0); (void)loc_delete_property(obj_id, prop_name, 0, 1);
return(0); return(0);
} }
@ -1133,7 +1153,7 @@ int nw_set_passwd(uint32 obj_id, char *password, int dont_ch)
uint8 s_uid[4]; uint8 s_uid[4];
U32_TO_BE32(obj_id, s_uid); U32_TO_BE32(obj_id, s_uid);
shuffle(s_uid, password, strlen(password), passwd); shuffle(s_uid, password, strlen(password), passwd);
#if 1 #if 0
XDPRINTF((2,0, "password %s->0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", XDPRINTF((2,0, "password %s->0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x",
password, password,
(int)passwd[0], (int)passwd[0],
@ -1159,6 +1179,53 @@ int nw_set_passwd(uint32 obj_id, char *password, int dont_ch)
} }
/* main work from Guntram Blohm
* no chance for unix password support here - can't get real password
* from ncp request
*/
int nw_keychange_passwd(uint32 obj_id, uint8 *cryptkey, uint8 *oldpass,
int cryptedlen, uint8 *newpass, uint32 act_id)
{
uint8 storedpass[200];
uint8 keybuff[8];
char buf[100];
int len;
int result = loc_nw_test_passwd(keybuff, storedpass,
obj_id, cryptkey, oldpass);
XDPRINTF((5, 0, "Crypted change password: id=%lx, oldpresult=0x%x",
obj_id, result));
len=(cryptedlen ^ storedpass[0] ^ storedpass[1])&0x3f;
XDPRINTF((5, 0, "real len of new pass = %d", len));
XDPRINTF((5, 0, "stored: %s", hex_str(buf, storedpass, 16)));
XDPRINTF((5, 0, "crypted: %s", hex_str(buf, keybuff, 8)));
XDPRINTF((5, 0, "ncp old: %s", hex_str(buf, oldpass, 8)));
if (result < 0) { /* wrong passwd */
if (1 == act_id) { /* supervisor is changing passwd */
uint8 buf[8];
uint8 s_uid[4];
U32_TO_BE32(obj_id, s_uid);
shuffle(s_uid, buf, 0, storedpass);
nw_encrypt(cryptkey, storedpass, keybuff);
len=(cryptedlen ^ storedpass[0] ^ storedpass[1])&0x3f;
XDPRINTF((5, 0, "N real len of new pass = %d", len));
XDPRINTF((5, 0, "N stored: %s", hex_str(buf, storedpass, 16)));
XDPRINTF((5, 0, "N crypted: %s", hex_str(buf, keybuff, 8)));
if (memcmp(oldpass, keybuff, 8))
return(-0xff); /* if not BLANK then error */
} else return(-0xff);
}
XDPRINTF((5, 0, "ncp new: %s", hex_str(buf,newpass, 16)));
nw_decrypt_newpass(storedpass, newpass, newpass);
nw_decrypt_newpass(storedpass+8, newpass+8, newpass+8);
XDPRINTF((5, 0, "realnew: %s", hex_str(buf,newpass, 16)));
nw_set_enpasswd(obj_id, newpass, 0);
return(0);
}
int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id) int prop_add_new_member(uint32 obj_id, int prop_id, uint32 member_id)
/* addiert member to set, if member not in set */ /* addiert member to set, if member not in set */
{ {
@ -1202,6 +1269,7 @@ static void create_nw_db(char *fn, int allways)
chmod(fname, 0600); chmod(fname, 0600);
} }
static void add_pr_queue(uint32 q_id, static void add_pr_queue(uint32 q_id,
char *q_name, char *q_directory, char *q_name, char *q_directory,
char *q_command, char *q_command,
@ -1342,12 +1410,13 @@ static uint8 *test_add_dir(uint8 *unixname, uint8 *pp, int shorten,
int nw_fill_standard(char *servername, ipxAddr_t *adr) int nw_fill_standard(char *servername, ipxAddr_t *adr)
/* fills the Standardproperties */ /* fills the standardproperties */
{ {
char serverna[MAX_SERVER_NAME+2]; char serverna[MAX_SERVER_NAME+2];
uint32 su_id = 0x00000001; uint32 su_id = 0x00000001;
uint32 ge_id = 0x01000001; uint32 ge_id = 0x01000001;
uint32 serv_id = 0x03000001; uint32 serv_id = 0x03000001;
uint32 pserv_id = 0L;
uint32 q1_id = 0x0E000001; uint32 q1_id = 0x0E000001;
#if 0 #if 0
uint32 guest_id = 0x02000001; uint32 guest_id = 0x02000001;
@ -1370,7 +1439,7 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) { while (0 != (what =get_ini_entry(f, 0, (char*)buff, sizeof(buff)))) {
if (1 == what && !*sysentry) { if (1 == what && !*sysentry) {
xstrcpy(sysentry, buff); xstrcpy(sysentry, buff);
} else if (6 == what) { /* Server Version */ } else if (6 == what) { /* server Version */
tells_server_version = atoi(buff); tells_server_version = atoi(buff);
} else if (7 == what) { /* password_scheme */ } else if (7 == what) { /* password_scheme */
int pwscheme = atoi(buff); int pwscheme = atoi(buff);
@ -1445,27 +1514,40 @@ int nw_fill_standard(char *servername, ipxAddr_t *adr)
} /* while */ } /* while */
fclose(f); fclose(f);
} }
if (servername && adr) { if (servername && adr) {
strmaxcpy(serverna, servername, MAX_SERVER_NAME); strmaxcpy(serverna, servername, MAX_SERVER_NAME);
upstr(serverna); upstr(serverna);
nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40, nw_new_obj_prop(serv_id, serverna, 0x4, O_FL_DYNA, 0x40,
"NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40, "NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40,
(char*)adr, sizeof(ipxAddr_t)); (char*)adr, sizeof(ipxAddr_t));
#if _MAR_TESTS_
nw_new_obj_prop(pserv_id, serverna, 0x47, O_FL_DYNA, 0x31,
"NET_ADDRESS", P_FL_ITEM | P_FL_DYNA, 0x40,
(char*)adr, sizeof(ipxAddr_t));
#endif
} }
if (auto_ins_user) { if (auto_ins_user) {
/* here Unix users will be inserted automaticly as mars_nwe users */
struct passwd *pw; struct passwd *pw;
upstr(auto_ins_passwd); upstr(auto_ins_passwd);
while (NULL != (pw=getpwent())) { while (NULL != (pw=getpwent())) {
if ( (pw->pw_passwd[0] != '*' && pw->pw_passwd[0] != 'x') if (pw->pw_uid) {
|| pw->pw_passwd[1] != '\0') { if ( (pw->pw_passwd[0] != '*' && pw->pw_passwd[0] != 'x')
char nname[100]; || pw->pw_passwd[1] != '\0') {
xstrcpy(nname, pw->pw_name); char nname[100];
upstr(nname); xstrcpy(nname, pw->pw_name);
add_user(0L, ge_id, nname, pw->pw_name, auto_ins_passwd, upstr(nname);
(auto_ins_user == 99) ? 0 : 99); add_user(0L, ge_id, nname, pw->pw_name, auto_ins_passwd,
(auto_ins_user == 99) ? 0 : 99);
} else {
XDPRINTF((1,0, "Unix User:'%s' not added because passwd='%s'",
pw->pw_name, pw->pw_passwd));
}
} else { } else {
XDPRINTF((1,0, "Unix User:'%s' not added because passwd='%s'", XDPRINTF((1,0, "Unix User:'%s' not added because uid=0 (root)",
pw->pw_name, pw->pw_passwd)); pw->pw_name));
} }
} }
endpwent(); endpwent();
@ -1572,7 +1654,7 @@ int nw_init_dbm(char *servername, ipxAddr_t *adr)
} }
} }
dbmclose(); dbmclose();
while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz]); /* now delete */ while (anz--) loc_delete_property(objs[anz], (char*)NULL, props[anz], 1); /* now delete */
anz = nw_fill_standard(servername, adr); anz = nw_fill_standard(servername, adr);
sync_dbm(); sync_dbm();
return(anz); return(anz);

View File

@ -180,6 +180,11 @@ extern int nw_test_passwd(uint32 obj_id, uint8 *vgl_key, uint8 *akt_key);
extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password); extern int nw_test_unenpasswd(uint32 obj_id, uint8 *password);
extern int nw_set_passwd(uint32 obj_id, char *password, int dont_ch); extern int nw_set_passwd(uint32 obj_id, char *password, int dont_ch);
extern int nw_keychange_passwd(uint32 obj_id,
uint8 *cryptkey, uint8 *oldpass,
int cryptedlen, uint8 *newpass,
uint32 act_id);
extern int nw_get_q_dirname(uint32 q_id, uint8 *buff); extern int nw_get_q_dirname(uint32 q_id, uint8 *buff);
extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff); extern int nw_get_q_prcommand(uint32 q_id, uint8 *buff);

View File

@ -36,7 +36,7 @@ static int new_file_handle(uint8 *unixname)
FILE_HANDLE *fh=NULL; FILE_HANDLE *fh=NULL;
while (++rethandle < anz_fhandles) { while (++rethandle < anz_fhandles) {
FILE_HANDLE *fh=&(file_handles[rethandle]); FILE_HANDLE *fh=&(file_handles[rethandle]);
if (fh->fd == -1 && !(fh->flags & 4)) { /* empty slot */ if (fh->fd == -1 && !(fh->fh_flags & FH_DO_NOT_REUSE)) { /* empty slot */
rethandle++; rethandle++;
break; break;
} else fh=NULL; } else fh=NULL;
@ -52,7 +52,7 @@ static int new_file_handle(uint8 *unixname)
fh->offd = 0L; fh->offd = 0L;
fh->tmodi = 0L; fh->tmodi = 0L;
strcpy((char*)fh->fname, (char*)unixname); strcpy((char*)fh->fname, (char*)unixname);
fh->flags = 0; fh->fh_flags = 0;
fh->f = NULL; fh->f = NULL;
XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s", XDPRINTF((5, 0, "new_file_handle=%d, anz_fhandles=%d, fn=%s",
rethandle, anz_fhandles, unixname)); rethandle, anz_fhandles, unixname));
@ -65,12 +65,12 @@ static int free_file_handle(int fhandle)
if (fhandle > 0 && (fhandle <= anz_fhandles)) { if (fhandle > 0 && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]); FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (fh->fd > -1) { if (fh->fd > -1) {
if (fh->flags & 2) { if (fh->fh_flags & FH_IS_PIPE_COMMAND) {
if (fh->f) ext_pclose(fh->f); if (fh->f) ext_pclose(fh->f);
fh->f = NULL; fh->f = NULL;
} else close(fh->fd); } else close(fh->fd);
if (fh->tmodi > 0L && !(fh->flags & 2) if (fh->tmodi > 0L && !(FH_IS_PIPE_COMMAND & fh->fh_flags)
&& !(fh->flags & FILE_IS_READONLY)) { && !(FH_IS_READONLY & fh->fh_flags) ) {
/* now set date and time */ /* now set date and time */
struct utimbuf ut; struct utimbuf ut;
ut.actime = ut.modtime = fh->tmodi; ut.actime = ut.modtime = fh->tmodi;
@ -79,11 +79,11 @@ static int free_file_handle(int fhandle)
} }
} }
fh->fd = -1; fh->fd = -1;
if (fhandle == anz_fhandles && !(fh->flags & 4)) { if (fhandle == anz_fhandles && !(fh->fh_flags & FH_DO_NOT_REUSE)) {
/* was last */ /* was last */
anz_fhandles--; anz_fhandles--;
while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1 while (anz_fhandles && file_handles[anz_fhandles-1].fd == -1
&& !(file_handles[anz_fhandles-1].flags & 4) ) && !(file_handles[anz_fhandles-1].fh_flags & FH_DO_NOT_REUSE) )
anz_fhandles--; anz_fhandles--;
} }
result=0; result=0;
@ -129,9 +129,10 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
fh->f = ext_popen(pipecommand, geteuid(), getegid()); fh->f = ext_popen(pipecommand, geteuid(), getegid());
fh->fd = (fh->f) ? fileno(fh->f->fildes[1]) : -1; fh->fd = (fh->f) ? fileno(fh->f->fildes[1]) : -1;
if (fh->fd > -1) { if (fh->fd > -1) {
fh->flags |= 2; fh->fh_flags |= FH_IS_PIPE;
fh->fh_flags |= FH_IS_PIPE_COMMAND;
if (!dowrite) stbuff->st_size = 0x7fffffff; if (!dowrite) stbuff->st_size = 0x7fffffff;
if (creatmode & 4) fh->flags |= 4; if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE;
return(fhandle); return(fhandle);
} }
} }
@ -162,10 +163,14 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
} else { } else {
int statr = stat(fh->fname, stbuff); int statr = stat(fh->fname, stbuff);
int acm = (access & 2) ? (int) O_RDWR : (int)O_RDONLY; int acm = (access & 2) ? (int) O_RDWR : (int)O_RDONLY;
if ( (!statr && (stbuff->st_mode & S_IFMT) != S_IFDIR) if ( (!statr && !S_ISDIR(stbuff->st_mode))
|| (statr && (acm & O_CREAT))){ || (statr && (acm & O_CREAT))){
XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle)); if ((!statr) && S_ISFIFO(stbuff->st_mode)){
acm |= O_NONBLOCK;
fh->fh_flags |= FH_IS_PIPE;
}
fh->fd = open(fh->fname, acm, 0777); fh->fd = open(fh->fname, acm, 0777);
XDPRINTF((5,0,"OPEN FILE with attrib:0x%x, access:0x%x, fh->fname:%s: fhandle=%d",attrib,access, fh->fname, fhandle));
fh->offd = 0L; fh->offd = 0L;
if (fh->fd > -1) { if (fh->fd > -1) {
if (statr) stat(fh->fname, stbuff); if (statr) stat(fh->fname, stbuff);
@ -173,7 +178,7 @@ int file_creat_open(int volume, uint8 *unixname, struct stat *stbuff,
} }
} }
if (fh->fd > -1) { if (fh->fd > -1) {
if (creatmode & 4) fh->flags |= 4; if (creatmode & 4) fh->fh_flags |= FH_DO_NOT_REUSE;
return(fhandle); return(fhandle);
} }
} /* else (NOT DEVICE) */ } /* else (NOT DEVICE) */
@ -188,7 +193,7 @@ int nw_set_fdate_time(uint32 fhandle, uint8 *datum, uint8 *zeit)
if (fhandle > 0 && (--fhandle < anz_fhandles) ) { if (fhandle > 0 && (--fhandle < anz_fhandles) ) {
FILE_HANDLE *fh=&(file_handles[fhandle]); FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) { if (fh->fd > -1) {
if (!(fh->flags & FILE_IS_READONLY)) { if (!(fh->fh_flags & FH_IS_READONLY)) {
fh->tmodi = nw_2_un_time(datum, zeit); fh->tmodi = nw_2_un_time(datum, zeit);
return(0); return(0);
} else return(-0x8c); } else return(-0x8c);
@ -203,11 +208,11 @@ int nw_close_datei(int fhandle, int reset_reuse)
fhandle, anz_fhandles)); fhandle, anz_fhandles));
if (fhandle > 0 && (fhandle <= anz_fhandles)) { if (fhandle > 0 && (fhandle <= anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle-1]); FILE_HANDLE *fh=&(file_handles[fhandle-1]);
if (reset_reuse) fh->flags &= (~4); if (reset_reuse) fh->fh_flags &= (~FH_DO_NOT_REUSE);
if (fh->fd > -1) { if (fh->fd > -1) {
int result = 0; int result = 0;
int result2; int result2;
if (fh->flags & 2) { if (fh->fh_flags & FH_IS_PIPE_COMMAND) {
if (fh->f) { if (fh->f) {
result=ext_pclose(fh->f); result=ext_pclose(fh->f);
if (result > 0) result = 0; if (result > 0) result = 0;
@ -215,8 +220,8 @@ int nw_close_datei(int fhandle, int reset_reuse)
fh->f = NULL; fh->f = NULL;
} else result=close(fh->fd); } else result=close(fh->fd);
fh->fd = -1; fh->fd = -1;
if (fh->tmodi > 0L && !(fh->flags&2) if (fh->tmodi > 0L && !(fh->fh_flags & FH_IS_PIPE)
&& !(fh->flags & FILE_IS_READONLY)) { && !(fh->fh_flags & FH_IS_READONLY)) {
struct utimbuf ut; struct utimbuf ut;
ut.actime = ut.modtime = fh->tmodi; ut.actime = ut.modtime = fh->tmodi;
utime(fh->fname, &ut); utime(fh->fname, &ut);
@ -248,8 +253,17 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
if (fhandle > 0 && (--fhandle < anz_fhandles)) { if (fhandle > 0 && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]); FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) { if (fh->fd > -1) {
if (fh->flags & 2) { /* PIPE */ if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
size = fread(data, 1, size, fh->f->fildes[1]); if (fh->fh_flags & FH_IS_PIPE_COMMAND)
size = fread(data, 1, size, fh->f->fildes[1]);
else {
size = read(fh->fd, data, size);
if (size < 0) {
int k=5;
while (size < 0 && --k /* && errno == EAGAIN */)
size = read(fh->fd, data, size);
}
}
} else { } else {
if (fh->offd != (long)offset) { if (fh->offd != (long)offset) {
fh->offd=lseek(fh->fd, offset, SEEK_SET); fh->offd=lseek(fh->fd, offset, SEEK_SET);
@ -265,6 +279,7 @@ int nw_read_datei(int fhandle, uint8 *data, int size, uint32 offset)
} }
} else size = -1; } else size = -1;
} }
if (size == -1) size=0;
return(size); return(size);
} }
} }
@ -276,7 +291,7 @@ int nw_seek_datei(int fhandle, int modus)
if (fhandle > 0 && (--fhandle < anz_fhandles)) { if (fhandle > 0 && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]); FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) { if (fh->fd > -1) {
if (fh->flags & 2) { /* PIPE */ if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
return(0x7fffffff); return(0x7fffffff);
} else { } else {
int size=-0xfb; int size=-0xfb;
@ -297,11 +312,13 @@ int nw_write_datei(int fhandle, uint8 *data, int size, uint32 offset)
if (fhandle > 0 && (--fhandle < anz_fhandles)) { if (fhandle > 0 && (--fhandle < anz_fhandles)) {
FILE_HANDLE *fh=&(file_handles[fhandle]); FILE_HANDLE *fh=&(file_handles[fhandle]);
if (fh->fd > -1) { if (fh->fd > -1) {
if (fh->flags & FILE_IS_READONLY) return(-0x94); if (fh->fh_flags & FH_IS_READONLY) return(-0x94);
if (fh->flags & 2) { /* PIPE */ if (fh->fh_flags & FH_IS_PIPE) { /* PIPE */
if (size) if (size) {
return(fwrite(data, 1, size, fh->f->fildes[0])); if (fh->fh_flags & FH_IS_PIPE_COMMAND)
return(0); return(fwrite(data, 1, size, fh->f->fildes[0]));
return(write(fh->fd, data, size));
} return(0);
} else { } else {
if (fh->offd != (long)offset) if (fh->offd != (long)offset)
fh->offd = lseek(fh->fd, offset, SEEK_SET); fh->offd = lseek(fh->fd, offset, SEEK_SET);
@ -345,7 +362,7 @@ int nw_server_copy(int qfhandle, uint32 qoffset,
if (fhq->fd > -1 && fhz->fd > -1) { if (fhq->fd > -1 && fhz->fd > -1) {
char buff[2048]; char buff[2048];
int wsize; int wsize;
if (fhz->flags & FILE_IS_READONLY) return(-0x94); if (fhz->fh_flags & FH_IS_READONLY) return(-0x94);
if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L && if (lseek(fhq->fd, qoffset, SEEK_SET) > -1L &&
lseek(fhz->fd, zoffset, SEEK_SET) > -1L) { lseek(fhz->fd, zoffset, SEEK_SET) > -1L) {
retsize = 0; retsize = 0;
@ -384,7 +401,7 @@ int nw_lock_datei(int fhandle, int offset, int size, int do_lock)
if (fh->fd > -1) { if (fh->fd > -1) {
struct flock flockd; struct flock flockd;
int result; int result;
if (fh->flags & 2) return(0); if (fh->fh_flags & FH_IS_PIPE) return(0);
flockd.l_type = (do_lock) ? F_WRLCK : F_UNLCK; flockd.l_type = (do_lock) ? F_WRLCK : F_UNLCK;
flockd.l_whence = SEEK_SET; flockd.l_whence = SEEK_SET;
flockd.l_start = offset; flockd.l_start = offset;

View File

@ -5,15 +5,20 @@
typedef struct { typedef struct {
int fd; /* filehandle from system open/creat */ int fd; /* filehandle from system open/creat */
long offd; /* aktuell file offset */ long offd; /* actual file offset */
time_t tmodi; /* modification TIME */ time_t tmodi; /* modification TIME */
FILE_PIPE *f; /* for PIPE */ FILE_PIPE *f; /* for PIPE */
int flags; /* 2 = PIPE */ int fh_flags; /* 2 = PIPE */
/* 4 = don't reuse after close */ /* 4 = don't reuse after close */
/* 0x20 = readonly */ /* 0x20 = readonly */
char fname[256]; /* UNIX filename */ char fname[256]; /* UNIX filename */
} FILE_HANDLE; } FILE_HANDLE;
#define FILE_IS_READONLY 0x20
/* fh_flags */
#define FH_IS_PIPE 0x01
#define FH_IS_PIPE_COMMAND 0x02
#define FH_DO_NOT_REUSE 0x04
#define FH_IS_READONLY 0x20
extern void init_file_module(void); extern void init_file_module(void);

View File

@ -159,8 +159,6 @@ int ext_pclose(FILE_PIPE *fp)
waitpid(fp->command_pid, &status, 0); waitpid(fp->command_pid, &status, 0);
} }
kill(fp->command_pid, SIGKILL); kill(fp->command_pid, SIGKILL);
signal(SIGINT, intsave); signal(SIGINT, intsave);
signal(SIGQUIT, quitsave); signal(SIGQUIT, quitsave);
signal(SIGHUP, hupsave); signal(SIGHUP, hupsave);

View File

@ -40,6 +40,10 @@ int anz_net_devices=0;
NW_NET_DEVICE *net_devices[MAX_NET_DEVICES]; NW_NET_DEVICE *net_devices[MAX_NET_DEVICES];
uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */ uint16 ipx_sock_nummern[]={ SOCK_AUTO /* WDOG */
#ifdef PSERVER_SLOT
,SOCK_PSERVER
#endif
#if INTERNAL_RIP_SAP #if INTERNAL_RIP_SAP
,SOCK_SAP ,SOCK_SAP
#else #else

View File

@ -426,3 +426,12 @@ uint8 *downstr(uint8 *ss)
return(ss); return(ss);
} }
char *hex_str(char *buf, uint8 *s, int len)
{
char *pp=buf;
while (len--) {
int i = sprintf(pp, "%02x ", *s++);
pp += i;
}
return(buf);
}

View File

@ -59,6 +59,7 @@ extern uint8 up_char(uint8 ch);
extern uint8 *downstr(uint8 *ss); extern uint8 *downstr(uint8 *ss);
extern uint8 *upstr(uint8 *ss); extern uint8 *upstr(uint8 *ss);
extern char *hex_str(char *buf, uint8 *s, int len);
extern int nw_debug; extern int nw_debug;
#if DO_DEBUG #if DO_DEBUG