Compare commits

..

1 Commits

Author SHA1 Message Date
ncpfs archive import
b36a27bedb Import ncpfs 2.0.0 2026-04-28 20:39:58 +02:00
19 changed files with 463 additions and 20 deletions

BIN
.downloads/ncpfs-2.0.0.tgz Normal file

Binary file not shown.

View File

@@ -1,6 +1,12 @@
I only began this file with ncpfs-0.12. If you're interested in older
versions, you can find them on ftp.gwdg.de:/pub/linux/misc/ncpfs/old.
ncpfs-0.24 -> ncpfs-2.0.0
- Changed the numbering scheme :-).
- Added npasswd. Many thanks to Guntram Blom for his work!
- Hopefully improved error messages a bit
- Hopefully made slist a bit more robust
ncpfs-0.23 -> ncpfs-0.24
- Fixed a bug that made it impossible to umount a filesystem after you
tried 'mkdir .' or 'mkdir ..'.

View File

@@ -2,7 +2,7 @@
# Makefile for the linux ncp-filesystem routines.
#
VERSION = 0.24
VERSION = 2.0.0
# If you are using kerneld to autoload ncp support,
# uncomment this (kerneld is in linux since about 1.3.57):

6
README
View File

@@ -3,6 +3,12 @@ some little utilities it also contains nprint, which enables you to
print on NetWare print queues. The opposite side, pserver, is also
provided.
I'm planning major changes in the structure of ncpfs for Linux 2.1.x
which will break the binary compatibility. So I changed the numbering
scheme for ncpfs. ncpfs-2.0.x will be the version to be used with
Linux 2.0.0 and older kernels, and ncpfs-2.1.x will be the version for
the development kernels.
INSTALLATION
Before you start the installation, make sure that your kernel has IPX

View File

@@ -12,6 +12,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
struct option options[] = {
{ "auto_primary", required_argument, NULL, 1 },
@@ -66,8 +67,14 @@ main(int argc, char **argv)
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
int old_errno = errno;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL)
{
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
exit(-1);
}

View File

@@ -15,6 +15,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <errno.h>
static struct ifreq id;
static char *progname;
@@ -118,8 +119,14 @@ ipx_add_interface(int argc, char **argv)
s = socket(AF_IPX, SOCK_DGRAM, AF_IPX);
if (s < 0) {
int old_errno = errno;
sprintf(errmsg, "%s: socket", progname);
perror(errmsg);
if (old_errno == -EINVAL)
{
fprintf(stderr, "Probably you have no IPX support in "
"your kernel\n");
}
exit(-1);
}

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
MAN1= slist nprint pqlist nsend pserver ncopy
MAN1= slist nprint pqlist nsend pserver ncopy npasswd
MAN5= nwclient
MAN8= ncpmount ncpumount ipx_configure ipx_interface ipx_internal_net \
ipx_route nwmsg

55
man/npasswd.1 Normal file
View File

@@ -0,0 +1,55 @@
.TH NPASSWD 1 06/22/1996 npasswd npasswd
.SH NAME
npasswd \- Change a user's password
.SH SYNOPSIS
.B npasswd
[
.B -h
] [
.B -S
.I server
] [
.B -U
.I user name
]
.B -t
.I object type
]
.SH DESCRIPTION
With
.B npasswd,
you can change your password on a NetWare server.
.B npasswd
asks for the old password and twice for the new password. Then it
changes the password on the server.
.SH OPTIONS
.B -h
.RS 3
With -h npasswd prints a little help text.
.RE
.B -S
.I server
.RS 3
is the name of the server you want to use.
.RE
.B -U
.I user name
.RS 3
is the name of the bindery object whose password is to be changed.
.RE
.B -t
.I object type
.RS 3
is the bindery object type of the object whose password is to be
changed.
.RE
.SH CREDITS
npasswd would not have been possible without the work of Guntram
Blom. Look at nwcrypt.c for his work.

View File

