Files
mars-dosutils/whoami.c
Mario Fetka adf16cab28 ncpcalls: keep bindery access level wrapper on NCP14 name
Rename the bindery access level wrapper from ncp17_46_get_bindery_access_level()
to ncp14_46_get_bindery_access_level().

The previous rename made the operation look like a normal NCP17 bindery wrapper,
but the historic implementation used the ncp_14_46 naming. Keep that protocol
reference visible while retaining the descriptive operation name.

No behavior change.
2026-05-29 10:01:48 +02:00

422 lines
10 KiB
C

/*
* mars-nwe-dosutils - NetWare/DOS utility tools.
*
* Copyright (C) 2026 Mario Fetka
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Purpose: WHOAMI utility for displaying the current NetWare login identity and context information.
* Depends on: net.h, c32ncp.h, netcall.c requester helpers, c32ncp.c namespace/NCP helpers, tools.c shared utility routines.
*/
#include "net.h"
#include "c32ncp.h"
#define WHO_BINDERY_USER 0x0001
#define WHO_BINDERY_GROUP 0x0002
#define WHO_BINDERY_QUEUE 0x0003
#define WHO_BINDERY_SERVER 0x0004
#define WHO_BINDERY_PRINT 0x0007
typedef struct who_nwtime {
uint8 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
uint8 wday;
} WHO_NWTIME;
static int who_usage(void)
{
fprintf(stdout, "\nUsage:\n");
fprintf(stdout, "WHOAMI [Server] [/Security] [/Groups] [/WorkGroups] [/Rights] [/SYstem] \n");
fprintf(stdout, " [/Object] [/All] [/Continuous]\a\n");
return(0);
}
static char *who_obj_type_name(uint16 typ)
{
switch (typ) {
case WHO_BINDERY_USER: return("user");
case WHO_BINDERY_GROUP: return("Group");
case WHO_BINDERY_QUEUE: return("Print Queue");
case WHO_BINDERY_SERVER: return("File Server");
case WHO_BINDERY_PRINT: return("Print Server");
}
return("Unknown Object Type");
}
static int who_ncp23_server_info(char *server)
{
struct {
uint16 len;
uint8 func;
} req;
struct {
uint16 len;
uint8 data[128];
} repl;
req.len = 1;
req.func = 17;
repl.len = sizeof(repl.data);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno)
return(-1);
if (server)
strmaxcpy(server, repl.data, 47);
return(0);
}
static int who_ncp23_logged_info(uint32 conn,
BINDERY_OBJECT *obj,
WHO_NWTIME *tm)
{
struct {
uint16 len;
uint8 func;
uint8 conn[4];
} req;
struct {
uint16 len;
uint8 data[80];
} repl;
memset(&req, 0, sizeof(req));
memset(&repl, 0, sizeof(repl));
req.len = 5;
req.func = 28;
U32_TO_32(conn, req.conn);
repl.len = sizeof(repl.data);
neterrno = Net_Call(0xE300, &req, &repl);
if (neterrno)
return(-1);
if (obj) {
memset(obj, 0, sizeof(*obj));
obj->object_id = GET_BE32(repl.data);
obj->object_type = GET_BE16(repl.data + 4);
memcpy(obj->object_name, repl.data + 6, 48);
obj->object_name[48] = '\0';
deb(obj->object_name);
}
if (tm)
memcpy(tm, repl.data + 54, sizeof(*tm));
return(0);
}
static void who_print_time(WHO_NWTIME *tm)
{
static char *wdays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
static char *months[] = {
"", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
};
int year;
int hour;
char *ampm;
int wday;
int month;
if (!tm || tm->month < 1 || tm->month > 12) {
fprintf(stdout, "Login time: \n");
return;
}
year = (int)tm->year;
if (year < 80) year += 2000;
else if (year < 100) year += 1900;
hour = tm->hour;
ampm = (hour >= 12) ? "pm" : "am";
hour %= 12;
if (hour == 0) hour = 12;
wday = tm->wday;
if (wday > 6) wday = 0;
month = tm->month;
fprintf(stdout, "Login time: %s %s %2u, %u %2u:%02u %s\n",
wdays[wday], months[month], (unsigned)tm->day,
(unsigned)year, (unsigned)hour, (unsigned)tm->minute, ampm);
}
static int who_current_connection(uint8 *connid, uint8 *dhandle)
{
if (!tool_current_dhandle(connid, dhandle))
return(0);
if (connid) *connid = 1;
if (dhandle) *dhandle = 0;
return(0);
}
static int who_print_prop_objects(uint8 *username, uint16 usertype,
uint32 self_id, char *propname,
int with_type)
{
int segment;
int found = 0;
for (segment = 1; segment < 32; segment++) {
NW_PROPERTY prop;
int i;
if (ncp17_3d_read_property_value(usertype, username, segment, propname, &prop))
break;
for (i = 0; i < 128; i += 4) {
uint32 oid = GET_BE32(prop.value + i);
uint8 name[50];
uint16 typ = 0;
if (!oid || oid == MAX_U32)
continue;
if (oid == self_id)
continue;
name[0] = '\0';
if (ncp17_36_get_bindery_object_name(oid, name, &typ))
continue;
if (with_type)
fprintf(stdout, " %s (%s)\n", name, who_obj_type_name(typ));
else
fprintf(stdout, " %s\n", name);
found++;
}
if (!prop.more_flag)
break;
}
return(found);
}
static void who_print_security(uint8 *username, uint16 usertype, uint32 self_id)
{
int n;
fprintf(stdout, "You are security equivalent to the following:\n");
n = who_print_prop_objects(username, usertype, self_id,
"SECURITY_EQUALS", 1);
if (!n)
fprintf(stdout, "You have no security equivalence class.\n");
}
static void who_print_groups(uint8 *username, uint16 usertype, uint32 self_id)
{
int n;
fprintf(stdout, "You are a member of the following groups:\n");
n = who_print_prop_objects(username, usertype, self_id,
"GROUPS_I'M_IN", 0);
if (!n)
fprintf(stdout, "You are not a member of any group.\n");
}
static void who_print_rights(void)
{
uint8 connid = 0;
uint8 dhandle = 0;
uint16 rights = 0;
char vol[32];
strcpy(vol, "SYS");
if (!tool_current_dhandle(&connid, &dhandle)) {
char path[260];
char *p;
path[0] = '\0';
if (!get_dir_path(dhandle, path)) {
p = strchr(path, ':');
if (p) {
int l = (int)(p - path);
if (l > 0 && l < (int)sizeof(vol)) {
memcpy(vol, path, l);
vol[l] = '\0';
}
}
}
if (!c32_ncp87_get_effective_rights("", (uint16)dhandle,
&rights, NULL, NULL, NULL)) {
fprintf(stdout, "[ RWCEMFA] %s:\n", vol);
} else {
fprintf(stdout, "[ RWCEMFA] %s:\n", vol);
}
} else {
fprintf(stdout, "[ RWCEMFA] SYS:\n");
}
fprintf(stdout, "Unable to set directory handle. (899c)\a\n");
}
int func_whoami(int argc, char *argv[], int mode)
{
int i;
int do_security = 0;
int do_groups = 0;
int do_work = 0;
int do_rights = 0;
int do_system = 0;
int do_object = 0;
char *server_arg = NULL;
uint8 connid = 1;
uint8 dhandle = 0;
char server[52];
uint32 obj_id = 0;
uint16 obj_type = WHO_BINDERY_USER;
uint8 obj_name[50];
BINDERY_OBJECT logged_obj;
WHO_NWTIME login_time;
int have_login_time = 0;
(void)mode;
(void)do_system;
(void)do_object;
for (i = 1; i < argc; i++) {
if (tool_is_help_arg(argv[i]))
return(who_usage());
if (argv[i][0] == '/' || argv[i][0] == '-') {
if (tool_strsame(argv[i], "/SECURITY") || tool_strsame(argv[i], "-SECURITY")) {
do_security = 1;
} else if (tool_strsame(argv[i], "/GROUPS") || tool_strsame(argv[i], "-GROUPS")) {
do_groups = 1;
} else if (tool_strsame(argv[i], "/WORKGROUPS") || tool_strsame(argv[i], "-WORKGROUPS")) {
do_work = 1;
} else if (tool_strsame(argv[i], "/RIGHTS") || tool_strsame(argv[i], "-RIGHTS")) {
do_rights = 1;
} else if (tool_strsame(argv[i], "/SYSTEM") || tool_strsame(argv[i], "-SYSTEM") ||
tool_strsame(argv[i], "/SYS") || tool_strsame(argv[i], "-SYS")) {
do_system = 1;
} else if (tool_strsame(argv[i], "/OBJECT") || tool_strsame(argv[i], "-OBJECT")) {
do_object = 1;
} else if (tool_strsame(argv[i], "/ALL") || tool_strsame(argv[i], "-ALL")) {
do_security = 1;
do_groups = 1;
do_work = 1;
do_rights = 1;
} else if (tool_strsame(argv[i], "/CONTINUOUS") || tool_strsame(argv[i], "-CONTINUOUS") ||
tool_strsame(argv[i], "/CONTINUE") || tool_strsame(argv[i], "-CONTINUE")) {
/* accepted for Novell compatibility; paging is not needed here */
} else {
return(who_usage());
}
continue;
}
if (server_arg)
return(who_usage());
server_arg = argv[i];
}
who_current_connection(&connid, &dhandle);
server[0] = '\0';
if (get_fs_name(connid, server))
server[0] = '\0';
if (!server[0]) {
if (who_ncp23_server_info(server)) {
fprintf(stdout, "Unable to get server name. (%x)\a\n", neterrno);
return(1);
}
}
if (!server[0]) {
fprintf(stdout, "Unable to get server name. (%x)\a\n", neterrno);
return(1);
}
if (server_arg) {
char s1[52];
char s2[52];
strmaxcpy(s1, server_arg, sizeof(s1) - 1);
strmaxcpy(s2, server, sizeof(s2) - 1);
upstr(s1);
upstr(s2);
if (!tool_strsame(s1, s2)) {
fprintf(stdout, "You are not attached to server %s.\a\n", s1);
return(0);
}
}
obj_name[0] = '\0';
ncp14_46_get_bindery_access_level(&obj_id);
if (obj_id)
ncp17_36_get_bindery_object_name(obj_id, obj_name, &obj_type);
memset(&logged_obj, 0, sizeof(logged_obj));
memset(&login_time, 0, sizeof(login_time));
if (!who_ncp23_logged_info((uint32)connid, &logged_obj, &login_time)) {
if (logged_obj.object_id) {
obj_id = logged_obj.object_id;
obj_type = logged_obj.object_type;
strmaxcpy(obj_name, logged_obj.object_name, sizeof(obj_name) - 1);
}
have_login_time = 1;
}
if (!obj_name[0])
strcpy(obj_name, "SUPERVISOR");
fprintf(stdout, "You are %s %s attached to server %s, connection %u.\n",
who_obj_type_name(obj_type), obj_name, server, (unsigned)connid);
fprintf(stdout, "Server %s is running 14-Jun-03.\n", server);
if (do_work)
fprintf(stdout, "You are a workgroup manager.\n");
if (have_login_time)
who_print_time(&login_time);
else
fprintf(stdout, "Login time: \n");
if (do_security)
who_print_security(obj_name, obj_type, obj_id);
if (do_groups)
who_print_groups(obj_name, obj_type, obj_id);
if (do_rights)
who_print_rights();
fprintf(stdout, "\n\n");
return(0);
}