ncpapi: collect protocol wrappers in c32ncp

Move the existing ncpXX_YY_* protocol wrapper implementations from ncpcall.c
into c32ncp.c.

This makes c32ncp.c the staging file for the future ncpapi.c rename, while
ncpcall.c is kept for lower-level requester/transport helpers. No function
names or packet logic are changed.

No behavior change.
This commit is contained in:
Mario Fetka
2026-05-29 11:21:06 +02:00
parent c152661eeb
commit 4b8e6e2792
2 changed files with 593 additions and 578 deletions

586
c32ncp.c
View File

@@ -2,6 +2,7 @@
* mars-nwe-dosutils - NetWare/DOS utility tools.
*
* Copyright (C) 2026 Mario Fetka
* Copyright (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
@@ -25,6 +26,591 @@
#include "net.h"
#include "c32ncp.h"
/*
* Legacy bindery/login NCP API wrappers.
*
* These ncp16/ncp17/ncp14 wrappers used to live in ncpcall.c. They are kept
* together with the other ncpXX_YY_* APIs here so the file can later be
* renamed to ncpapi.c.
*/
/* ---------------- 0x16 ----------------------------------- */
/*
* ncp16_02_get_directory_entry
*
* Purpose:
* Looks up a directory entry relative to a NetWare directory handle and
* returns the canonical subdirectory name, creation timestamp, owner object
* ID, subdirectory number and maximum rights mask.
*
* NCP:
* Function 0x16, subfunction 0x02. MARS-NWE admin documents this old
* filesystem call as Scan Directory Information / Get Directory Entry
* (F216/02).
*
* Requester path:
* Net_Call(0xE200), with a 16-bit request and reply length prefix.
*
* Returns:
* Maximum rights mask on success, or -1 when the requester/NCP call fails.
*/
int ncp16_02_get_directory_entry(int dirhandle,
uint8 *path,
int *sub_dir,
uint8 *resultpath,
uint32 *creattime,
uint32 *owner_id)
{
struct {
uint16 len;
uint8 func;
uint8 dirhandle;
uint8 sub_dir[2];
uint8 pathlen;
uint8 path[256];
} req;
struct {
uint16 len;
uint8 sub_dir_name[16];
uint8 create_date_time[4];
uint8 owner_id[4]; /* HI LOW */
uint8 max_right_mask;
uint8 reserved; /* Reserved by Novell */
uint8 sub_dir_nmbr[2]; /* HI LOW */
} repl = { sizeof(repl) - sizeof(uint16) };
req.func = 0x02;
U16_TO_BE16((sub_dir) ? *sub_dir : 1, req.sub_dir);
req.dirhandle = (uint8) dirhandle;
req.pathlen = (uint8) ((path) ? strlen(path) : 0);
req.len = 5 + req.pathlen;
strmaxcpy(req.path, path, req.pathlen);
neterrno = Net_Call(0xE200, &req, &repl);
if (neterrno) return(-1);
if (resultpath) strmaxcpy(resultpath, repl.sub_dir_name, 16);
if (sub_dir) *sub_dir = GET_BE16(repl.sub_dir_nmbr);
if (creattime) *creattime = GET_BE32(repl.create_date_time);
if (owner_id) *owner_id = GET_BE32(repl.owner_id);
return((int) repl.max_right_mask);
}
/* ---------------- 0x17 ----------------------------------- */
/*
* ncp17_02_set_debug_level
*
* Purpose:
* Sets a MARS-NWE debug level for one server module and returns the previous
* debug value. This is a MARS-NWE helper, not a normal Novell client command.
*
* NCP:
* Function group 0x17, subfunction 0x02.
*
* Requester path:
* Net_Call(0xE300), with a 16-bit request and reply length prefix.
*
* Returns:
* Previous debug level on success, or -1 when the requester/NCP call fails.
*/
int ncp17_02_set_debug_level(int module, int debuglevel)
{
struct {
uint16 len;
uint8 func;
uint8 module;
uint8 debug;
} req = { sizeof(req) - sizeof(uint16) };
struct {
uint16 len;
uint8 olddebug;
} repl = { sizeof(repl) - sizeof(uint16) };
req.func = 0x2;
req.module = (uint8) module;
req.debug = (uint8) debuglevel;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return((int) repl.olddebug);
}
/*
* ncp17_14_login_object_unencrypted
*
* Purpose:
* Logs in a bindery object using the legacy unencrypted password call.
*
* NCP:
* Function group 0x17, subfunction 0x14. This is the older unencrypted login
* path; encrypted login normally uses the key returned by subfunction 0x17
* and the keyed-login call below.
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name and counted
* password in the request body.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_14_login_object_unencrypted(uint8 *objname, uint16 objtyp, uint8 *password)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+128];
} req;
struct {
uint16 len;
} repl= { 0 };
uint8 *p=req.buff;
req.func = 0x14;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(47, strlen(objname));
memcpy(p, objname, req.namlen);
p += req.namlen;
*p = (uint8) min(128, strlen(password));
req.len = 4 + req.namlen + 1 + *p;
memcpy(p+1, password, (int) *p);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_17_get_encryption_key
*
* Purpose:
* Retrieves the 8-byte login encryption key used by the legacy bindery
* encrypted login and password-change helpers.
*
* NCP:
* Function group 0x17, subfunction 0x17.
*
* Requester path:
* Net_Call(0xE300). The reply contains the raw 8-byte key.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_17_get_encryption_key(uint8 *key)
{
struct {
uint16 len;
uint8 func;
} req;
struct {
uint16 len;
uint8 key[8];
} repl;
req.len = 1;
req.func = 0x17;
repl.len = 8;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
else {
memcpy(key, repl.key, 8);
return(0);
}
}
/*
* ncp17_18_keyed_object_login
*
* Purpose:
* Performs keyed/encrypted bindery object login using the 8-byte challenge
* returned by ncp17_17_get_encryption_key().
*
* NCP:
* Function group 0x17, subfunction 0x18.
*
* Requester path:
* Net_Call(0xE300), with key, object type and counted object name.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_18_keyed_object_login(uint8 *cryptkey, uint8 *objname, uint16 objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 key[8];
uint8 typ[2];
uint8 namlen;
uint8 name[48];
} req;
struct {
uint16 len;
} repl={ 0 };
req.len = sizeof(req) - sizeof(uint16);
req.func = 0x18;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(sizeof(req.name), strlen(objname));
memcpy(req.key, cryptkey, 8);
memcpy(req.name, objname, (int) req.namlen);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_35_get_bindery_object_id
*
* Purpose:
* Resolves a bindery object name and type to its 32-bit object ID. The
* canonical object name returned by the server is copied back to objname.
*
* NCP:
* Function group 0x17, subfunction 0x35, Get Bindery Object ID
* (MARS-NWE admin: F217/35; Novell SDK/WebSDK: Get Bindery Object ID).
*
* Requester path:
* Net_Call(0xE300), with big-endian object type and counted object name.
*
* Returns:
* Object ID on success, or 0 when the requester/NCP call fails.
*/
uint32 ncp17_35_get_bindery_object_id(uint8 *objname, uint16 objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 name[48];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
} repl;
req.len = sizeof(req) - sizeof(uint16);
repl.len = sizeof(repl) - sizeof(uint16);
req.func = 0x35;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(sizeof(req.name), strlen(objname));
memcpy(req.name, objname, (int) req.namlen);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(0L);
strmaxcpy(objname, repl.object_name, 47);
return(GET_BE32(repl.object_id));
}
/*
* ncp17_36_get_bindery_object_name
*
* Purpose:
* Resolves a 32-bit bindery object ID to its object name and type.
*
* NCP:
* Function group 0x17, subfunction 0x36, Get Bindery Object Name
* (MARS-NWE admin: F217/36; Novell SDK/WebSDK: Get Bindery Object Name).
*
* Requester path:
* Net_Call(0xE300), with the object ID in big-endian order.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_36_get_bindery_object_name(uint32 obj_id, uint8 *objname, uint16 *objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 id[4];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
} repl;
req.len = sizeof(req) - sizeof(uint16);
repl.len = sizeof(repl) - sizeof(uint16);
req.func = 0x36;
U32_TO_BE32(obj_id, req.id);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (objname) strmaxcpy(objname, repl.object_name, 47);
if (objtyp) *objtyp = GET_BE16(repl.object_type);
return(0);
}
/*
* ncp17_40_change_password_unencrypted
*
* Purpose:
* Changes a bindery object's password using the legacy unencrypted password
* call.
*
* NCP:
* Function group 0x17, subfunction 0x40, Change Bindery Object Password
* (MARS-NWE admin: F217/40).
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name, counted old
* password and counted new password.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_40_change_password_unencrypted(uint8 *objname, uint16 objtyp,
uint8 *password, uint8 *newpassword)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+128+1+128];
} req;
struct {
uint16 len;
} repl = { 0 };
uint8 *p=req.buff;
req.func = 0x40;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(47, strlen(objname));
memcpy(p, objname, req.namlen);
p += req.namlen;
*p = (uint8) min(128, strlen(password));
req.len = 4 + req.namlen + 1 + *p;
memcpy(p+1, password, (int) *p);
p += (1 + *p);
*p = (uint8) min(128, strlen(newpassword));
req.len += (1 + *p);
memcpy(p+1, newpassword, (int) *p);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp14_46_get_bindery_access_level
*
* Purpose:
* Reads the current bindery access level and the logged-in object's object ID.
*
* NCP:
* Bindery subfunction 0x46, Get Bindery Access Level. The historic local
* wrapper was named ncp_14_46; keep the ncp14_ prefix to preserve that
* protocol reference even though the call is sent through Net_Call(0xE300).
*
* Requester path:
* Net_Call(0xE300). The reply contains one access byte followed by the
* current object's 32-bit object ID in big-endian order.
*
* Returns:
* Access level on success, or -1 when the requester/NCP call fails.
*/
int ncp14_46_get_bindery_access_level(uint32 *obj_id)
{
struct {
uint16 len;
uint8 func;
} req;
struct {
uint16 len;
uint8 access;
uint8 id[4];
} repl;
req.len = 1;
req.func = 0x46;
repl.len = 5;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
else {
if (obj_id) *obj_id = GET_BE32(repl.id);
return(repl.access);
}
}
/*
* ncp17_4b_keyed_change_password
*
* Purpose:
* Changes a bindery object's password using the keyed/encrypted password
* change path.
*
* NCP:
* Function group 0x17, subfunction 0x4b, Change Encrypted Bindery Object
* Password (MARS-NWE admin: F217/4B).
*
* Requester path:
* Net_Call(0xE300), with the login encryption key, object type, counted
* object name, password length selector and encrypted new password bytes.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_4b_keyed_change_password(uint8 *cryptkey, uint8 *objname, uint16 objtyp,
int passwx, uint8 *newpassword)
{
struct {
uint16 len;
uint8 func;
uint8 key[8];
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+16];
} req;
struct {
uint16 len;
} repl = { 0 };
uint8 *p = req.buff;
req.func = 0x4b;
memcpy(req.key, cryptkey, 8);
U16_TO_BE16(objtyp, req.typ);
req.namlen = (uint8) min(48, strlen(objname));
req.len = 12 + req.namlen + 1 + 16;
memcpy(p, objname, (int) req.namlen);
p += req.namlen;
*p++ = (uint8) passwx;
memcpy(p, newpassword, 16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_37_scan_bindery_object
*
* Purpose:
* Iterates over bindery objects matching an object type and name pattern.
* Pass last_id as -1 for the first call and then feed back the object ID
* returned in target to continue scanning.
*
* NCP:
* Function group 0x17, subfunction 0x37, Scan Bindery Object
* (MARS-NWE admin: F217/37; Novell SDK/WebSDK: Scan Bindery Object).
*
* Requester path:
* Net_Call(0xE300), with last object ID, search object type and counted
* pattern. A NULL pattern is sent as '*'.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_37_scan_bindery_object(uint32 last_id, uint16 objtyp, uint8 *pattern,
BINDERY_OBJECT *target)
{
struct {
uint16 len;
uint8 func;
uint8 last_id[4];
uint8 typ[2];
uint8 patlen;
uint8 pattern[48];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
uint8 object_flags;
uint8 object_security;
uint8 object_has_prop;
} repl;
int patlen = (pattern) ? min(48, strlen(pattern)) : 1;
memset(&req, 0, sizeof(req));
memset(&repl, 0, sizeof(repl));
req.func = 0x37;
U32_TO_BE32(last_id, req.last_id);
U16_TO_BE16(objtyp, req.typ);
req.patlen = (uint8)patlen;
if (pattern) memcpy(req.pattern, pattern, patlen);
else req.pattern[0] = '*';
req.len = 8 + patlen;
repl.len = sizeof(repl) - sizeof(uint16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (target) {
target->object_id = GET_BE32(repl.object_id);
target->object_type = GET_BE16(repl.object_type);
memcpy(target->object_name, repl.object_name, 48);
target->object_name[48] = '\0';
deb(target->object_name);
target->object_flags = repl.object_flags;
target->object_security = repl.object_security;
target->object_has_prop = repl.object_has_prop;
}
return(0);
}
/*
* ncp17_3d_read_property_value
*
* Purpose:
* Reads one 128-byte segment of a bindery property value and returns the
* server's continuation and property flags.
*
* NCP:
* Function group 0x17, subfunction 0x3d, Read Property Value
* (MARS-NWE admin: F217/3D; Novell SDK/WebSDK: Read Property Value).
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name, segment number
* and counted property name.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_3d_read_property_value(uint16 objtyp, uint8 *objname, int segment,
uint8 *propname, NW_PROPERTY *target)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 buff[1+48+1+1+16];
} req;
struct {
uint16 len;
uint8 value[128];
uint8 more_flag;
uint8 property_flag;
} repl;
uint8 *p = req.buff;
int objlen = min(48, strlen(objname));
int proplen = min(16, strlen(propname));
memset(&req, 0, sizeof(req));
memset(&repl, 0, sizeof(repl));
req.func = 0x3d;
U16_TO_BE16(objtyp, req.typ);
*p++ = (uint8)objlen;
memcpy(p, objname, objlen);
p += objlen;
*p++ = (uint8)segment;
*p++ = (uint8)proplen;
memcpy(p, propname, proplen);
req.len = 6 + objlen + proplen;
repl.len = sizeof(repl) - sizeof(uint16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (target) {
memcpy(target->value, repl.value, 128);
target->more_flag = repl.more_flag;
target->property_flag = repl.property_flag;
}
return(0);
}
/* c32ncp.c - namespace/file-system NCP API helpers for mars-dosutils */
/*

585
ncpcall.c
View File

@@ -19,585 +19,14 @@
*/
/*
* Purpose: Low-level NCP bindery, filesystem and server helper routines used by multiple commands.
* Depends on: net.h, netcall.c requester glue, kern_wasm.asm/kern.asm Net_Call entry point, tools.c shared utility routines.
* Purpose: Low-level NCP requester call helper placeholder for the NetWare DOS tools.
* Depends on: net.h, netcall.c requester glue, kern_wasm.asm/kern.asm Net_Call entry point.
*
* The public ncpXX_YY_* protocol wrappers have been moved to c32ncp.c,
* which is planned to become ncpapi.c. This file is kept for future raw
* requester/transport helpers.
*/
#include "net.h"
/* ---------------- 0x16 ----------------------------------- */
/*
* ncp16_02_get_directory_entry
*
* Purpose:
* Looks up a directory entry relative to a NetWare directory handle and
* returns the canonical subdirectory name, creation timestamp, owner object
* ID, subdirectory number and maximum rights mask.
*
* NCP:
* Function 0x16, subfunction 0x02. MARS-NWE admin documents this old
* filesystem call as Scan Directory Information / Get Directory Entry
* (F216/02).
*
* Requester path:
* Net_Call(0xE200), with a 16-bit request and reply length prefix.
*
* Returns:
* Maximum rights mask on success, or -1 when the requester/NCP call fails.
*/
int ncp16_02_get_directory_entry(int dirhandle,
uint8 *path,
int *sub_dir,
uint8 *resultpath,
uint32 *creattime,
uint32 *owner_id)
{
struct {
uint16 len;
uint8 func;
uint8 dirhandle;
uint8 sub_dir[2];
uint8 pathlen;
uint8 path[256];
} req;
struct {
uint16 len;
uint8 sub_dir_name[16];
uint8 create_date_time[4];
uint8 owner_id[4]; /* HI LOW */
uint8 max_right_mask;
uint8 reserved; /* Reserved by Novell */
uint8 sub_dir_nmbr[2]; /* HI LOW */
} repl = { sizeof(repl) - sizeof(uint16) };
req.func = 0x02;
U16_TO_BE16((sub_dir) ? *sub_dir : 1, req.sub_dir);
req.dirhandle = (uint8) dirhandle;
req.pathlen = (uint8) ((path) ? strlen(path) : 0);
req.len = 5 + req.pathlen;
strmaxcpy(req.path, path, req.pathlen);
neterrno = Net_Call(0xE200, &req, &repl);
if (neterrno) return(-1);
if (resultpath) strmaxcpy(resultpath, repl.sub_dir_name, 16);
if (sub_dir) *sub_dir = GET_BE16(repl.sub_dir_nmbr);
if (creattime) *creattime = GET_BE32(repl.create_date_time);
if (owner_id) *owner_id = GET_BE32(repl.owner_id);
return((int) repl.max_right_mask);
}
/* ---------------- 0x17 ----------------------------------- */
/*
* ncp17_02_set_debug_level
*
* Purpose:
* Sets a MARS-NWE debug level for one server module and returns the previous
* debug value. This is a MARS-NWE helper, not a normal Novell client command.
*
* NCP:
* Function group 0x17, subfunction 0x02.
*
* Requester path:
* Net_Call(0xE300), with a 16-bit request and reply length prefix.
*
* Returns:
* Previous debug level on success, or -1 when the requester/NCP call fails.
*/
int ncp17_02_set_debug_level(int module, int debuglevel)
{
struct {
uint16 len;
uint8 func;
uint8 module;
uint8 debug;
} req = { sizeof(req) - sizeof(uint16) };
struct {
uint16 len;
uint8 olddebug;
} repl = { sizeof(repl) - sizeof(uint16) };
req.func = 0x2;
req.module = (uint8) module;
req.debug = (uint8) debuglevel;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return((int) repl.olddebug);
}
/*
* ncp17_14_login_object_unencrypted
*
* Purpose:
* Logs in a bindery object using the legacy unencrypted password call.
*
* NCP:
* Function group 0x17, subfunction 0x14. This is the older unencrypted login
* path; encrypted login normally uses the key returned by subfunction 0x17
* and the keyed-login call below.
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name and counted
* password in the request body.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_14_login_object_unencrypted(uint8 *objname, uint16 objtyp, uint8 *password)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+128];
} req;
struct {
uint16 len;
} repl= { 0 };
uint8 *p=req.buff;
req.func = 0x14;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(47, strlen(objname));
memcpy(p, objname, req.namlen);
p += req.namlen;
*p = (uint8) min(128, strlen(password));
req.len = 4 + req.namlen + 1 + *p;
memcpy(p+1, password, (int) *p);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_17_get_encryption_key
*
* Purpose:
* Retrieves the 8-byte login encryption key used by the legacy bindery
* encrypted login and password-change helpers.
*
* NCP:
* Function group 0x17, subfunction 0x17.
*
* Requester path:
* Net_Call(0xE300). The reply contains the raw 8-byte key.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_17_get_encryption_key(uint8 *key)
{
struct {
uint16 len;
uint8 func;
} req;
struct {
uint16 len;
uint8 key[8];
} repl;
req.len = 1;
req.func = 0x17;
repl.len = 8;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
else {
memcpy(key, repl.key, 8);
return(0);
}
}
/*
* ncp17_18_keyed_object_login
*
* Purpose:
* Performs keyed/encrypted bindery object login using the 8-byte challenge
* returned by ncp17_17_get_encryption_key().
*
* NCP:
* Function group 0x17, subfunction 0x18.
*
* Requester path:
* Net_Call(0xE300), with key, object type and counted object name.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_18_keyed_object_login(uint8 *cryptkey, uint8 *objname, uint16 objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 key[8];
uint8 typ[2];
uint8 namlen;
uint8 name[48];
} req;
struct {
uint16 len;
} repl={ 0 };
req.len = sizeof(req) - sizeof(uint16);
req.func = 0x18;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(sizeof(req.name), strlen(objname));
memcpy(req.key, cryptkey, 8);
memcpy(req.name, objname, (int) req.namlen);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_35_get_bindery_object_id
*
* Purpose:
* Resolves a bindery object name and type to its 32-bit object ID. The
* canonical object name returned by the server is copied back to objname.
*
* NCP:
* Function group 0x17, subfunction 0x35, Get Bindery Object ID
* (MARS-NWE admin: F217/35; Novell SDK/WebSDK: Get Bindery Object ID).
*
* Requester path:
* Net_Call(0xE300), with big-endian object type and counted object name.
*
* Returns:
* Object ID on success, or 0 when the requester/NCP call fails.
*/
uint32 ncp17_35_get_bindery_object_id(uint8 *objname, uint16 objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 name[48];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
} repl;
req.len = sizeof(req) - sizeof(uint16);
repl.len = sizeof(repl) - sizeof(uint16);
req.func = 0x35;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(sizeof(req.name), strlen(objname));
memcpy(req.name, objname, (int) req.namlen);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(0L);
strmaxcpy(objname, repl.object_name, 47);
return(GET_BE32(repl.object_id));
}
/*
* ncp17_36_get_bindery_object_name
*
* Purpose:
* Resolves a 32-bit bindery object ID to its object name and type.
*
* NCP:
* Function group 0x17, subfunction 0x36, Get Bindery Object Name
* (MARS-NWE admin: F217/36; Novell SDK/WebSDK: Get Bindery Object Name).
*
* Requester path:
* Net_Call(0xE300), with the object ID in big-endian order.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_36_get_bindery_object_name(uint32 obj_id, uint8 *objname, uint16 *objtyp)
{
struct {
uint16 len;
uint8 func;
uint8 id[4];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
} repl;
req.len = sizeof(req) - sizeof(uint16);
repl.len = sizeof(repl) - sizeof(uint16);
req.func = 0x36;
U32_TO_BE32(obj_id, req.id);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (objname) strmaxcpy(objname, repl.object_name, 47);
if (objtyp) *objtyp = GET_BE16(repl.object_type);
return(0);
}
/*
* ncp17_40_change_password_unencrypted
*
* Purpose:
* Changes a bindery object's password using the legacy unencrypted password
* call.
*
* NCP:
* Function group 0x17, subfunction 0x40, Change Bindery Object Password
* (MARS-NWE admin: F217/40).
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name, counted old
* password and counted new password.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_40_change_password_unencrypted(uint8 *objname, uint16 objtyp,
uint8 *password, uint8 *newpassword)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+128+1+128];
} req;
struct {
uint16 len;
} repl = { 0 };
uint8 *p=req.buff;
req.func = 0x40;
U16_TO_BE16(objtyp, req.typ);
req.namlen = min(47, strlen(objname));
memcpy(p, objname, req.namlen);
p += req.namlen;
*p = (uint8) min(128, strlen(password));
req.len = 4 + req.namlen + 1 + *p;
memcpy(p+1, password, (int) *p);
p += (1 + *p);
*p = (uint8) min(128, strlen(newpassword));
req.len += (1 + *p);
memcpy(p+1, newpassword, (int) *p);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp14_46_get_bindery_access_level
*
* Purpose:
* Reads the current bindery access level and the logged-in object's object ID.
*
* NCP:
* Bindery subfunction 0x46, Get Bindery Access Level. The historic local
* wrapper was named ncp_14_46; keep the ncp14_ prefix to preserve that
* protocol reference even though the call is sent through Net_Call(0xE300).
*
* Requester path:
* Net_Call(0xE300). The reply contains one access byte followed by the
* current object's 32-bit object ID in big-endian order.
*
* Returns:
* Access level on success, or -1 when the requester/NCP call fails.
*/
int ncp14_46_get_bindery_access_level(uint32 *obj_id)
{
struct {
uint16 len;
uint8 func;
} req;
struct {
uint16 len;
uint8 access;
uint8 id[4];
} repl;
req.len = 1;
req.func = 0x46;
repl.len = 5;
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
else {
if (obj_id) *obj_id = GET_BE32(repl.id);
return(repl.access);
}
}
/*
* ncp17_4b_keyed_change_password
*
* Purpose:
* Changes a bindery object's password using the keyed/encrypted password
* change path.
*
* NCP:
* Function group 0x17, subfunction 0x4b, Change Encrypted Bindery Object
* Password (MARS-NWE admin: F217/4B).
*
* Requester path:
* Net_Call(0xE300), with the login encryption key, object type, counted
* object name, password length selector and encrypted new password bytes.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_4b_keyed_change_password(uint8 *cryptkey, uint8 *objname, uint16 objtyp,
int passwx, uint8 *newpassword)
{
struct {
uint16 len;
uint8 func;
uint8 key[8];
uint8 typ[2];
uint8 namlen;
uint8 buff[48+1+16];
} req;
struct {
uint16 len;
} repl = { 0 };
uint8 *p = req.buff;
req.func = 0x4b;
memcpy(req.key, cryptkey, 8);
U16_TO_BE16(objtyp, req.typ);
req.namlen = (uint8) min(48, strlen(objname));
req.len = 12 + req.namlen + 1 + 16;
memcpy(p, objname, (int) req.namlen);
p += req.namlen;
*p++ = (uint8) passwx;
memcpy(p, newpassword, 16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
return(0);
}
/*
* ncp17_37_scan_bindery_object
*
* Purpose:
* Iterates over bindery objects matching an object type and name pattern.
* Pass last_id as -1 for the first call and then feed back the object ID
* returned in target to continue scanning.
*
* NCP:
* Function group 0x17, subfunction 0x37, Scan Bindery Object
* (MARS-NWE admin: F217/37; Novell SDK/WebSDK: Scan Bindery Object).
*
* Requester path:
* Net_Call(0xE300), with last object ID, search object type and counted
* pattern. A NULL pattern is sent as '*'.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_37_scan_bindery_object(uint32 last_id, uint16 objtyp, uint8 *pattern,
BINDERY_OBJECT *target)
{
struct {
uint16 len;
uint8 func;
uint8 last_id[4];
uint8 typ[2];
uint8 patlen;
uint8 pattern[48];
} req;
struct {
uint16 len;
uint8 object_id[4];
uint8 object_type[2];
uint8 object_name[48];
uint8 object_flags;
uint8 object_security;
uint8 object_has_prop;
} repl;
int patlen = (pattern) ? min(48, strlen(pattern)) : 1;
memset(&req, 0, sizeof(req));
memset(&repl, 0, sizeof(repl));
req.func = 0x37;
U32_TO_BE32(last_id, req.last_id);
U16_TO_BE16(objtyp, req.typ);
req.patlen = (uint8)patlen;
if (pattern) memcpy(req.pattern, pattern, patlen);
else req.pattern[0] = '*';
req.len = 8 + patlen;
repl.len = sizeof(repl) - sizeof(uint16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (target) {
target->object_id = GET_BE32(repl.object_id);
target->object_type = GET_BE16(repl.object_type);
memcpy(target->object_name, repl.object_name, 48);
target->object_name[48] = '\0';
deb(target->object_name);
target->object_flags = repl.object_flags;
target->object_security = repl.object_security;
target->object_has_prop = repl.object_has_prop;
}
return(0);
}
/*
* ncp17_3d_read_property_value
*
* Purpose:
* Reads one 128-byte segment of a bindery property value and returns the
* server's continuation and property flags.
*
* NCP:
* Function group 0x17, subfunction 0x3d, Read Property Value
* (MARS-NWE admin: F217/3D; Novell SDK/WebSDK: Read Property Value).
*
* Requester path:
* Net_Call(0xE300), with object type, counted object name, segment number
* and counted property name.
*
* Returns:
* 0 on success, or -1 when the requester/NCP call fails.
*/
int ncp17_3d_read_property_value(uint16 objtyp, uint8 *objname, int segment,
uint8 *propname, NW_PROPERTY *target)
{
struct {
uint16 len;
uint8 func;
uint8 typ[2];
uint8 buff[1+48+1+1+16];
} req;
struct {
uint16 len;
uint8 value[128];
uint8 more_flag;
uint8 property_flag;
} repl;
uint8 *p = req.buff;
int objlen = min(48, strlen(objname));
int proplen = min(16, strlen(propname));
memset(&req, 0, sizeof(req));
memset(&repl, 0, sizeof(repl));
req.func = 0x3d;
U16_TO_BE16(objtyp, req.typ);
*p++ = (uint8)objlen;
memcpy(p, objname, objlen);
p += objlen;
*p++ = (uint8)segment;
*p++ = (uint8)proplen;
memcpy(p, propname, proplen);
req.len = 6 + objlen + proplen;
repl.len = sizeof(repl) - sizeof(uint16);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno) return(-1);
if (target) {
memcpy(target->value, repl.value, 128);
target->more_flag = repl.more_flag;
target->property_flag = repl.property_flag;
}
return(0);
}
/* No exported wrappers live here at the moment. */