@@ -1,7 +1,7 @@
Begin3
Title: ncpfs
Version: 0.24
Entered-date: 02. June 1996
Version: 2.0.0
Entered-date: 22. June 1996
Description: With ncpfs you can mount volumes of your netware
server under Linux. You can also print to netware
print queues and spool netware print queues to the
@@ -13,7 +13,7 @@ Author: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Maintained-by: lendecke@namu01.Num.Math.Uni-Goettingen.de (Volker Lendecke)
Primary-site: ftp.gwdg.de:/pub/linux/misc/ncpfs
Alternate-site: sunsite.unc.edu:/pub/system/Filesystems/ncpfs
~120k ncpfs-0.24.tgz
~ 1k ncpfs-0.24.lsm
~120k ncpfs-2.0.0.tgz
~ 1k ncpfs-2.0.0.lsm
Copying-policy: GPL
End

View File

@@ -2,7 +2,7 @@
# Makefile for the linux ncp-filesystem routines.
#
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy
USERUTILS = slist pqlist nwfsinfo pserver nprint nsend ncopy npasswd
UIDUTILS = ncpmount ncpumount
SBINUTILS = nwmsg

View File

@@ -237,6 +237,10 @@ ipx_sap_find_nearest(int server_type, struct sockaddr_ipx *result,
if ((sock = socket(AF_IPX,SOCK_DGRAM,PF_IPX)) < 0)
{
if (errno == EINVAL)
{
return NCPL_ET_NO_IPX;
}
return errno;
}
@@ -344,7 +348,11 @@ ipx_make_reachable(IPXNet network)
if (sock == -1)
{
return -1;
if (errno == EINVAL)
{
return NCPL_ET_NO_IPX;
}
return errno;
}
opt=1;
@@ -1833,7 +1841,7 @@ ncp_send_broadcast(struct ncp_conn *conn,
}
/*
* result is a 8-byte buffer
* target is a 8-byte buffer
*/
long
ncp_get_encryption_key(struct ncp_conn *conn,
@@ -1941,14 +1949,17 @@ ncp_scan_bindery_object(struct ncp_conn *conn,
long
ncp_create_bindery_object(struct ncp_conn *conn,
struct ncp_bindery_object *source)
__u16 object_type,
const char *object_name,
__u8 object_security,
__u8 object_status)
{
long result;
ncp_init_request_s(conn, 50);
ncp_add_byte(conn, source->object_flags);
ncp_add_byte(conn, source->object_security);
ncp_add_word(conn, htons(source->object_type));
ncp_add_pstring(conn, source->object_name);
ncp_add_byte(conn, object_status);
ncp_add_byte(conn, object_security);
ncp_add_word(conn, htons(object_type));
ncp_add_pstring(conn, object_name);
result = ncp_request(conn, 23);
ncp_unlock_conn(conn);
@@ -2163,6 +2174,43 @@ ncp_login_encrypted(struct ncp_conn *conn,
return result;
}
long
ncp_change_login_passwd(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *oldpasswd,
const unsigned char *newpasswd)
{
long id = htonl(object->object_id);
unsigned char cryptkey[8];
unsigned char newpwd[16]; /* new passwd as stored by server */
unsigned char oldpwd[16]; /* old passwd as stored by server */
unsigned char len;
long result;
memcpy(cryptkey, key, 8);
shuffle((byte *)&id, oldpasswd, strlen(oldpasswd), oldpwd);
shuffle((byte *)&id, newpasswd, strlen(newpasswd), newpwd);
nw_encrypt(cryptkey, oldpwd, cryptkey);
newpassencrypt(oldpwd, newpwd, newpwd);
newpassencrypt(oldpwd+8, newpwd+8, newpwd+8);
if ((len = strlen(newpasswd)) > 63)
{
len = 63;
}
len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40;
ncp_init_request_s(conn, 75);
ncp_add_mem(conn, cryptkey, 8);
ncp_add_word(conn, htons(object->object_type));
ncp_add_pstring(conn, object->object_name);
ncp_add_byte(conn, len);
ncp_add_mem(conn, newpwd, 16);
result = ncp_request(conn, 23);
ncp_unlock_conn(conn);
return result;
}
long
ncp_login_user(struct ncp_conn *conn,
const unsigned char *username,

View File

@@ -104,7 +104,7 @@ ncp_initialize_as(int *argc, char **argv,
int login_necessary, int login_type, long *err);
/* Open an existing permanent connection */
/* Open a connection */
struct ncp_conn *
ncp_open(const struct ncp_conn_spec *spec, long *err);
@@ -183,12 +183,21 @@ ncp_scan_bindery_object(struct ncp_conn *conn,
struct ncp_bindery_object *target);
long
ncp_create_bindery_object(struct ncp_conn *conn,
struct ncp_bindery_object *source);
__u16 object_type,
const char *object_name,
__u8 object_security,
__u8 object_status);
long
ncp_delete_bindery_object(struct ncp_conn *conn,
__u16 object_type,
const char *object_name);
long
ncp_change_object_security(struct ncp_conn *conn,
__u16 object_type,
const char *object_name,
__u8 security);
struct ncp_prop_login_control {
__u8 AccountExpireDate[3] __attribute__ ((packed));
__u8 Disabled __attribute__ ((packed));
@@ -256,6 +265,13 @@ ncp_login_encrypted(struct ncp_conn *conn,
const unsigned char *key,
const unsigned char *passwd);
long
ncp_change_login_passwd(struct ncp_conn *conn,
const struct ncp_bindery_object *object,
const unsigned char *key,
const unsigned char *oldpasswd,
const unsigned char *newpasswd);
#define NCP_GRACE_PERIOD (0xdf)
long

View File

@@ -33,4 +33,7 @@ ec NCPL_ET_NO_PASSWORD,
ec NCPL_ET_PWD_TOO_LONG,
"Password too long"
ec NCPL_ET_NO_IPX,
"Could not alloc IPX socket. Probably no IPX support in kernel."
end

View File

@@ -106,7 +106,30 @@ test_create(struct ncp_conn *conn)
return;
}
}
int
test_change(struct ncp_conn *conn)
{
long result;
unsigned char ncp_key[8];
struct ncp_bindery_object user;
if ((result = ncp_get_encryption_key(conn, ncp_key)) != 0) {
return result;
}
if ((result = ncp_get_bindery_object_id(conn, 1,
"ME", &user)) != 0) {
return result;
}
if ((result = ncp_change_login_passwd(conn, &user, ncp_key,
"MEE", "ME")) != 0)
{
return result;
}
return 0;
}
int
main(int argc, char *argv[])
@@ -120,7 +143,7 @@ main(int argc, char *argv[])
return 1;
}
test_send(conn);
test_change(conn);
ncp_close(conn);
return 0;
}

