Implement REVOKE and REMOVE for the Client32 DOS utilities. REVOKE now supports Novell-style syntax: REVOKE rightslist* [FOR path] FROM [USER|GROUP] name [options] and removes rights from explicit trustee assignments. It scans the trustee list first, updates the trustee rights mask, and deletes the trustee entry when no rights remain. REMOVE now supports Novell-style syntax: REMOVE [USER | GROUP] name [FROM path] [option] and deletes explicit trustee assignments for users or groups. Both tools support USER/GROUP lookup, /FILES, /SUBDIRS, /SUBDIRECTORIES, wildcard file targets, recursive directory handling, Novell-style help text and summary output. Missing trustee entries are reported with Novell-style "No trustee for the specified ..." messages. Add shared trustee helpers and Client32 NCP87 trustee scan/delete support. Also adjust GRANT ALL so it matches Novell behavior by not granting Supervisor implicitly; Supervisor must be granted explicitly.
342 lines
7.1 KiB
C
342 lines
7.1 KiB
C
/* trustee.c - shared helpers for GRANT/REVOKE/REMOVE style tools */
|
|
|
|
#include "net.h"
|
|
#include "trustee.h"
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#ifndef S_IFDIR
|
|
#define S_IFDIR 0040000
|
|
#endif
|
|
|
|
int trustee_same(char *a, char *b)
|
|
{
|
|
while (*a || *b) {
|
|
int ca = *a++;
|
|
int cb = *b++;
|
|
if (ca >= 'a' && ca <= 'z') ca -= 32;
|
|
if (cb >= 'a' && cb <= 'z') cb -= 32;
|
|
if (ca != cb) return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
int trustee_is_help(char *s)
|
|
{
|
|
if (!s) return(0);
|
|
return(trustee_same(s, "/?") || trustee_same(s, "-?") || trustee_same(s, "?"));
|
|
}
|
|
|
|
int trustee_is_option(char *s)
|
|
{
|
|
if (!s) return(0);
|
|
return(s[0] == '/' || s[0] == '-');
|
|
}
|
|
|
|
int trustee_is_subdirs_option(char *s)
|
|
{
|
|
if (!s) return(0);
|
|
return(trustee_same(s, "/SUBDIRS") || trustee_same(s, "-SUBDIRS") ||
|
|
trustee_same(s, "/SUBDIRECTORIES") || trustee_same(s, "-SUBDIRECTORIES") ||
|
|
trustee_same(s, "/S") || trustee_same(s, "-S"));
|
|
}
|
|
|
|
int trustee_is_files_option(char *s)
|
|
{
|
|
if (!s) return(0);
|
|
return(trustee_same(s, "/FILES") || trustee_same(s, "-FILES") ||
|
|
trustee_same(s, "/F") || trustee_same(s, "-F"));
|
|
}
|
|
|
|
static int trustee_get_current_drive(void)
|
|
{
|
|
REGS regs;
|
|
|
|
regs.h.ah = 0x19;
|
|
int86(0x21, ®s, ®s);
|
|
return((int)regs.h.al);
|
|
}
|
|
|
|
int trustee_current_dhandle(uint8 *connid, uint8 *dhandle)
|
|
{
|
|
uint8 flags = 0;
|
|
int drive = trustee_get_current_drive();
|
|
|
|
if (get_drive_info((uint8)drive, connid, dhandle, &flags))
|
|
return(-1);
|
|
|
|
if (!*connid || (flags & 0x80))
|
|
return(-1);
|
|
|
|
return(0);
|
|
}
|
|
|
|
static int trustee_current_prefix(char *out, int max)
|
|
{
|
|
uint8 connid = 0;
|
|
uint8 dhandle = 0;
|
|
uint8 flags = 0;
|
|
int drive;
|
|
char server[52];
|
|
char dpath[260];
|
|
char volume[32];
|
|
char *p;
|
|
int i = 0;
|
|
|
|
if (!out || max < 8)
|
|
return(-1);
|
|
|
|
out[0] = '\0';
|
|
|
|
drive = trustee_get_current_drive();
|
|
if (get_drive_info((uint8)drive, &connid, &dhandle, &flags))
|
|
return(-1);
|
|
|
|
if (!connid || (flags & 0x80))
|
|
return(-1);
|
|
|
|
server[0] = '\0';
|
|
if (get_fs_name(connid, server))
|
|
server[0] = '\0';
|
|
|
|
dpath[0] = '\0';
|
|
if (get_dir_path(dhandle, dpath) || !dpath[0])
|
|
return(-1);
|
|
|
|
p = strchr(dpath, ':');
|
|
if (!p)
|
|
return(-1);
|
|
|
|
while (dpath + i < p && i < (int)sizeof(volume) - 1) {
|
|
volume[i] = dpath[i];
|
|
i++;
|
|
}
|
|
volume[i] = '\0';
|
|
|
|
if (!volume[0])
|
|
return(-1);
|
|
|
|
if (server[0])
|
|
sprintf(out, "%s/%s:", server, volume);
|
|
else
|
|
sprintf(out, "%s:", volume);
|
|
|
|
return(0);
|
|
}
|
|
|
|
void trustee_upcopy(char *dst, char *src, int max)
|
|
{
|
|
int i = 0;
|
|
|
|
if (!src) src = "";
|
|
|
|
while (*src && i < max - 1) {
|
|
char c = *src++;
|
|
if (c == '/') c = '\\';
|
|
if (c >= 'a' && c <= 'z') c -= 32;
|
|
dst[i++] = c;
|
|
}
|
|
dst[i] = 0;
|
|
}
|
|
|
|
void trustee_basename(char *dst, char *src, int max)
|
|
{
|
|
char up[260];
|
|
char *p;
|
|
|
|
trustee_upcopy(up, src, sizeof(up));
|
|
p = strrchr(up, '\\');
|
|
if (!p) p = strrchr(up, ':');
|
|
|
|
if (p)
|
|
strmaxcpy(dst, p + 1, max - 1);
|
|
else
|
|
strmaxcpy(dst, up, max - 1);
|
|
}
|
|
|
|
void trustee_header_path(char *out, char *path, int max)
|
|
{
|
|
char prefix[90];
|
|
char up[260];
|
|
|
|
if (trustee_current_prefix(prefix, sizeof(prefix)))
|
|
prefix[0] = '\0';
|
|
|
|
trustee_upcopy(up, path, sizeof(up));
|
|
|
|
strmaxcpy(out, prefix, max - 1);
|
|
if ((int)(strlen(out) + strlen(up)) < max - 1)
|
|
strcat(out, up);
|
|
}
|
|
|
|
void trustee_join_path(char *out, char *base, char *name, int max)
|
|
{
|
|
int len;
|
|
|
|
out[0] = '\0';
|
|
strmaxcpy(out, base, max - 1);
|
|
len = strlen(out);
|
|
|
|
if (len > 0 && out[len - 1] != '\\' && out[len - 1] != '/' &&
|
|
out[len - 1] != ':') {
|
|
if (len < max - 1) {
|
|
out[len++] = '\\';
|
|
out[len] = '\0';
|
|
}
|
|
}
|
|
|
|
if ((int)(strlen(out) + strlen(name)) < max - 1)
|
|
strcat(out, name);
|
|
}
|
|
|
|
int trustee_is_dot_dir(char *name)
|
|
{
|
|
if (!name) return(0);
|
|
if (name[0] == '.' && name[1] == '\0') return(1);
|
|
if (name[0] == '.' && name[1] == '.' && name[2] == '\0') return(1);
|
|
return(0);
|
|
}
|
|
|
|
int trustee_parse_right_word(char *s, uint16 *rights)
|
|
{
|
|
if (trustee_same(s, "ALL")) {
|
|
*rights = TRUSTEE_RIGHT_ALL_386;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "N") || trustee_same(s, "NONE")) {
|
|
*rights = TRUSTEE_RIGHT_ALL_386;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "S") || trustee_same(s, "SUPERVISOR")) {
|
|
*rights |= TRUSTEE_RIGHT_SUPER;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "R") || trustee_same(s, "READ")) {
|
|
*rights |= TRUSTEE_RIGHT_READ;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "W") || trustee_same(s, "WRITE")) {
|
|
*rights |= TRUSTEE_RIGHT_WRITE;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "C") || trustee_same(s, "CREATE")) {
|
|
*rights |= TRUSTEE_RIGHT_CREATE;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "E") || trustee_same(s, "ERASE") ||
|
|
trustee_same(s, "D") || trustee_same(s, "DELETE")) {
|
|
*rights |= TRUSTEE_RIGHT_DELETE;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "M") || trustee_same(s, "MODIFY")) {
|
|
*rights |= TRUSTEE_RIGHT_MODIFY;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "F") || trustee_same(s, "FILESCAN") ||
|
|
trustee_same(s, "FILE") || trustee_same(s, "SCAN")) {
|
|
*rights |= TRUSTEE_RIGHT_SEARCH;
|
|
return(0);
|
|
}
|
|
|
|
if (trustee_same(s, "A") || trustee_same(s, "ACCESS") ||
|
|
trustee_same(s, "CONTROL") || trustee_same(s, "ACCESSCONTROL")) {
|
|
*rights |= TRUSTEE_RIGHT_OWNER;
|
|
return(0);
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
void trustee_rights_bracket(uint16 rights, char *out)
|
|
{
|
|
out[0] = (rights & TRUSTEE_RIGHT_SUPER) ? 'S' : ' ';
|
|
out[1] = (rights & TRUSTEE_RIGHT_READ) ? 'R' : ' ';
|
|
out[2] = (rights & TRUSTEE_RIGHT_WRITE) ? 'W' : ' ';
|
|
out[3] = (rights & TRUSTEE_RIGHT_CREATE) ? 'C' : ' ';
|
|
out[4] = (rights & TRUSTEE_RIGHT_DELETE) ? 'E' : ' ';
|
|
out[5] = (rights & TRUSTEE_RIGHT_MODIFY) ? 'M' : ' ';
|
|
out[6] = (rights & TRUSTEE_RIGHT_SEARCH) ? 'F' : ' ';
|
|
out[7] = (rights & TRUSTEE_RIGHT_OWNER) ? 'A' : ' ';
|
|
out[8] = '\0';
|
|
}
|
|
|
|
uint32 trustee_lookup_object(char *name, uint16 *objtype, int objtype_given)
|
|
{
|
|
uint8 namebuf[48];
|
|
uint32 object_id;
|
|
|
|
strmaxcpy(namebuf, name, sizeof(namebuf) - 1);
|
|
upstr(namebuf);
|
|
|
|
if (objtype_given) {
|
|
return(ncp_17_35(namebuf, *objtype));
|
|
}
|
|
|
|
*objtype = TRUSTEE_BINDERY_USER;
|
|
object_id = ncp_17_35(namebuf, TRUSTEE_BINDERY_USER);
|
|
if (object_id)
|
|
return(object_id);
|
|
|
|
*objtype = TRUSTEE_BINDERY_GROUP;
|
|
object_id = ncp_17_35(namebuf, TRUSTEE_BINDERY_GROUP);
|
|
return(object_id);
|
|
}
|
|
|
|
int trustee_path_is_dir(char *path)
|
|
{
|
|
struct stat st;
|
|
|
|
if (!path || !*path || trustee_same(path, ".") || trustee_same(path, ".\\") ||
|
|
trustee_same(path, "./"))
|
|
return(1);
|
|
|
|
if (stat(path, &st) == 0) {
|
|
if (st.st_mode & S_IFDIR)
|
|
return(1);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
int trustee_path_has_wildcards(char *path)
|
|
{
|
|
if (!path) return(0);
|
|
while (*path) {
|
|
if (*path == '*' || *path == '?') return(1);
|
|
path++;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
void trustee_parent_pattern(char *dir, char *pattern, char *path, int maxdir, int maxpat)
|
|
{
|
|
char tmp[260];
|
|
char *p;
|
|
|
|
trustee_upcopy(tmp, path, sizeof(tmp));
|
|
p = strrchr(tmp, '\\');
|
|
if (!p) p = strrchr(tmp, ':');
|
|
|
|
if (p) {
|
|
char save = *p;
|
|
*p = '\0';
|
|
strmaxcpy(pattern, p + 1, maxpat - 1);
|
|
if (save == ':') {
|
|
*p = ':';
|
|
*(p + 1) = '\0';
|
|
}
|
|
strmaxcpy(dir, tmp, maxdir - 1);
|
|
} else {
|
|
strmaxcpy(dir, ".", maxdir - 1);
|
|
strmaxcpy(pattern, tmp, maxpat - 1);
|
|
}
|
|
}
|