/* revoke.c - Novell REVOKE-like DOS utility */ #include "net.h" #include "c32ncp.h" #include "trustee.h" #ifndef _A_NORMAL #define _A_NORMAL 0x00 #endif static int revoke_last_rc = 0; static void revoke_usage_error(void) { fprintf(stdout, "Command line arguments violate grammar defined for REVOKE.\n\n"); } static void revoke_usage(void) { fprintf(stdout, "Usage: REVOKE rightslist* [FOR path] FROM [USER|GROUP] name [options]\n"); fprintf(stdout, "Options: /SubDirectories | /Files\n\n"); fprintf(stdout, "286 Rights:\t\t386 Rights:\n"); fprintf(stdout, "---------------\t\t--------------------\n"); fprintf(stdout, "ALL = All\t\tALL = All\n"); fprintf(stdout, "R = Read\t\tS = Supervisor\n"); fprintf(stdout, "W = Write\t\tR = Read\n"); fprintf(stdout, "O = Open\t\tW = Write\n"); fprintf(stdout, "C = Create\t\tC = Create\n"); fprintf(stdout, "D = Delete\t\tE = Erase\n"); fprintf(stdout, "P = Parental\t\tM = Modify\n"); fprintf(stdout, "S = Search\t\tF = File Scan\n"); fprintf(stdout, "M = Modify\t\tA = Access Control\n"); fprintf(stdout, "\n* Use abbreviations listed above, separated by spaces.\n"); } static int revoke_one(char *path, uint16 dhandle, uint32 object_id, uint16 revoke_mask, int forced_is_file) { uint16 old_rights = 0; uint16 new_rights; int is_dir; int rc; is_dir = forced_is_file ? 0 : trustee_path_is_dir(path); rc = c32_ncp87_find_trustee_rights(path, dhandle, object_id, &old_rights, NULL, NULL, NULL); revoke_last_rc = rc; if (rc) { if (rc == 0xff) fprintf(stdout, "No trustee for the specified %s.\n", is_dir ? "directory" : "file"); else fprintf(stdout, "Error scanning trustee list.\n"); return(1); } new_rights = (uint16)(old_rights & ~revoke_mask); if (new_rights == 0) { rc = c32_ncp87_delete_trustee_rights(path, dhandle, object_id, NULL, NULL, NULL); revoke_last_rc = rc; if (rc) { fprintf(stdout, "Error deleting trustee.\n"); return(1); } } else { rc = c32_ncp87_add_trustee_rights(path, dhandle, object_id, new_rights, 0xffff, NULL, NULL, NULL); revoke_last_rc = rc; if (rc) { fprintf(stdout, "Fatal error revoking access rights.\n"); return(1); } } { char header[300]; char bracket[10]; trustee_header_path(header, path, sizeof(header)); trustee_rights_bracket(new_rights, bracket); fprintf(stdout, "%s\n\n", header); fprintf(stdout, "Trustee's access rights set to [%s]\n", bracket); } return(0); } static int revoke_subdirs(char *path, uint16 dhandle, uint32 object_id, uint16 revoke_mask, int *count) { struct find_t ff; char pattern[260]; char child[260]; int rc = 0; if (revoke_one(path, dhandle, object_id, revoke_mask, 0) == 0) (*count)++; else rc = 1; trustee_join_path(pattern, path, "*.*", sizeof(pattern)); if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) { do { if ((ff.attrib & _A_SUBDIR) && !trustee_is_dot_dir(ff.name)) { trustee_join_path(child, path, ff.name, sizeof(child)); if (revoke_subdirs(child, dhandle, object_id, revoke_mask, count)) rc = 1; } } while (_dos_findnext(&ff) == 0); } return(rc); } static int revoke_files(char *path, uint16 dhandle, uint32 object_id, uint16 revoke_mask, int *count) { struct find_t ff; char dir[260]; char pat[80]; char spec[260]; char target[260]; int rc = 0; if (trustee_path_is_dir(path)) { strmaxcpy(dir, path, sizeof(dir) - 1); strmaxcpy(pat, "*.*", sizeof(pat) - 1); } else if (trustee_path_has_wildcards(path)) { trustee_parent_pattern(dir, pat, path, sizeof(dir), sizeof(pat)); } else { if (revoke_one(path, dhandle, object_id, revoke_mask, 1) == 0) (*count)++; else rc = 1; return(rc); } trustee_join_path(spec, dir, pat, sizeof(spec)); if (_dos_findfirst(spec, _A_NORMAL | _A_HIDDEN | _A_SYSTEM | _A_ARCH, &ff) == 0) { do { if (!(ff.attrib & _A_SUBDIR)) { trustee_join_path(target, dir, ff.name, sizeof(target)); if (revoke_one(target, dhandle, object_id, revoke_mask, 1) == 0) (*count)++; else rc = 1; } } while (_dos_findnext(&ff) == 0); } return(rc); } int func_revoke(int argc, char *argv[], int mode) { uint16 rights = 0; char *path = "."; char *objname = NULL; char objprint[48]; uint16 objtype = TRUSTEE_BINDERY_USER; int objtype_given = 0; uint8 connid = 0; uint8 dhandle = 0; uint32 object_id; int use_subdirs = 0; int use_files = 0; int count = 0; int i = 1; int have_rights = 0; int rc; (void)mode; if (argc < 2 || trustee_is_help(argv[1])) { if (argc < 2) revoke_usage_error(); revoke_usage(); return(argc < 2 ? 1 : 0); } while (i < argc) { if (trustee_same(argv[i], "FOR") || trustee_same(argv[i], "FROM")) break; if (trustee_is_option(argv[i])) break; if (trustee_parse_right_word(argv[i], &rights)) { fprintf(stdout, "Invalid right specified.\n"); revoke_usage(); return(1); } have_rights = 1; i++; } if (!have_rights || i >= argc) { revoke_usage_error(); revoke_usage(); return(1); } if (trustee_same(argv[i], "FOR")) { i++; if (i >= argc) { revoke_usage_error(); revoke_usage(); return(1); } path = argv[i++]; } if (i >= argc || !trustee_same(argv[i], "FROM")) { revoke_usage_error(); revoke_usage(); return(1); } i++; if (i < argc && trustee_same(argv[i], "USER")) { objtype = TRUSTEE_BINDERY_USER; objtype_given = 1; i++; } else if (i < argc && trustee_same(argv[i], "GROUP")) { objtype = TRUSTEE_BINDERY_GROUP; objtype_given = 1; i++; } if (i >= argc) { revoke_usage_error(); revoke_usage(); return(1); } objname = argv[i++]; while (i < argc) { if (!trustee_is_option(argv[i])) { revoke_usage_error(); revoke_usage(); return(1); } if (trustee_is_files_option(argv[i])) { use_files = 1; i++; continue; } if (trustee_is_subdirs_option(argv[i])) { use_subdirs = 1; i++; continue; } revoke_usage_error(); revoke_usage(); return(1); } if (use_files && use_subdirs) { fprintf(stdout, "Revoke cannot do both directories and files in a single pass.\n"); return(1); } if (trustee_current_dhandle(&connid, &dhandle)) { fprintf(stdout, "Error: Drive not mapped to Network.\n"); return(1); } object_id = trustee_lookup_object(objname, &objtype, objtype_given); if (!object_id) { if (objtype_given && objtype == TRUSTEE_BINDERY_GROUP) fprintf(stdout, "Group \"%s\" not found.\n", objname); else if (objtype_given) fprintf(stdout, "User \"%s\" not found.\n", objname); else fprintf(stdout, "User or group \"%s\" not found.\n", objname); return(1); } trustee_upcopy(objprint, objname, sizeof(objprint)); if (use_subdirs) rc = revoke_subdirs(path, (uint16)dhandle, object_id, rights, &count); else if (use_files) rc = revoke_files(path, (uint16)dhandle, object_id, rights, &count); else { rc = revoke_one(path, (uint16)dhandle, object_id, rights, 0); if (!rc) count = 1; } if (use_subdirs || (!use_files && !rc)) fprintf(stdout, "Rights for %d directories were changed for %s.\n", count, objprint); else if (use_files) fprintf(stdout, "Rights for %d files were changed for %s.\n", count, objprint); return(rc ? (revoke_last_rc ? revoke_last_rc : 1) : 0); }