144
util/npasswd.c Normal file
View File

@@ -0,0 +1,144 @@
/*
* npasswd.c
*
* Change a bindery object's password
*
* Copyright (C) 1996 by Volker Lendecke
*
*/
#include "ncplib.h"
#include <unistd.h>
#include <stdlib.h>
static char *progname;
static void
usage(void)
{
fprintf(stderr, "usage: %s [options]\n", progname);
}
static void
help(void)
{
printf("\n");
printf("usage: %s [options]\n", progname);
printf("\n"
"-h Print this help text\n"
"-S server Server name to be used\n"
"-U username Username sent to server\n"
"-t type Object type (decimal value)\n"
"\n");
}
int
main(int argc, char *argv[])
{
struct ncp_conn_spec *spec;
struct ncp_conn *conn;
char *server = NULL;
char *object_name = NULL;
int object_type = NCP_BINDERY_USER;
unsigned char ncp_key[8];
struct ncp_bindery_object user;
long err;
char *str;
char oldpass[200], newpass1[200], newpass2[200];
int opt;
progname = argv[0];
while ((opt = getopt(argc, argv, "hS:U:t:")) != EOF)
{
switch(opt) {
case 'S':
server = optarg;
break;
case 'U':
object_name = optarg;
break;
case 't':
object_type = atoi(optarg);
break;
case 'h':
help();
exit(1);
default:
usage();
exit(1);
}
}
spec = ncp_find_conn_spec(server, object_name, "",
1, getuid(), &err);
if (spec == NULL)
{
com_err(argv[0], err, "trying to find server");
exit(1);
}
spec->login_type = object_type;
printf("Changing password for user %s on server %s\n",
spec->user, spec->server);
str = getpass("Enter old password: ");
if (strlen(str) >= sizeof(oldpass))
{
printf("Password too long\n");
exit(1);
}
strcpy(oldpass, str);
str = getpass("Enter new password: ");
if (strlen(str) >= sizeof(newpass1))
{
printf("Password too long\n");
exit(1);
}
strcpy(newpass1, str);
str = getpass("Re-Enter new password: ");
if (strlen(str) >= sizeof(newpass2))
{
printf("Password too long\n");
exit(1);
}
strcpy(newpass2, str);
str_upper(oldpass);
str_upper(newpass1);
str_upper(newpass2);
if (strcmp(newpass1, newpass2) != 0)
{
printf("You mistype the new password, try again\n");
exit(1);
}
strcpy(spec->password, oldpass);
if ((conn = ncp_open(spec, &err)) == NULL)
{
com_err(argv[0], err, "when trying to open connection");
exit(1);
}
if ( ((err = ncp_get_encryption_key(conn, ncp_key)) != 0)
|| ((err = ncp_get_bindery_object_id(conn, 1, spec->user,
&user)) != 0)
|| ((err = ncp_change_login_passwd(conn, &user, ncp_key,
oldpass, newpass1)) != 0))
{
com_err(argv[0], err, "trying to change password");
}
ncp_close(conn);
return 0;
}

