/* 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 /* Novell GRANT ALL assigns all normal trustee rights, not Supervisor. */ #define NCP_RIGHT_ALL_386 (NCP_RIGHT_READ | NCP_RIGHT_WRITE | \ NCP_RIGHT_CREATE | NCP_RIGHT_DELETE | \ NCP_RIGHT_MODIFY | NCP_RIGHT_SEARCH | \ NCP_RIGHT_OWNER) 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 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 (tool_strsame(s, "ALL")) { *rights = NCP_RIGHT_ALL_386; return(0); } if (tool_strsame(s, "N") || tool_strsame(s, "NONE")) { *rights = 0; return(0); } if (tool_strsame(s, "S") || tool_strsame(s, "SUPERVISOR")) { *rights |= NCP_RIGHT_SUPER; return(0); } if (tool_strsame(s, "R") || tool_strsame(s, "READ")) { *rights |= NCP_RIGHT_READ; return(0); } if (tool_strsame(s, "W") || tool_strsame(s, "WRITE")) { *rights |= NCP_RIGHT_WRITE; return(0); } if (tool_strsame(s, "C") || tool_strsame(s, "CREATE")) { *rights |= NCP_RIGHT_CREATE; return(0); } if (tool_strsame(s, "E") || tool_strsame(s, "ERASE")) { *rights |= NCP_RIGHT_DELETE; return(0); } if (tool_strsame(s, "M") || tool_strsame(s, "MODIFY")) { *rights |= NCP_RIGHT_MODIFY; return(0); } if (tool_strsame(s, "F") || tool_strsame(s, "FILESCAN") || tool_strsame(s, "FILE") || tool_strsame(s, "SCAN")) { *rights |= NCP_RIGHT_SEARCH; return(0); } if (tool_strsame(s, "A") || tool_strsame(s, "ACCESS") || tool_strsame(s, "CONTROL") || tool_strsame(s, "ACCESSCONTROL")) { *rights |= NCP_RIGHT_OWNER; return(0); } return(-1); } 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); } /* * 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; tool_join_path(pattern, path, "*.*", sizeof(pattern)); if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) { do { if ((ff.attrib & _A_SUBDIR) && !tool_is_dot_dir(ff.name)) { tool_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 || tool_is_help_arg(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 (tool_strsame(argv[i], "FOR") || tool_strsame(argv[i], "TO")) break; if (tool_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 (tool_strsame(argv[i], "FOR")) { i++; if (i >= argc) { grant_usage_error(); grant_usage(); return(1); } path = argv[i++]; } if (i >= argc || !tool_strsame(argv[i], "TO")) { grant_usage_error(); grant_usage(); return(1); } i++; if (i < argc && tool_strsame(argv[i], "USER")) { objtype = GRANT_BINDERY_USER; i++; } else if (i < argc && tool_strsame(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 (!tool_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 (tool_strsame(argv[i], "/FILES") || tool_strsame(argv[i], "-FILES") || tool_strsame(argv[i], "/F") || tool_strsame(argv[i], "-F")) { i++; continue; } if (tool_strsame(argv[i], "/SUBDIRECTORIES") || tool_strsame(argv[i], "-SUBDIRECTORIES") || tool_strsame(argv[i], "/S") || tool_strsame(argv[i], "-S")) { recurse_subdirs = 1; i++; continue; } grant_usage_error(); grant_usage(); return(1); } if (tool_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]; tool_header_path(header, path, sizeof(header)); tool_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); }