dosutils: implement GRANT trustee management
- add GRANT as a new multi-call DOS utility - implement Client32 NCP87 trustee-add helper - resolve USER and GROUP bindery objects before granting rights - support Novell-style rights lists, including ALL and N - support directory trustee grants - support file trustee grants via /FILES - implement recursive grants via /SUBDIRECTORIES - accept /SUBDIRS as a compatibility alias - format GRANT success output close to Novell GRANT - add GRANT comparison scripts for normal and recursive test cases
This commit is contained in:
@@ -40,6 +40,8 @@ set(MARS_DOSUTILS_NEW_ONLY_TOOLS
|
||||
slist
|
||||
flag
|
||||
flagdir
|
||||
rights
|
||||
grant
|
||||
)
|
||||
|
||||
if(MARS_NWE_BUILD_DOSUTILS)
|
||||
@@ -56,6 +58,7 @@ if(MARS_NWE_BUILD_DOSUTILS)
|
||||
flag.c
|
||||
flagdir.c
|
||||
rights.c
|
||||
grant.c
|
||||
c32ncp.c
|
||||
nwcrypt.c
|
||||
nwdebug.c
|
||||
|
||||
113
c32ncp.c
113
c32ncp.c
@@ -16,6 +16,14 @@ static void c32_put_dword_lh(uint8 *p, uint32 v)
|
||||
p[3] = (uint8)((v >> 24) & 0xff);
|
||||
}
|
||||
|
||||
static void c32_put_dword_hl(uint8 *p, uint32 v)
|
||||
{
|
||||
p[0] = (uint8)((v >> 24) & 0xff);
|
||||
p[1] = (uint8)((v >> 16) & 0xff);
|
||||
p[2] = (uint8)((v >> 8) & 0xff);
|
||||
p[3] = (uint8)(v & 0xff);
|
||||
}
|
||||
|
||||
static uint16 c32_get_word_lh(uint8 *p)
|
||||
{
|
||||
return((uint16)(p[0] | ((uint16)p[1] << 8)));
|
||||
@@ -480,3 +488,108 @@ int c32_ncp87_get_effective_rights(const char *path_name,
|
||||
}
|
||||
|
||||
|
||||
int c32_ncp87_add_trustee_rights(const char *path_name,
|
||||
uint16 dir_handle,
|
||||
uint32 object_id,
|
||||
uint16 rights,
|
||||
uint16 rights_mask,
|
||||
uint16 *actual_out,
|
||||
uint16 *handle_lo_out,
|
||||
uint16 *handle_hi_out)
|
||||
{
|
||||
uint16 handle_lo, handle_hi;
|
||||
uint8 hdr[16];
|
||||
uint8 reqpath[0x180];
|
||||
uint8 rep0[0x20];
|
||||
uint8 rep1[0x20];
|
||||
uint8 rawout[32];
|
||||
uint16 raw_ret_ax, raw_ret_dx;
|
||||
uint16 actual_lo;
|
||||
UI path_struct_len;
|
||||
UI reqpath_len;
|
||||
uint8 *tp;
|
||||
int rc;
|
||||
|
||||
if (actual_out) *actual_out = 0;
|
||||
if (handle_lo_out) *handle_lo_out = 0;
|
||||
if (handle_hi_out) *handle_hi_out = 0;
|
||||
|
||||
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
|
||||
if (rc)
|
||||
return(10 + rc);
|
||||
|
||||
/*
|
||||
* NCP 87 subfunction 10: Add trustee.
|
||||
*
|
||||
* This mirrors ncpfs ncp_ns_trustee_add():
|
||||
* byte 10
|
||||
* byte namespace DOS
|
||||
* byte reserved
|
||||
* word search attributes, little endian
|
||||
* word rights mask, little endian
|
||||
* word object count, little endian
|
||||
* handle/path
|
||||
* trustee array at request offset 16 + 307
|
||||
*
|
||||
* Client32 Raw5 has two request fragments, so the second fragment carries
|
||||
* the handle/path and the padded trustee record.
|
||||
*/
|
||||
memset(hdr, 0, sizeof(hdr));
|
||||
hdr[0] = 10;
|
||||
hdr[1] = 0; /* DOS namespace */
|
||||
hdr[2] = 0; /* reserved */
|
||||
c32_put_word_lh(hdr + 3, 0x8006); /* SA_ALL: files/subdirs + system + hidden */
|
||||
c32_put_word_lh(hdr + 5, rights_mask);
|
||||
c32_put_word_lh(hdr + 7, 1); /* one trustee */
|
||||
|
||||
memset(reqpath, 0, sizeof(reqpath));
|
||||
path_struct_len = c32_build_handle_path_from_dos_path(reqpath,
|
||||
(uint8)dir_handle,
|
||||
0, 0,
|
||||
path_name);
|
||||
|
||||
/*
|
||||
* ncpfs seeks to absolute packet offset 16+307 before writing the
|
||||
* trustee list. The NCP request header is 7 bytes, so inside the NCP
|
||||
* payload the trustee list begins at:
|
||||
*
|
||||
* (16 + 307) - 7 = 316
|
||||
*
|
||||
* Our first Raw5 request fragment is the 9-byte subfunction header,
|
||||
* so the trustee list begins in the second fragment at:
|
||||
*
|
||||
* 316 - 9 = 307
|
||||
*/
|
||||
if (path_struct_len > 307)
|
||||
return(2);
|
||||
|
||||
tp = reqpath + 307;
|
||||
c32_put_dword_hl(tp, object_id); tp += 4;
|
||||
c32_put_word_lh(tp, rights); tp += 2;
|
||||
reqpath_len = (UI)(tp - reqpath);
|
||||
|
||||
memset(rep0, 0, sizeof(rep0));
|
||||
memset(rep1, 0, sizeof(rep1));
|
||||
memset(rawout, 0, sizeof(rawout));
|
||||
|
||||
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
|
||||
hdr, 9,
|
||||
reqpath, reqpath_len,
|
||||
rep0, sizeof(rep0),
|
||||
rep1, sizeof(rep1),
|
||||
rawout);
|
||||
|
||||
raw_ret_ax = c32_get_word_lh(rawout + 14);
|
||||
raw_ret_dx = c32_get_word_lh(rawout + 16);
|
||||
actual_lo = c32_get_word_lh(rawout + 18);
|
||||
|
||||
if (actual_out) *actual_out = actual_lo;
|
||||
if (handle_lo_out) *handle_lo_out = handle_lo;
|
||||
if (handle_hi_out) *handle_hi_out = handle_hi;
|
||||
|
||||
if (raw_ret_ax != 0 || raw_ret_dx != 0)
|
||||
return(20);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
9
c32ncp.h
9
c32ncp.h
@@ -26,4 +26,13 @@ int c32_ncp87_get_effective_rights(const char *path,
|
||||
uint16 *handle_lo_out,
|
||||
uint16 *handle_hi_out);
|
||||
|
||||
int c32_ncp87_add_trustee_rights(const char *path_name,
|
||||
uint16 dir_handle,
|
||||
uint32 object_id,
|
||||
uint16 rights,
|
||||
uint16 rights_mask,
|
||||
uint16 *actual_out,
|
||||
uint16 *handle_lo_out,
|
||||
uint16 *handle_hi_out);
|
||||
|
||||
#endif
|
||||
|
||||
519
grant.c
Normal file
519
grant.c
Normal file
@@ -0,0 +1,519 @@
|
||||
/* grant.c - Novell GRANT-like DOS utility, first Client32 implementation */
|
||||
|
||||
#include "net.h"
|
||||
#include "c32ncp.h"
|
||||
|
||||
#define GRANT_BINDERY_USER 0x0001
|
||||
#define GRANT_BINDERY_GROUP 0x0002
|
||||
|
||||
#define NCP_RIGHT_READ 0x0001
|
||||
#define NCP_RIGHT_WRITE 0x0002
|
||||
#define NCP_RIGHT_OPEN 0x0004
|
||||
#define NCP_RIGHT_CREATE 0x0008
|
||||
#define NCP_RIGHT_DELETE 0x0010
|
||||
#define NCP_RIGHT_OWNER 0x0020
|
||||
#define NCP_RIGHT_SEARCH 0x0040
|
||||
#define NCP_RIGHT_MODIFY 0x0080
|
||||
#define NCP_RIGHT_SUPER 0x0100
|
||||
|
||||
#define NCP_RIGHT_ALL_386 (NCP_RIGHT_SUPER | NCP_RIGHT_READ | \
|
||||
NCP_RIGHT_WRITE | NCP_RIGHT_CREATE | \
|
||||
NCP_RIGHT_DELETE | NCP_RIGHT_MODIFY | \
|
||||
NCP_RIGHT_SEARCH | NCP_RIGHT_OWNER)
|
||||
|
||||
static int grant_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);
|
||||
}
|
||||
|
||||
static int grant_is_help(char *s)
|
||||
{
|
||||
if (!s) return(0);
|
||||
return(grant_same(s, "/?") || grant_same(s, "-?") || grant_same(s, "?"));
|
||||
}
|
||||
|
||||
static void grant_usage_error(void)
|
||||
{
|
||||
fprintf(stdout, "Command line arguments violate grammar defined for GRANT.\n\n");
|
||||
}
|
||||
|
||||
static void grant_usage(void)
|
||||
{
|
||||
fprintf(stdout, "Usage: GRANT rightslist* [FOR path] TO [USER | GROUP] name [options]\n");
|
||||
fprintf(stdout, "Options: /SubDirectories | /Files\n\n");
|
||||
fprintf(stdout, "386 Rights:\n");
|
||||
fprintf(stdout, "--------------------\n");
|
||||
fprintf(stdout, "ALL = All\n");
|
||||
fprintf(stdout, "N = No Rights\n");
|
||||
fprintf(stdout, "S = Supervisor\n");
|
||||
fprintf(stdout, "R = Read\n");
|
||||
fprintf(stdout, "W = Write\n");
|
||||
fprintf(stdout, "C = Create\n");
|
||||
fprintf(stdout, "E = Erase\n");
|
||||
fprintf(stdout, "M = Modify\n");
|
||||
fprintf(stdout, "F = File Scan\n");
|
||||
fprintf(stdout, "A = Access Control\n");
|
||||
}
|
||||
|
||||
static int grant_get_current_drive(void)
|
||||
{
|
||||
REGS regs;
|
||||
|
||||
regs.h.ah = 0x19;
|
||||
int86(0x21, ®s, ®s);
|
||||
return((int)regs.h.al);
|
||||
}
|
||||
|
||||
static int grant_current_dhandle(uint8 *connid, uint8 *dhandle)
|
||||
{
|
||||
uint8 flags = 0;
|
||||
int drive = grant_get_current_drive();
|
||||
|
||||
if (get_drive_info((uint8)drive, connid, dhandle, &flags))
|
||||
return(-1);
|
||||
|
||||
if (!*connid || (flags & 0x80))
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
static int grant_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 = grant_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);
|
||||
}
|
||||
|
||||
static void grant_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;
|
||||
}
|
||||
|
||||
static void grant_basename(char *dst, char *src, int max)
|
||||
{
|
||||
char up[260];
|
||||
char *p;
|
||||
|
||||
grant_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);
|
||||
}
|
||||
|
||||
static void grant_header_path(char *out, char *path, int max)
|
||||
{
|
||||
char prefix[90];
|
||||
char up[260];
|
||||
|
||||
if (grant_current_prefix(prefix, sizeof(prefix)))
|
||||
prefix[0] = '\0';
|
||||
|
||||
grant_upcopy(up, path, sizeof(up));
|
||||
|
||||
strmaxcpy(out, prefix, max - 1);
|
||||
if ((int)(strlen(out) + strlen(up)) < max - 1)
|
||||
strcat(out, up);
|
||||
}
|
||||
|
||||
static void grant_rights_bracket(uint16 rights, char *out)
|
||||
{
|
||||
out[0] = (rights & NCP_RIGHT_SUPER) ? 'S' : ' ';
|
||||
out[1] = (rights & NCP_RIGHT_READ) ? 'R' : ' ';
|
||||
out[2] = (rights & NCP_RIGHT_WRITE) ? 'W' : ' ';
|
||||
out[3] = (rights & NCP_RIGHT_CREATE) ? 'C' : ' ';
|
||||
out[4] = (rights & NCP_RIGHT_DELETE) ? 'E' : ' ';
|
||||
out[5] = (rights & NCP_RIGHT_MODIFY) ? 'M' : ' ';
|
||||
out[6] = (rights & NCP_RIGHT_SEARCH) ? 'F' : ' ';
|
||||
out[7] = (rights & NCP_RIGHT_OWNER) ? 'A' : ' ';
|
||||
out[8] = '\0';
|
||||
}
|
||||
|
||||
|
||||
static void grant_rights_string(uint16 rights, char *out)
|
||||
{
|
||||
char *p = out;
|
||||
|
||||
if (rights == 0) {
|
||||
strcpy(out, "N");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rights & NCP_RIGHT_ALL_386) == NCP_RIGHT_ALL_386) {
|
||||
strcpy(out, "ALL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rights & NCP_RIGHT_SUPER) *p++ = 'S';
|
||||
if (rights & NCP_RIGHT_READ) *p++ = 'R';
|
||||
if (rights & NCP_RIGHT_WRITE) *p++ = 'W';
|
||||
if (rights & NCP_RIGHT_CREATE) *p++ = 'C';
|
||||
if (rights & NCP_RIGHT_DELETE) *p++ = 'E';
|
||||
if (rights & NCP_RIGHT_MODIFY) *p++ = 'M';
|
||||
if (rights & NCP_RIGHT_SEARCH) *p++ = 'F';
|
||||
if (rights & NCP_RIGHT_OWNER) *p++ = 'A';
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
static int grant_add_right_word(char *s, uint16 *rights)
|
||||
{
|
||||
if (grant_same(s, "ALL")) {
|
||||
*rights = NCP_RIGHT_ALL_386;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "N") || grant_same(s, "NONE")) {
|
||||
*rights = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "S") || grant_same(s, "SUPERVISOR")) {
|
||||
*rights |= NCP_RIGHT_SUPER;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "R") || grant_same(s, "READ")) {
|
||||
*rights |= NCP_RIGHT_READ;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "W") || grant_same(s, "WRITE")) {
|
||||
*rights |= NCP_RIGHT_WRITE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "C") || grant_same(s, "CREATE")) {
|
||||
*rights |= NCP_RIGHT_CREATE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "E") || grant_same(s, "ERASE")) {
|
||||
*rights |= NCP_RIGHT_DELETE;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "M") || grant_same(s, "MODIFY")) {
|
||||
*rights |= NCP_RIGHT_MODIFY;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "F") || grant_same(s, "FILESCAN") ||
|
||||
grant_same(s, "FILE") || grant_same(s, "SCAN")) {
|
||||
*rights |= NCP_RIGHT_SEARCH;
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (grant_same(s, "A") || grant_same(s, "ACCESS") ||
|
||||
grant_same(s, "CONTROL") || grant_same(s, "ACCESSCONTROL")) {
|
||||
*rights |= NCP_RIGHT_OWNER;
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static int grant_is_option(char *s)
|
||||
{
|
||||
if (!s) return(0);
|
||||
return(s[0] == '/' || s[0] == '-');
|
||||
}
|
||||
|
||||
|
||||
static int grant_last_rc = 0;
|
||||
|
||||
static int grant_set_one(char *path, uint16 dhandle,
|
||||
uint32 object_id, uint16 rights)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = c32_ncp87_add_trustee_rights(path,
|
||||
dhandle,
|
||||
object_id,
|
||||
rights,
|
||||
0xffff,
|
||||
NULL, NULL, NULL);
|
||||
grant_last_rc = rc;
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static int grant_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);
|
||||
}
|
||||
|
||||
static void grant_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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply the grant to PATH and every directory below it.
|
||||
*
|
||||
* This intentionally walks through the DOS redirector, not through another
|
||||
* NCP search helper, so it works with the same mapped-drive view that the
|
||||
* user passed to GRANT.
|
||||
*/
|
||||
static int grant_set_subdirs(char *path, uint16 dhandle,
|
||||
uint32 object_id, uint16 rights)
|
||||
{
|
||||
struct find_t ff;
|
||||
char pattern[260];
|
||||
char child[260];
|
||||
int rc = 0;
|
||||
|
||||
if (grant_set_one(path, dhandle, object_id, rights))
|
||||
rc = 1;
|
||||
|
||||
grant_join_path(pattern, path, "*.*", sizeof(pattern));
|
||||
|
||||
if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) {
|
||||
do {
|
||||
if ((ff.attrib & _A_SUBDIR) && !grant_is_dot_dir(ff.name)) {
|
||||
grant_join_path(child, path, ff.name, sizeof(child));
|
||||
if (grant_set_subdirs(child, dhandle, object_id, rights))
|
||||
rc = 1;
|
||||
}
|
||||
} while (_dos_findnext(&ff) == 0);
|
||||
}
|
||||
|
||||
return(rc);
|
||||
}
|
||||
|
||||
|
||||
int func_grant(int argc, char *argv[], int mode)
|
||||
{
|
||||
uint16 rights = 0;
|
||||
char *path = ".";
|
||||
char *objname = NULL;
|
||||
uint16 objtype = GRANT_BINDERY_USER;
|
||||
uint8 connid = 0;
|
||||
uint8 dhandle = 0;
|
||||
uint8 namebuf[48];
|
||||
uint32 object_id;
|
||||
int recurse_subdirs = 0;
|
||||
int i = 1;
|
||||
int have_rights = 0;
|
||||
int rc;
|
||||
|
||||
(void)mode;
|
||||
|
||||
if (argc < 2 || grant_is_help(argv[1])) {
|
||||
if (argc < 2)
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(argc < 2 ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* GRANT rightslist* [FOR path] TO [USER|GROUP] name [options]
|
||||
*/
|
||||
while (i < argc) {
|
||||
if (grant_same(argv[i], "FOR") || grant_same(argv[i], "TO"))
|
||||
break;
|
||||
|
||||
if (grant_is_option(argv[i]))
|
||||
break;
|
||||
|
||||
if (grant_add_right_word(argv[i], &rights)) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
have_rights = 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!have_rights || i >= argc) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (grant_same(argv[i], "FOR")) {
|
||||
i++;
|
||||
if (i >= argc) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
path = argv[i++];
|
||||
}
|
||||
|
||||
if (i >= argc || !grant_same(argv[i], "TO")) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
i++;
|
||||
|
||||
if (i < argc && grant_same(argv[i], "USER")) {
|
||||
objtype = GRANT_BINDERY_USER;
|
||||
i++;
|
||||
} else if (i < argc && grant_same(argv[i], "GROUP")) {
|
||||
objtype = GRANT_BINDERY_GROUP;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= argc) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
|
||||
objname = argv[i++];
|
||||
|
||||
while (i < argc) {
|
||||
if (!grant_is_option(argv[i])) {
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* /FILES is harmless because the explicit path is passed to the
|
||||
* NCP87 trustee-add call. /SUBDIRECTORIES recursively applies the
|
||||
* same grant to all subdirectories below the given path.
|
||||
*/
|
||||
if (grant_same(argv[i], "/FILES") || grant_same(argv[i], "-FILES") ||
|
||||
grant_same(argv[i], "/F") || grant_same(argv[i], "-F")) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grant_same(argv[i], "/SUBDIRECTORIES") ||
|
||||
grant_same(argv[i], "-SUBDIRECTORIES") ||
|
||||
grant_same(argv[i], "/S") || grant_same(argv[i], "-S")) {
|
||||
recurse_subdirs = 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
grant_usage_error();
|
||||
grant_usage();
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (grant_current_dhandle(&connid, &dhandle)) {
|
||||
fprintf(stdout, "Specified path not locatable.\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
strmaxcpy(namebuf, objname, sizeof(namebuf) - 1);
|
||||
upstr(namebuf);
|
||||
object_id = ncp_17_35(namebuf, objtype);
|
||||
if (!object_id) {
|
||||
fprintf(stdout, "Object not found.\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
if (recurse_subdirs)
|
||||
rc = grant_set_subdirs(path, (uint16)dhandle, object_id, rights);
|
||||
else
|
||||
rc = grant_set_one(path, (uint16)dhandle, object_id, rights);
|
||||
|
||||
if (rc) {
|
||||
fprintf(stdout, "Could not add trustee rights. rc=%d\n", grant_last_rc);
|
||||
return(grant_last_rc ? grant_last_rc : 1);
|
||||
}
|
||||
|
||||
{
|
||||
char header[300];
|
||||
char base[80];
|
||||
char bracket[10];
|
||||
|
||||
grant_header_path(header, path, sizeof(header));
|
||||
grant_basename(base, path, sizeof(base));
|
||||
grant_rights_bracket(rights, bracket);
|
||||
|
||||
fprintf(stdout, "%s\n", header);
|
||||
fprintf(stdout, "%-29.29sRights set to [%s]\n", base, bracket);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
1
net.c
1
net.c
@@ -36,6 +36,7 @@ static struct s_net_functions {
|
||||
{"LOGOUT", "logout from server", func_logout , 0},
|
||||
{"FLAG", "display or modify file attributes", func_flag , 0},
|
||||
{"FLAGDIR","display or modify directory attributes",func_flagdir, 0},
|
||||
{"GRANT", "grant trustee rights", func_grant , 0},
|
||||
{"RIGHTS", "display effective file/directory rights",func_rights, 0},
|
||||
{"SLIST", "list servers", func_slist , 0},
|
||||
{"PASSWD", "change password", func_passwd , 0},
|
||||
|
||||
1
net.h
1
net.h
@@ -255,6 +255,7 @@ extern int func_capture(int argc, char *argv[], int mode);
|
||||
/* flag.c */
|
||||
extern int func_flag (int argc, char *argv[], int mode);
|
||||
extern int func_flagdir(int argc, char *argv[], int mode);
|
||||
extern int func_grant(int argc, char *argv[], int mode);
|
||||
extern int func_rights (int argc, char *argv[], int mode);
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user