View File

@@ -209,3 +209,131 @@ nw_encrypt(const unsigned char *fra,
}
/*****************************************************************************/
/* */
/* The following code was contributed by */
/* Guntram Blohm <gbl%th7csun1@str.daimler-benz.com> */
/* */
/*****************************************************************************/
/* server side (mars etc.) should:
* store the *encrypted* password internally (output from shuffle)
* verify if nw_encrypt(cryptkey from GetCryptKey, old stored password)
== cryptkey in EncryptedChangePassword request buffer (this means
old password was correct)
* decrypt new password in request buffer using (yet to write) inverse of
newpassencrypt with old stored password as parameter
* compute the length of the unencrypted new password as len ^ (first byte of
old internal password) ^ (second byte of old internal password)
*/
static 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,
};
/*
* verschluesseln des neuen Passworts fuer keyed change password
* Verwendung:
* - Shuffle (aus nwcrypt.c) altes passwort nach old (16 bytes)
* - shuffle neues passwort nach new (16 bytes)
* - nwpassencrypt (diese Funktion) zweimal aufrufen fuer je 8 bytes:
* nwpassencrypt(old+0, new+0, out+0)
* nwpassencrypt(old+8, new+8, out+8)
* - NCP-Buffer aufbauen:
* 2 byte Laenge im Hi-Lo-Format
* 1 byte Funktion (0x4b)
* 8 byte (nwcrypt Ergebnis analog login/verify password)
* 2 byte Objecttype
* 1 byte Objectname-Laenge
* n byte Objectname
* 1 byte (Laenge des eingegebenen neuen Passworts ^ old[0] ^ old[1])&0x7f|0x40
* 16 byte (Ergebnis dieser Funktion doppelt aufgerufen, s.o.)
*/
/*
* Encrypt the new password for keyed change password
* For info on how to use this function, look at ncp_change_login_passwd
* in ncplib.c.
*/
static void
newpassencrypt(char *old, char *new, char *out)
{
char *p, *bx;
char copy[8];
int i, di, ax;
char cl, dl, ch;
memcpy(copy, new, 8);
for (i=0; i<16; i++)
{
for (di=0, ax=0, p=old; di<8; di++, ax+=0x20, p++)
{
cl=newshuffle[(((copy[di]^*p)>>4)&0x0f)+ax+0x10]<<4;
dl=newshuffle[((copy[di]^*p)&0xf)+ax];
copy[di]=cl|dl;
}
ch=old[7];
for (bx=old+7; bx>old; bx--)
{
*bx=((bx[-1]>>4)&0x0f)|((*bx)<<4);
}
*old=((ch>>4)&0x0f)|(*old)<<4;
memset(out, '\0', 8);
for (di=0; di<16; di++)
{
if (newshuffle[di+0x100]&1)
ch=((copy[newshuffle[di+0x100]/2]>>4)&0x0f);
else
ch=copy[newshuffle[di+0x100]/2]&0x0f;
out[di/2]|=((di&1) ? ch<<4 : ch);
}
memcpy(copy, out, 8);
}
}

View File

@@ -41,9 +41,9 @@ main(int argc, char *argv[])
*p = toupper(*p);
}
if ((conn = ncp_initialize(&argc, argv, 0, &err)) == NULL)
if ((conn = ncp_open(NULL, &err)) == NULL)
{
com_err(argv[0], err, "in ncp_initialize");
com_err(argv[0], err, "in ncp_open");
exit(1);
}