/* * 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 . */ /* * 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 (!ncp87_1d_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); }