1b22328f9Schristos /* 2b22328f9Schristos * Copyright (C) 2006 The Free Software Foundation, Inc. 3b22328f9Schristos * 4b22328f9Schristos * Portions Copyright (C) 2006, Baris Sahin <sbaris at users.sourceforge.net> 5b22328f9Schristos * <http://cvsacl.sourceforge.net> 6b22328f9Schristos * 7b22328f9Schristos * 8b22328f9Schristos * You may distribute under the terms of the GNU General Public License as 9b22328f9Schristos * specified in the README file that comes with the CVS source distribution. 10b22328f9Schristos * 11b22328f9Schristos * 12b22328f9Schristos * 13b22328f9Schristos * CVS ACCESS CONTROL LIST EXTENSION 14b22328f9Schristos * 15b22328f9Schristos * It provides advanced access control definitions per modules, 16b22328f9Schristos * directories, and files on branch/tag for remote cvs repository 17b22328f9Schristos * connections.Execution of all CVS subcommands can be controlled 18b22328f9Schristos * with eight different permissions. 19b22328f9Schristos * 20b22328f9Schristos * Permission Types: 21b22328f9Schristos * - no permission (n) (1) 22b22328f9Schristos * - all permissions (a) (2) 23b22328f9Schristos * - write permission (w) (3) 24b22328f9Schristos * - tag permission (t) (4) 25b22328f9Schristos * - read permission (r) (5) 26b22328f9Schristos * - add permission (c) (6) 27b22328f9Schristos * - remove permission (d) (7) 28b22328f9Schristos * - permission change (p) (8) 29b22328f9Schristos * 30b22328f9Schristos */ 31b22328f9Schristos #include "cvs.h" 32b22328f9Schristos #include "getline.h" 33b22328f9Schristos #include <grp.h> 34b22328f9Schristos 35b22328f9Schristos static int acl_fileproc (void *callerdat, struct file_info *finfo); 36b22328f9Schristos 37b22328f9Schristos static Dtype acl_dirproc (void *callerdat, const char *dir, const char *repos, 38b22328f9Schristos const char *update_dir, List *entries); 39b22328f9Schristos 40b22328f9Schristos static int acllist_fileproc (void *callerdat, struct file_info *finfo); 41b22328f9Schristos static Dtype acllist_dirproc (void *callerdat, const char *dir, 42b22328f9Schristos const char *repos, const char *update_dir, 43b22328f9Schristos List *entries); 44b22328f9Schristos 45b22328f9Schristos static void acllist_print (char *line, const char *obj); 46b22328f9Schristos 47b22328f9Schristos static int racl_proc (int argc, char **argv, char *xwhere, 48b22328f9Schristos char *mwhere, char *mfile, int shorten, 49b22328f9Schristos int local_specified, char *mname, char *msg); 50b22328f9Schristos 51b22328f9Schristos static FILE *open_accessfile (char *xmode, const char *repos, char **fname); 52b22328f9Schristos static FILE *open_groupfile (char *xmode); 53b22328f9Schristos 54b22328f9Schristos static char *get_perms (const char *xperms); 55b22328f9Schristos static char *make_perms (char *xperms, char *xfounduserpart, char **xerrmsg); 56b22328f9Schristos 57b22328f9Schristos static char *findusername (const char *string1, const char *string2); 58b22328f9Schristos static char *findgroupname (const char *string1, const char *string2); 59b22328f9Schristos static int valid_tag (const char *part_tag, const char *tag); 60b22328f9Schristos static int valid_perm (const char *part_perms, int perm); 61b22328f9Schristos static int write_perms (const char *user, const char *perms, 62b22328f9Schristos const char *founduserpart, int foundline, 63b22328f9Schristos char *otheruserparts, const char *part_type, 64b22328f9Schristos const char *part_object, const char *part_tag, int pos, 65b22328f9Schristos const char *arepos); 66b22328f9Schristos 67b22328f9Schristos static char *cache_repository; 68b22328f9Schristos static int cache_retval; 69b22328f9Schristos static int founddeniedfile; 70b22328f9Schristos static int cache_perm; 71b22328f9Schristos 72b22328f9Schristos static int is_racl; 73b22328f9Schristos static int debug = 0; 74b22328f9Schristos 75b22328f9Schristos int use_cvs_acl = 0; 76b22328f9Schristos char *cvs_acl_default_permissions; 77b22328f9Schristos int use_cvs_groups = 0; 78b22328f9Schristos int use_system_groups = 0; 79b22328f9Schristos int use_separate_acl_file_for_each_dir = 0; 80b22328f9Schristos char *cvs_acl_file_location = NULL; 81b22328f9Schristos char *cvs_groups_file_location = NULL; 82b22328f9Schristos char *cvs_server_run_as = NULL; 83b22328f9Schristos int stop_at_first_permission_denied = 0; 84b22328f9Schristos 85b22328f9Schristos char *tag = NULL; 86b22328f9Schristos 87b22328f9Schristos char *muser; 88b22328f9Schristos char *mperms; 89b22328f9Schristos static int defaultperms; 90b22328f9Schristos 91b22328f9Schristos static char *default_perms_object; 92b22328f9Schristos char *default_part_perms_accessfile; 93b22328f9Schristos int aclconfig_default_used; 94b22328f9Schristos 95b22328f9Schristos int acldir = 0; 96b22328f9Schristos int aclfile = 0; 97b22328f9Schristos int listacl = 0; 98b22328f9Schristos 99b22328f9Schristos int userfound = 0; 100b22328f9Schristos int groupfound = 0; 101b22328f9Schristos 102b22328f9Schristos /* directory depth ... */ 103b22328f9Schristos char *dirs[255]; 104b22328f9Schristos 105b22328f9Schristos static const char *const acl_usage[] = 106b22328f9Schristos { 107b22328f9Schristos "Usage: %s %s [user||group:permissions] [-Rl] [-r tag] [directories...] [files...]\n", 108b22328f9Schristos "\t-R\tProcess directories recursively.\n", 109b22328f9Schristos "\t-r rev\tExisting revision/tag.\n", 110b22328f9Schristos "\t-l\tList defined ACLs.\n", 111b22328f9Schristos "(Specify the --help global option for a list of other help options)\n", 112b22328f9Schristos NULL 113b22328f9Schristos }; 114b22328f9Schristos 115b22328f9Schristos static const char *const racl_usage[] = 116b22328f9Schristos { 117b22328f9Schristos "Usage: %s %s [user||group:permissions] [-Rl] [-r tag] [directories...]" 118b22328f9Schristos " [files...]\n", 119b22328f9Schristos "\t-R\tProcess directories recursively.\n", 120b22328f9Schristos "\t-r rev\tExisting revision/tag.\n", 121b22328f9Schristos "\t-l\tList defined ACLs.\n", 122b22328f9Schristos "(Specify the --help global option for a list of other help options)\n", 123b22328f9Schristos NULL 124b22328f9Schristos }; 125b22328f9Schristos 126b22328f9Schristos 127b22328f9Schristos int 128b22328f9Schristos access_allowed (const char *file, const char *repos, const char *tag, 129b22328f9Schristos int perm, char **mline, int *mpos, int usecache) 130b22328f9Schristos { 131b22328f9Schristos int retval = 0; 132b22328f9Schristos int foundline = 0; 133b22328f9Schristos FILE *accessfp; 134b22328f9Schristos 135b22328f9Schristos int flag = 1; 136b22328f9Schristos 137b22328f9Schristos char *iline; 138b22328f9Schristos char *tempv; 139b22328f9Schristos char *tempc; 140b22328f9Schristos size_t tempsize; 141b22328f9Schristos 142b22328f9Schristos int intcount; 143b22328f9Schristos int accessfilecount; 144b22328f9Schristos int signlevel = -1; 145b22328f9Schristos int dadmin = 0; 146b22328f9Schristos 147b22328f9Schristos const char *repository; 148b22328f9Schristos char *filefullname = NULL; 149b22328f9Schristos userfound = 0; 150b22328f9Schristos groupfound = 0; 151b22328f9Schristos 152b22328f9Schristos if (defaultperms) 153b22328f9Schristos { 154b22328f9Schristos repository = xstrdup ("ALL"); 155b22328f9Schristos } 156b22328f9Schristos else { 157b22328f9Schristos if (strlen(repository = Short_Repository (repos)) == 0) 158b22328f9Schristos { 159b22328f9Schristos repository = xstrdup ("."); 160b22328f9Schristos } 161b22328f9Schristos } 162b22328f9Schristos 163b22328f9Schristos /* cache */ 164b22328f9Schristos if (usecache && cache_repository != NULL && 165b22328f9Schristos strcmp (cache_repository, repository) == 0 && !founddeniedfile 166b22328f9Schristos && perm == cache_perm) 167b22328f9Schristos return (cache_retval); 168b22328f9Schristos else 169b22328f9Schristos { 170b22328f9Schristos free (cache_repository); 171b22328f9Schristos cache_repository = xstrdup (repository); 172b22328f9Schristos cache_perm = perm; 173b22328f9Schristos } 174b22328f9Schristos 175b22328f9Schristos iline = xstrdup(repository); 176b22328f9Schristos 177b22328f9Schristos tempv = strtok(iline, "/\t"); 178b22328f9Schristos tempc = xstrdup(tempv); 179b22328f9Schristos tempsize = ( tempc != NULL ) ? strlen(tempc) : 0; 180b22328f9Schristos 181b22328f9Schristos intcount = 0; 182b22328f9Schristos /* store paths from object to cvsroot */ 183b22328f9Schristos dirs[intcount] = xstrdup(tempc); 184b22328f9Schristos while ((tempv = strtok(NULL, "/\t")) != NULL) 185b22328f9Schristos { 186b22328f9Schristos intcount++; 187b22328f9Schristos 188b22328f9Schristos xrealloc_and_strcat(&tempc, &tempsize, "/"); 189b22328f9Schristos xrealloc_and_strcat(&tempc, &tempsize, tempv); 190b22328f9Schristos 191b22328f9Schristos dirs[intcount] = xstrdup(tempc); 192b22328f9Schristos } 193b22328f9Schristos 194b22328f9Schristos /* free not needed variables here */ 195b22328f9Schristos free (tempv); 196b22328f9Schristos free (tempc); 197b22328f9Schristos free (iline); 198b22328f9Schristos 199b22328f9Schristos /* accessfilecount will used 200b22328f9Schristos * if UseSeparateACLFile keyword is set to yes*/ 201b22328f9Schristos accessfilecount = intcount; 202b22328f9Schristos 203b22328f9Schristos /* if file is not null add it to dirs array */ 204b22328f9Schristos if (file != NULL) 205b22328f9Schristos { 206b22328f9Schristos filefullname = Xasprintf("%s/%s", repository, file); 207b22328f9Schristos intcount++; 208b22328f9Schristos dirs[intcount] = xstrdup(filefullname); 209b22328f9Schristos } 210b22328f9Schristos 211b22328f9Schristos for (accessfilecount; accessfilecount >= 0 && flag; accessfilecount--) 212b22328f9Schristos { 213b22328f9Schristos if (!use_separate_acl_file_for_each_dir) { 214b22328f9Schristos flag = 0; 215b22328f9Schristos accessfp = open_accessfile ("r", repository, NULL); 216b22328f9Schristos } 217b22328f9Schristos else 218b22328f9Schristos { 219b22328f9Schristos flag = 1; 220b22328f9Schristos accessfp = open_accessfile ("r", dirs[accessfilecount], NULL); 221b22328f9Schristos } 222b22328f9Schristos 223b22328f9Schristos if (accessfp != NULL) 224b22328f9Schristos { 225b22328f9Schristos char *line = NULL; 226b22328f9Schristos size_t line_allocated = 0; 227b22328f9Schristos 228b22328f9Schristos char *xline; 229b22328f9Schristos char *part_type = NULL; 230b22328f9Schristos char *part_object = NULL; 231b22328f9Schristos char *part_tag = NULL; 232b22328f9Schristos char *part_perms = NULL; 233b22328f9Schristos 234b22328f9Schristos int x; 235b22328f9Schristos 236b22328f9Schristos while (getline (&line, &line_allocated, accessfp) >= 0) 237b22328f9Schristos { 238b22328f9Schristos 239b22328f9Schristos if (line[0] == '#' || line[0] == '\0' || line[0] == '\n') 240b22328f9Schristos continue; 241b22328f9Schristos 242b22328f9Schristos xline = xstrdup (line); 243b22328f9Schristos part_type = strtok (line, ":\t"); 244b22328f9Schristos part_object = strtok (NULL, ":\t"); 245b22328f9Schristos part_tag = strtok (NULL, ":\t"); 246b22328f9Schristos part_perms = strtok (NULL, ":\t"); 247b22328f9Schristos 248b22328f9Schristos if (part_type == NULL || part_object == NULL || 249b22328f9Schristos part_tag == NULL || part_perms == NULL) 250b22328f9Schristos { 251b22328f9Schristos free (line); 252b22328f9Schristos error(1, 0, "access file is corrupted or has invalid" 253b22328f9Schristos " format"); 254b22328f9Schristos } 255b22328f9Schristos 256b22328f9Schristos if (debug) fprintf (stderr, "type %s object %s tag %s perms" 257b22328f9Schristos "%s\n", part_type, part_object, part_tag, 258b22328f9Schristos part_perms); 259b22328f9Schristos for (x = intcount; x >= signlevel && x != -1; x--) 260b22328f9Schristos { 261b22328f9Schristos if (debug) fprintf (stderr, "dirs[%d] = %s, part_object=" 262b22328f9Schristos "%s\n", x, dirs[x], part_object); 263b22328f9Schristos if (strcmp (dirs[x], part_object) == 0) 264b22328f9Schristos { 265b22328f9Schristos if (debug) fprintf(stderr, "tag %s \n", tag); 266b22328f9Schristos if (valid_tag (part_tag, tag)) 267b22328f9Schristos { 268b22328f9Schristos foundline = 1; 269b22328f9Schristos if (debug) fprintf(stderr, "foundline\n"); 270b22328f9Schristos 271b22328f9Schristos if (listacl || ((acldir || aclfile) && 272b22328f9Schristos x == intcount) && 273b22328f9Schristos strcmp(part_tag, tag) == 0) 274b22328f9Schristos { 275b22328f9Schristos *mline = xstrdup (xline); 276b22328f9Schristos *mpos = ftell (accessfp); 277b22328f9Schristos } 278b22328f9Schristos 279b22328f9Schristos if (debug) fprintf(stderr, "perm %d\n", perm); 280b22328f9Schristos if (valid_perm (part_perms, perm)) 281b22328f9Schristos { 282b22328f9Schristos if (signlevel == x) 283b22328f9Schristos { 284b22328f9Schristos if (strcmp(part_tag, "ALL") != 0 && 285b22328f9Schristos !aclconfig_default_used) 286b22328f9Schristos retval = 1; 287b22328f9Schristos } 288b22328f9Schristos else if (!aclconfig_default_used) 289b22328f9Schristos { 290b22328f9Schristos signlevel = x; 291b22328f9Schristos retval = 1; 292b22328f9Schristos } 293b22328f9Schristos else { 294b22328f9Schristos /* nothing... */ 295b22328f9Schristos } 296b22328f9Schristos } 297b22328f9Schristos else 298b22328f9Schristos { 299b22328f9Schristos if (signlevel == x) 300b22328f9Schristos { 301b22328f9Schristos if (strcmp(part_tag, "ALL") != 0 && 302b22328f9Schristos !aclconfig_default_used) 303b22328f9Schristos retval = 0; 304b22328f9Schristos } 305b22328f9Schristos else if (!aclconfig_default_used) 306b22328f9Schristos { 307b22328f9Schristos signlevel = x; 308b22328f9Schristos retval = 0; 309b22328f9Schristos 310b22328f9Schristos if (strncmp (part_type, "f", 1) == 0) 311b22328f9Schristos founddeniedfile = 1; 312b22328f9Schristos } 313b22328f9Schristos else { 314b22328f9Schristos } 315b22328f9Schristos } 316b22328f9Schristos } 317b22328f9Schristos } 318b22328f9Schristos } 319b22328f9Schristos 320b22328f9Schristos if (debug) fprintf (stderr, "xline tag = %s %d %d\n", xline, 321b22328f9Schristos groupfound, userfound); 322b22328f9Schristos if (strncmp (xline, "d:ALL:", 6) == 0 && 323b22328f9Schristos ((!groupfound && !userfound) || listacl)) 324b22328f9Schristos { 325b22328f9Schristos if (debug) fprintf (stderr, "ALL tag = %s\n", tag); 326b22328f9Schristos /* a default found */ 327b22328f9Schristos if (valid_tag (part_tag, tag) > 0) 328b22328f9Schristos { 329b22328f9Schristos foundline = 1; 330b22328f9Schristos 331b22328f9Schristos default_part_perms_accessfile = xstrdup (part_perms); 332b22328f9Schristos 333b22328f9Schristos if (debug) fprintf (stderr, "valid perm = %d\n", perm); 334b22328f9Schristos if (valid_perm (part_perms, perm)) 335b22328f9Schristos { 336b22328f9Schristos retval = 1; 337b22328f9Schristos if (perm == 8) 338b22328f9Schristos dadmin = 1; 339b22328f9Schristos } 340b22328f9Schristos else 341b22328f9Schristos retval = 0; 342b22328f9Schristos } 343b22328f9Schristos } 344b22328f9Schristos 345b22328f9Schristos } 346b22328f9Schristos 347b22328f9Schristos if (fclose (accessfp) == EOF) 348b22328f9Schristos error (1, errno, "cannot close 'access' file"); 349b22328f9Schristos } 350b22328f9Schristos } 351b22328f9Schristos 352b22328f9Schristos if (!foundline) 353b22328f9Schristos { 354b22328f9Schristos if (debug) fprintf(stderr, "not found line\n"); 355b22328f9Schristos /* DEFAULT */ 356b22328f9Schristos if (valid_perm (NULL, perm)) 357b22328f9Schristos retval = 1; 358b22328f9Schristos else 359b22328f9Schristos retval = 0; 360b22328f9Schristos } 361b22328f9Schristos 362b22328f9Schristos /* acl admin rigths 'p' */ 363b22328f9Schristos if (dadmin) 364b22328f9Schristos { 365b22328f9Schristos retval = dadmin; 366b22328f9Schristos } 367b22328f9Schristos 368b22328f9Schristos cache_retval = retval; 369b22328f9Schristos 370b22328f9Schristos free (filefullname); 371b22328f9Schristos /* free directories array */ 372b22328f9Schristos while (intcount >= 0) 373b22328f9Schristos { 374b22328f9Schristos free (dirs[intcount]); 375b22328f9Schristos intcount--; 376b22328f9Schristos } 377b22328f9Schristos 378b22328f9Schristos return retval; 379b22328f9Schristos } 380b22328f9Schristos 381b22328f9Schristos /* Returns 1 if tag is valid, 0 if not */ 382b22328f9Schristos static int 383b22328f9Schristos valid_tag (const char *part_tag, const char *tag) 384b22328f9Schristos { 385b22328f9Schristos int retval; 386b22328f9Schristos 387b22328f9Schristos if (tag == NULL) 388b22328f9Schristos tag = "HEAD"; 389b22328f9Schristos 390b22328f9Schristos if (strcmp (tag, part_tag) == 0 || strcmp (part_tag, "ALL") == 0) 391b22328f9Schristos retval = 1; 392b22328f9Schristos else 393b22328f9Schristos retval = 0; 394b22328f9Schristos 395b22328f9Schristos return retval; 396b22328f9Schristos } 397b22328f9Schristos 398b22328f9Schristos /* Returns 1 if successful, 0 if not. */ 399b22328f9Schristos static int 400b22328f9Schristos valid_perm (const char *part_perms, int perm) 401b22328f9Schristos { 402b22328f9Schristos char *perms; 403b22328f9Schristos int retval = 0; 404b22328f9Schristos 405b22328f9Schristos perms = get_perms (part_perms); 406b22328f9Schristos 407b22328f9Schristos /* Allow, if nothing found. */ 408b22328f9Schristos if (perms[0] == '\0') 409b22328f9Schristos return (1); 410b22328f9Schristos 411b22328f9Schristos /* no access allowed, exit */ 412b22328f9Schristos if (strstr (perms, "n")) 413b22328f9Schristos retval = 0; 414b22328f9Schristos 415b22328f9Schristos if (strstr (perms, "p")) 416b22328f9Schristos /* admin rights */ 417b22328f9Schristos retval = 1; 418b22328f9Schristos else if (strstr (perms, "a") && perm != 8) 419b22328f9Schristos /* all access allowed, exit */ 420b22328f9Schristos retval = 1; 421b22328f9Schristos else 422b22328f9Schristos switch (perm) 423b22328f9Schristos { 424b22328f9Schristos case 3:/* write permission */ 425b22328f9Schristos if (strstr (perms, "w")) 426b22328f9Schristos retval = 1; 427b22328f9Schristos break; 428b22328f9Schristos case 4:/* tag permission */ 429b22328f9Schristos if (strstr (perms, "t")) 430b22328f9Schristos retval = 1; 431b22328f9Schristos break; 432b22328f9Schristos case 5:/* read permission */ 433b22328f9Schristos if (strstr (perms, "w") || strstr (perms, "t") || 434b22328f9Schristos strstr (perms, "c") || strstr (perms, "d") || 435b22328f9Schristos strstr (perms, "r")) 436b22328f9Schristos retval = 1; 437b22328f9Schristos break; 438b22328f9Schristos case 6:/* create permission */ 439b22328f9Schristos if (strstr (perms, "c")) 440b22328f9Schristos retval = 1; 441b22328f9Schristos break; 442b22328f9Schristos case 7:/* delete permission */ 443b22328f9Schristos if (strstr (perms, "d")) 444b22328f9Schristos retval = 1; 445b22328f9Schristos break; 446b22328f9Schristos case 8:/* permission change */ 447b22328f9Schristos if (strstr (perms, "p")) 448b22328f9Schristos retval = 1; 449b22328f9Schristos break; 450b22328f9Schristos default:/* never reached */ 451b22328f9Schristos retval = 0; 452b22328f9Schristos break; 453b22328f9Schristos } 454b22328f9Schristos 455b22328f9Schristos free (perms); 456b22328f9Schristos 457b22328f9Schristos return (retval); 458b22328f9Schristos } 459b22328f9Schristos 460b22328f9Schristos /* returns permissions found */ 461b22328f9Schristos char * 462b22328f9Schristos get_perms (const char *part_perms) 463b22328f9Schristos { 464b22328f9Schristos char *username; 465b22328f9Schristos char *xperms; 466b22328f9Schristos size_t xperms_len = 1; 467b22328f9Schristos 468b22328f9Schristos FILE *groupfp; 469b22328f9Schristos 470b22328f9Schristos char *founduser = NULL; 471b22328f9Schristos char *foundall = NULL; 472b22328f9Schristos int default_checked = 0; 473b22328f9Schristos 474b22328f9Schristos if (debug) fprintf (stderr, "get_perms %s...", part_perms); 475b22328f9Schristos aclconfig_default_used = 0; 476b22328f9Schristos 477b22328f9Schristos xperms = xmalloc (xperms_len); 478b22328f9Schristos xperms[0] = '\0'; 479b22328f9Schristos 480b22328f9Schristos /* use CVS_Username if set */ 481b22328f9Schristos if (CVS_Username == NULL) 482b22328f9Schristos username = getcaller (); 483b22328f9Schristos else 484b22328f9Schristos username = CVS_Username; 485b22328f9Schristos 486b22328f9Schristos /* no defined acl, no default acl in access file, 487b22328f9Schristos * or no access file at all */ 488b22328f9Schristos if (part_perms == NULL) { 489b22328f9Schristos if (cvs_acl_default_permissions) 490b22328f9Schristos { 491b22328f9Schristos aclconfig_default_used = 1; 492b22328f9Schristos if (debug) fprintf (stderr, "default %s\n", 493b22328f9Schristos cvs_acl_default_permissions); 494b22328f9Schristos return (cvs_acl_default_permissions); 495b22328f9Schristos } 496b22328f9Schristos else { 497b22328f9Schristos if (debug) fprintf (stderr, "early %s\n", xperms); 498b22328f9Schristos return xperms; 499b22328f9Schristos } 500b22328f9Schristos } 501b22328f9Schristos 502b22328f9Schristos check_default: 503b22328f9Schristos founduser = findusername (part_perms, username); 504b22328f9Schristos foundall = strstr (part_perms, "ALL!"); 505b22328f9Schristos 506b22328f9Schristos if (debug) fprintf (stderr, "founduser=%s foundALL=%s\n", 507b22328f9Schristos founduser, foundall); 508b22328f9Schristos if (founduser) 509b22328f9Schristos { 510b22328f9Schristos char *usr; 511b22328f9Schristos char *per; 512b22328f9Schristos 513b22328f9Schristos usr = strtok (founduser, "!\t"); 514b22328f9Schristos per = strtok (NULL, ",\t"); 515b22328f9Schristos 516*cc7958a0Schristos free(xperms); 517b22328f9Schristos xperms = xstrdup (per); 518b22328f9Schristos xperms_len = strlen (xperms); 519b22328f9Schristos 520b22328f9Schristos userfound = 1; 521*cc7958a0Schristos free (founduser); 522b22328f9Schristos } 523b22328f9Schristos else 524b22328f9Schristos { 525b22328f9Schristos if (debug) fprintf (stderr, "usesystemgroups=%d\n", use_system_groups); 526b22328f9Schristos if (use_system_groups) { 527b22328f9Schristos struct group *griter; 528b22328f9Schristos setgrent (); 529b22328f9Schristos while (griter = getgrent ()) 530b22328f9Schristos { 531b22328f9Schristos char **users=griter->gr_mem; 532b22328f9Schristos int index = 0; 533b22328f9Schristos char *userchk = users [index++]; 534b22328f9Schristos while(userchk != NULL) { 535b22328f9Schristos if(strcmp (userchk, username) == 0) 536b22328f9Schristos break; 537b22328f9Schristos userchk = users[index++]; 538b22328f9Schristos } 539b22328f9Schristos if (debug) fprintf (stderr, "usercheck=%s\n", userchk); 540b22328f9Schristos if (userchk != NULL) { 541b22328f9Schristos char *grp; 542b22328f9Schristos if ((grp = findusername (part_perms, griter->gr_name))) 543b22328f9Schristos { 544b22328f9Schristos char *gperm = strtok (grp, "!\t"); 545b22328f9Schristos if (debug) fprintf (stderr, "usercheck=%s, grp=%s\n", 546b22328f9Schristos userchk, grp); 547b22328f9Schristos gperm = strtok (NULL, ",\t"); 548b22328f9Schristos xrealloc_and_strcat (&xperms, &xperms_len, gperm); 549b22328f9Schristos 550b22328f9Schristos groupfound = 1; 551*cc7958a0Schristos free (grp); 552b22328f9Schristos } 553b22328f9Schristos } 554b22328f9Schristos } 555b22328f9Schristos endgrent (); 556b22328f9Schristos } 557b22328f9Schristos else if (use_cvs_groups) { 558b22328f9Schristos groupfp = open_groupfile ("r"); 559b22328f9Schristos if (groupfp != NULL) 560b22328f9Schristos { 561b22328f9Schristos char *line = NULL; 562b22328f9Schristos char *grp; 563b22328f9Schristos char *gperm; 564b22328f9Schristos int read; 565b22328f9Schristos 566b22328f9Schristos size_t line_allocated = 0; 567b22328f9Schristos 568b22328f9Schristos while ((read = getline (&line, &line_allocated, groupfp)) >= 0) 569b22328f9Schristos { 570*cc7958a0Schristos char *user; 571b22328f9Schristos if (line[0] == '#' || line[0] == '\0' || line[0] == '\n') 572b22328f9Schristos continue; 573b22328f9Schristos 574b22328f9Schristos if (line[read - 1] == '\n') 575b22328f9Schristos line[--read] = '\0'; 576b22328f9Schristos 577*cc7958a0Schristos if ((grp = findgroupname (line, username)) && 578*cc7958a0Schristos (user = findusername (part_perms, grp))) 579*cc7958a0Schristos 580b22328f9Schristos { 581*cc7958a0Schristos gperm = strtok (user, "!\t"); 582b22328f9Schristos gperm = strtok (NULL, ",\t"); 583b22328f9Schristos xrealloc_and_strcat (&xperms, &xperms_len, gperm); 584b22328f9Schristos groupfound = 1; 585*cc7958a0Schristos free (grp); 586*cc7958a0Schristos free (user); 587b22328f9Schristos } 588b22328f9Schristos } 589b22328f9Schristos 590b22328f9Schristos free (line); 591b22328f9Schristos 592b22328f9Schristos if (fclose (groupfp) == EOF) 593b22328f9Schristos error (1, errno, "cannot close 'group' file"); 594b22328f9Schristos } 595b22328f9Schristos } 596b22328f9Schristos } 597b22328f9Schristos 598b22328f9Schristos if (foundall) 599b22328f9Schristos { 600b22328f9Schristos char *usr; 601b22328f9Schristos char *per; 602b22328f9Schristos 603b22328f9Schristos usr = strtok (strstr (part_perms, "ALL!"), "!\t"); 604b22328f9Schristos per = strtok (NULL, ",\t"); 605b22328f9Schristos 606b22328f9Schristos if (!default_checked) 607b22328f9Schristos default_perms_object = xstrdup (per); 608b22328f9Schristos 609b22328f9Schristos if (xperms[0] == '\0') 610b22328f9Schristos { 611b22328f9Schristos xperms = xstrdup (per); 612b22328f9Schristos xperms_len = strlen (xperms); 613b22328f9Schristos } 614b22328f9Schristos 615b22328f9Schristos /* You don't free pointers from strtok()! */ 616b22328f9Schristos //free(usr); 617b22328f9Schristos //free(per); 618b22328f9Schristos } 619b22328f9Schristos 620b22328f9Schristos if (xperms[0] == '\0' && !default_checked && default_part_perms_accessfile) 621b22328f9Schristos { 622b22328f9Schristos part_perms = xstrdup (default_part_perms_accessfile); 623b22328f9Schristos default_checked = 1; 624b22328f9Schristos 625b22328f9Schristos goto check_default; 626b22328f9Schristos } 627b22328f9Schristos 628b22328f9Schristos if (xperms[0] != '\0' && strcmp (xperms, "x") == 0) 629b22328f9Schristos { 630b22328f9Schristos if (default_perms_object) 631b22328f9Schristos xperms = xstrdup (default_perms_object); 632b22328f9Schristos else if (default_part_perms_accessfile) 633b22328f9Schristos { 634b22328f9Schristos part_perms = default_part_perms_accessfile; 635b22328f9Schristos default_checked = 1; 636b22328f9Schristos goto check_default; 637b22328f9Schristos } 638b22328f9Schristos else if (cvs_acl_default_permissions) 639b22328f9Schristos { 640b22328f9Schristos aclconfig_default_used = 1; 641b22328f9Schristos xperms = xstrdup (cvs_acl_default_permissions); 642b22328f9Schristos } 643b22328f9Schristos } 644b22328f9Schristos 645b22328f9Schristos if (xperms[0] == '\0' && cvs_acl_default_permissions) 646b22328f9Schristos { 647b22328f9Schristos aclconfig_default_used = 1; 648b22328f9Schristos xperms = xstrdup (cvs_acl_default_permissions); 649b22328f9Schristos } 650b22328f9Schristos 651b22328f9Schristos if (debug) fprintf (stderr, "late %s\n", xperms); 652b22328f9Schristos return xperms; 653b22328f9Schristos } 654b22328f9Schristos 655b22328f9Schristos 656b22328f9Schristos int 657b22328f9Schristos cvsacl (int argc, char **argv) 658b22328f9Schristos { 659b22328f9Schristos char *chdirrepository; 660b22328f9Schristos int c; 661b22328f9Schristos int err = 0; 662b22328f9Schristos int usetag = 0; 663b22328f9Schristos int recursive = 0; 664b22328f9Schristos 665b22328f9Schristos int which; 666b22328f9Schristos char *where; 667b22328f9Schristos 668b22328f9Schristos is_racl = (strcmp (cvs_cmd_name, "racl") == 0); 669b22328f9Schristos 670b22328f9Schristos if (argc == -1) 671b22328f9Schristos usage (is_racl ? racl_usage : acl_usage); 672b22328f9Schristos 673b22328f9Schristos /* parse the args */ 674b22328f9Schristos optind = 0; 675b22328f9Schristos 676b22328f9Schristos while ((c = getopt (argc, argv, "dRr:l")) != -1) 677b22328f9Schristos { 678b22328f9Schristos switch (c) 679b22328f9Schristos { 680b22328f9Schristos case 'd': 681b22328f9Schristos debug++; 682b22328f9Schristos break; 683b22328f9Schristos case 'R': 684b22328f9Schristos recursive = 1; 685b22328f9Schristos break; 686b22328f9Schristos case 'r': // baris 687b22328f9Schristos tag = xstrdup (optarg); 688b22328f9Schristos break; 689b22328f9Schristos case 'l': 690b22328f9Schristos listacl = 1; 691b22328f9Schristos break; 692b22328f9Schristos case '?': 693b22328f9Schristos default: 694b22328f9Schristos usage (is_racl ? racl_usage : acl_usage); 695b22328f9Schristos break; 696b22328f9Schristos } 697b22328f9Schristos } 698b22328f9Schristos 699b22328f9Schristos argc -= optind; 700b22328f9Schristos argv += optind; 701b22328f9Schristos 702b22328f9Schristos if (argc < (is_racl ? 1 : 1)) 703b22328f9Schristos usage (is_racl ? racl_usage : acl_usage); 704b22328f9Schristos if (listacl) { 705b22328f9Schristos if (strstr (argv[0], ":")) 706b22328f9Schristos usage (is_racl ? racl_usage : acl_usage); 707b22328f9Schristos } else { 708b22328f9Schristos if (!strstr (argv[0], ":")) 709b22328f9Schristos usage (is_racl ? racl_usage : acl_usage); 710b22328f9Schristos } 711b22328f9Schristos 712b22328f9Schristos 713b22328f9Schristos #ifdef CLIENT_SUPPORT 714b22328f9Schristos 715b22328f9Schristos if (current_parsed_root->isremote) 716b22328f9Schristos { 717b22328f9Schristos start_server (); 718b22328f9Schristos ign_setup (); 719b22328f9Schristos 720b22328f9Schristos if(recursive) 721b22328f9Schristos send_arg ("-R"); 722b22328f9Schristos 723b22328f9Schristos if (listacl) 724b22328f9Schristos send_arg ("-l"); 725b22328f9Schristos 726b22328f9Schristos if(tag) 727b22328f9Schristos { 728b22328f9Schristos option_with_arg ("-r", tag); 729b22328f9Schristos } 730b22328f9Schristos 731b22328f9Schristos send_arg ("--"); 732b22328f9Schristos 733b22328f9Schristos if (!listacl) 734b22328f9Schristos { 735b22328f9Schristos send_arg (argv[0]); 736b22328f9Schristos 737b22328f9Schristos argc--; 738b22328f9Schristos argv++; 739b22328f9Schristos } 740b22328f9Schristos 741b22328f9Schristos if (is_racl) 742b22328f9Schristos { 743b22328f9Schristos int i; 744b22328f9Schristos for (i = 0; i < argc; ++i) 745b22328f9Schristos send_arg (argv[i]); 746b22328f9Schristos 747b22328f9Schristos send_to_server ("racl\012",0); 748b22328f9Schristos } 749b22328f9Schristos else 750b22328f9Schristos { 751b22328f9Schristos send_files (argc, argv, recursive, 0, SEND_NO_CONTENTS); 752b22328f9Schristos send_file_names (argc, argv, SEND_EXPAND_WILD); 753b22328f9Schristos send_to_server ("acl\012", 0); 754b22328f9Schristos } 755b22328f9Schristos 756b22328f9Schristos return get_responses_and_close (); 757b22328f9Schristos } 758b22328f9Schristos #endif 759b22328f9Schristos 760b22328f9Schristos #ifdef SERVER_SUPPORT 761b22328f9Schristos 762b22328f9Schristos if (!listacl) 763b22328f9Schristos { 764b22328f9Schristos muser = strtok (argv[0], ":\t"); 765b22328f9Schristos mperms = strtok (NULL, ":\t"); 766b22328f9Schristos 767b22328f9Schristos /* if set to 'default' */ 768b22328f9Schristos if ((strlen (mperms) == 7) && (strncmp (mperms, "default", 7) == 0)) 769b22328f9Schristos mperms = xstrdup ("x"); 770b22328f9Schristos 771b22328f9Schristos /* Check that the given permissions are valid. */ 772b22328f9Schristos if (!given_perms_valid (mperms)) 773b22328f9Schristos error (1,0,"Invalid permissions: `%s'", mperms); 774b22328f9Schristos 775b22328f9Schristos argc--; 776b22328f9Schristos argv++; 777b22328f9Schristos } 778b22328f9Schristos 779b22328f9Schristos 780b22328f9Schristos if (!tag) 781b22328f9Schristos tag = xstrdup ("HEAD"); 782b22328f9Schristos 783b22328f9Schristos if (!strcasecmp (argv[0], "ALL")) 784b22328f9Schristos { 785b22328f9Schristos argv[0] = xstrdup ("."); 786b22328f9Schristos defaultperms = 1; 787b22328f9Schristos if (!use_separate_acl_file_for_each_dir) 788b22328f9Schristos { 789b22328f9Schristos recursive = 0; 790b22328f9Schristos } 791b22328f9Schristos 792b22328f9Schristos } 793b22328f9Schristos 794b22328f9Schristos if (is_racl) 795b22328f9Schristos { 796b22328f9Schristos DBM *db; 797b22328f9Schristos int i; 798b22328f9Schristos db = open_module (); 799b22328f9Schristos for (i = 0; i < argc; i++) 800b22328f9Schristos { 801b22328f9Schristos err += do_module (db, argv[i], MISC, "ACL ing: ", 802b22328f9Schristos racl_proc, NULL, 0, !recursive, 0, 803b22328f9Schristos 0, NULL); 804b22328f9Schristos } 805b22328f9Schristos close_module (db); 806b22328f9Schristos } 807b22328f9Schristos else 808b22328f9Schristos { 809b22328f9Schristos err = racl_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, !recursive, 810b22328f9Schristos NULL, NULL); 811b22328f9Schristos } 812b22328f9Schristos 813b22328f9Schristos return err; 814b22328f9Schristos 815b22328f9Schristos #endif 816b22328f9Schristos } 817b22328f9Schristos 818b22328f9Schristos static int 819b22328f9Schristos racl_proc (int argc, char **argv, char *xwhere, char *mwhere, 820b22328f9Schristos char *mfile, int shorten, int local, char *mname, char *msg) 821b22328f9Schristos { 822b22328f9Schristos char *myargv[2]; 823b22328f9Schristos int err = 0; 824b22328f9Schristos int which; 825*cc7958a0Schristos char *repository; 826b22328f9Schristos char *where; 827b22328f9Schristos char *obj; 828b22328f9Schristos size_t objlen = 0; 829b22328f9Schristos 830b22328f9Schristos if (!use_cvs_acl) 831b22328f9Schristos { 832b22328f9Schristos error(1, 0, "CVSACL extension is not enabled, set `UseCVSACL=yes'" 833b22328f9Schristos " in aclconfig file"); 834b22328f9Schristos } 835b22328f9Schristos 836b22328f9Schristos if (is_racl) 837b22328f9Schristos { 838*cc7958a0Schristos char *v; 839b22328f9Schristos repository = Xasprintf ("%s/%s", current_parsed_root->directory, 840b22328f9Schristos argv[0]); 841*cc7958a0Schristos where = xstrdup (argv[0]); 842b22328f9Schristos 843b22328f9Schristos /* if mfile isn't null, we need to set up to do only part of the 844b22328f9Schristos * module */ 845b22328f9Schristos if (mfile != NULL) 846b22328f9Schristos { 847b22328f9Schristos char *cp; 848b22328f9Schristos char *path; 849b22328f9Schristos 850b22328f9Schristos /* if the portion of the module is a path, put the dir part on 851b22328f9Schristos * repos */ 852b22328f9Schristos if ((cp = strrchr (mfile, '/')) != NULL) 853b22328f9Schristos { 854b22328f9Schristos *cp = '\0'; 855*cc7958a0Schristos v = Xasprintf ("%s/%s", repository, mfile); 856*cc7958a0Schristos free (repository); 857*cc7958a0Schristos repository = v; 858*cc7958a0Schristos v = Xasprintf ("%s/%s", where, mfile); 859*cc7958a0Schristos free(where); 860*cc7958a0Schristos where = v; 861b22328f9Schristos mfile = cp + 1; 862b22328f9Schristos } 863b22328f9Schristos 864b22328f9Schristos /* take care of the rest */ 865b22328f9Schristos path = Xasprintf ("%s/%s", repository, mfile); 866b22328f9Schristos if (isdir (path)) 867b22328f9Schristos { 868b22328f9Schristos /* directory means repository gets the dir tacked on */ 869*cc7958a0Schristos free(repository); 870*cc7958a0Schristos repository = path; 871*cc7958a0Schristos v = Xasprintf ("%s/%s", where, mfile); 872*cc7958a0Schristos free(where); 873*cc7958a0Schristos where = v; 874b22328f9Schristos } 875b22328f9Schristos else 876b22328f9Schristos { 877*cc7958a0Schristos free (path); 878b22328f9Schristos myargv[0] = argv[0]; 879b22328f9Schristos myargv[1] = mfile; 880b22328f9Schristos argc = 2; 881b22328f9Schristos argv = myargv; 882b22328f9Schristos } 883b22328f9Schristos } 884b22328f9Schristos 885b22328f9Schristos /* cd to the starting repository */ 886b22328f9Schristos if ( CVS_CHDIR (repository) < 0) 887b22328f9Schristos { 888b22328f9Schristos error (0, errno, "cannot chdir to %s", repository); 889b22328f9Schristos free (repository); 890b22328f9Schristos free (where); 891b22328f9Schristos return 1; 892b22328f9Schristos } 893b22328f9Schristos 894b22328f9Schristos /* End section which is identical to patch_proc. */ 895b22328f9Schristos 896b22328f9Schristos which = W_REPOS | W_ATTIC; 897b22328f9Schristos 898b22328f9Schristos if (argc > 1) 899b22328f9Schristos { 900b22328f9Schristos obj = Xasprintf ("%s/%s", repository, argv[1]); 901b22328f9Schristos } 902b22328f9Schristos else 903b22328f9Schristos { 904b22328f9Schristos obj = xstrdup(repository); 905b22328f9Schristos } 906b22328f9Schristos } 907b22328f9Schristos else 908b22328f9Schristos { 909b22328f9Schristos where = NULL; 910*cc7958a0Schristos repository = NULL; 911b22328f9Schristos which = W_LOCAL | W_REPOS | W_ATTIC; 912b22328f9Schristos 913b22328f9Schristos obj = xstrdup (argv[1]); 914b22328f9Schristos } 915b22328f9Schristos 916b22328f9Schristos if (isdir (obj)) 917b22328f9Schristos acldir = 1; 918b22328f9Schristos else if (isfile (obj)) 919b22328f9Schristos aclfile = 1; 920b22328f9Schristos else 921b22328f9Schristos error(1, 0, "no such file or directory"); 922b22328f9Schristos 923b22328f9Schristos free (obj); 924b22328f9Schristos 925b22328f9Schristos if (listacl) 926b22328f9Schristos err = start_recursion (acllist_fileproc, NULL, acllist_dirproc, NULL, 927b22328f9Schristos NULL, argc - 1, argv + 1, local, which, 0, 0, 928*cc7958a0Schristos where, 1, repository); 929b22328f9Schristos else 930b22328f9Schristos err = start_recursion (acl_fileproc, NULL, acl_dirproc, NULL, NULL, 931b22328f9Schristos argc - 1, argv + 1, local, which, 0, 0, 932*cc7958a0Schristos where, 1, repository); 933b22328f9Schristos 934b22328f9Schristos if (repository != NULL) 935b22328f9Schristos free (repository); 936*cc7958a0Schristos if (where != NULL) 937*cc7958a0Schristos free (where); 938b22328f9Schristos 939b22328f9Schristos return err; 940b22328f9Schristos } 941b22328f9Schristos 942b22328f9Schristos 943b22328f9Schristos static int 944b22328f9Schristos acl_fileproc (void *callerdat, struct file_info *finfo) 945b22328f9Schristos { 946b22328f9Schristos char *filefullname; 947b22328f9Schristos char *founduserpart = NULL; 948b22328f9Schristos char *otheruserparts = NULL; 949b22328f9Schristos size_t otherslen = 0; 950b22328f9Schristos 951b22328f9Schristos const char *frepository; 952b22328f9Schristos int foundline = 0; 953b22328f9Schristos 954b22328f9Schristos char *line = NULL; 955b22328f9Schristos size_t line_allocated = 0; 956b22328f9Schristos int linelen; 957b22328f9Schristos 958b22328f9Schristos char *wperms; 959b22328f9Schristos char *errmsg; 960b22328f9Schristos 961b22328f9Schristos int pos; 962b22328f9Schristos 963b22328f9Schristos if (!aclfile) 964b22328f9Schristos return 0; 965b22328f9Schristos 966b22328f9Schristos frepository = Short_Repository (finfo->repository); 967b22328f9Schristos 968b22328f9Schristos filefullname = Xasprintf("%s/%s", frepository, finfo->file); 969b22328f9Schristos 970b22328f9Schristos 971b22328f9Schristos if (!access_allowed (finfo->file, finfo->repository, tag, 8, &line, &pos, 972b22328f9Schristos 0)) 973b22328f9Schristos error (1, 0, "You do not have acl admin rights on '%s'", frepository); 974b22328f9Schristos 975b22328f9Schristos if (line != NULL) 976b22328f9Schristos { 977b22328f9Schristos char *part_type = NULL; 978b22328f9Schristos char *part_object = NULL; 979b22328f9Schristos char *part_tag = NULL; 980b22328f9Schristos char *part_perms = NULL; 981b22328f9Schristos char *userpart; 982b22328f9Schristos 983b22328f9Schristos part_type = strtok (line, ":\t"); 984b22328f9Schristos part_object = strtok (NULL, ":\t"); 985b22328f9Schristos part_tag = strtok (NULL, ":\t"); 986b22328f9Schristos part_perms = strtok (NULL, ":\t"); 987b22328f9Schristos 988b22328f9Schristos foundline = 1; 989b22328f9Schristos userpart = strtok (part_perms, ",\t"); 990b22328f9Schristos 991b22328f9Schristos do 992b22328f9Schristos { 993b22328f9Schristos if (strncmp (userpart, muser, strlen (muser)) == 0) 994b22328f9Schristos founduserpart = xstrdup (userpart); 995b22328f9Schristos else 996b22328f9Schristos { 997b22328f9Schristos if (otheruserparts != NULL) 998b22328f9Schristos { 999b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, ","); 1000b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, userpart); 1001b22328f9Schristos } 1002b22328f9Schristos else 1003b22328f9Schristos { 1004b22328f9Schristos otheruserparts = xstrdup (userpart); 1005b22328f9Schristos otherslen = strlen (otheruserparts); 1006b22328f9Schristos } 1007b22328f9Schristos } 1008b22328f9Schristos } while ((userpart = strtok (NULL, ",\t")) != NULL); 1009b22328f9Schristos 1010b22328f9Schristos free (userpart); 1011b22328f9Schristos } 1012b22328f9Schristos 1013b22328f9Schristos wperms = make_perms (mperms, founduserpart, &errmsg); 1014b22328f9Schristos if (wperms == NULL) 1015b22328f9Schristos { 1016b22328f9Schristos if (errmsg) 1017b22328f9Schristos error (0, 0, "`%s' %s", filefullname, errmsg); 1018b22328f9Schristos } 1019b22328f9Schristos else 1020b22328f9Schristos { 1021b22328f9Schristos cvs_output ("X ", 0); 1022b22328f9Schristos cvs_output (filefullname, 0); 1023b22328f9Schristos cvs_output ("\n", 0); 1024b22328f9Schristos 1025b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline, 1026b22328f9Schristos otheruserparts, "f", filefullname, tag, pos, 1027b22328f9Schristos Short_Repository(finfo->repository)); 1028b22328f9Schristos } 1029b22328f9Schristos 1030b22328f9Schristos free (line); 1031b22328f9Schristos free (founduserpart); 1032b22328f9Schristos free (otheruserparts); 1033b22328f9Schristos free (wperms); 1034b22328f9Schristos free (filefullname); 1035b22328f9Schristos 1036b22328f9Schristos return 0; 1037b22328f9Schristos } 1038b22328f9Schristos 1039b22328f9Schristos static Dtype 1040b22328f9Schristos acl_dirproc (void *callerdat, const char *dir, const char *repos, 1041b22328f9Schristos const char *update_dir, List *entries) 1042b22328f9Schristos { 1043b22328f9Schristos const char *drepository; 1044b22328f9Schristos char *founduserpart = NULL; 1045b22328f9Schristos char *otheruserparts = NULL; 1046b22328f9Schristos size_t otherslen = 0; 1047b22328f9Schristos int foundline = 0; 1048b22328f9Schristos 1049b22328f9Schristos char *line = NULL; 1050b22328f9Schristos size_t line_allocated = 0; 1051b22328f9Schristos int linelen; 1052b22328f9Schristos 1053b22328f9Schristos int pos; 1054b22328f9Schristos 1055b22328f9Schristos char *wperms; 1056b22328f9Schristos char *errmsg; 1057b22328f9Schristos 1058b22328f9Schristos if (!acldir) 1059b22328f9Schristos return 0; 1060b22328f9Schristos 1061b22328f9Schristos if (repos[0] == '\0') 1062b22328f9Schristos repos = Name_Repository (dir, NULL); 1063b22328f9Schristos 1064b22328f9Schristos if (!access_allowed (NULL, repos, tag, 8, &line, &pos, 0)) 1065b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'", 1066b22328f9Schristos Short_Repository (repos)); 1067b22328f9Schristos 1068b22328f9Schristos drepository = Short_Repository (repos); 1069b22328f9Schristos 1070b22328f9Schristos if (line != NULL) 1071b22328f9Schristos { 1072b22328f9Schristos char *part_type = NULL; 1073b22328f9Schristos char *part_object = NULL; 1074b22328f9Schristos char *part_tag = NULL; 1075b22328f9Schristos char *part_perms = NULL; 1076b22328f9Schristos char *userpart; 1077b22328f9Schristos 1078b22328f9Schristos part_type = strtok (line, ":\t"); 1079b22328f9Schristos part_object = strtok (NULL, ":\t"); 1080b22328f9Schristos part_tag = strtok (NULL, ":\t"); 1081b22328f9Schristos part_perms = strtok (NULL, ":\t"); 1082b22328f9Schristos 1083b22328f9Schristos foundline = 1; 1084b22328f9Schristos userpart = strtok (part_perms, ",\t"); 1085b22328f9Schristos 1086b22328f9Schristos do 1087b22328f9Schristos { 1088b22328f9Schristos if (strncmp (userpart, muser, strlen (muser)) == 0) 1089b22328f9Schristos founduserpart = xstrdup (userpart); 1090b22328f9Schristos else 1091b22328f9Schristos { 1092b22328f9Schristos if (otheruserparts != NULL) 1093b22328f9Schristos { 1094b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, ","); 1095b22328f9Schristos xrealloc_and_strcat (&otheruserparts, &otherslen, userpart); 1096b22328f9Schristos } 1097b22328f9Schristos else 1098b22328f9Schristos { 1099b22328f9Schristos otheruserparts = xstrdup (userpart); 1100b22328f9Schristos otherslen = strlen (otheruserparts); 1101b22328f9Schristos } 1102b22328f9Schristos } 1103b22328f9Schristos } while ((userpart = strtok (NULL, ",\t")) != NULL); 1104b22328f9Schristos } 1105b22328f9Schristos 1106b22328f9Schristos wperms = make_perms (mperms, founduserpart, &errmsg); 1107b22328f9Schristos if (wperms == NULL) 1108b22328f9Schristos { 1109b22328f9Schristos if (errmsg) 1110b22328f9Schristos error (0, 0, "`%s' %s", drepository, errmsg); 1111b22328f9Schristos } 1112b22328f9Schristos else 1113b22328f9Schristos { 1114b22328f9Schristos if (defaultperms) 1115b22328f9Schristos { 1116b22328f9Schristos cvs_output ("X ", 0); 1117b22328f9Schristos cvs_output ("ALL", 0); 1118b22328f9Schristos cvs_output ("\n", 0); 1119b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline, 1120b22328f9Schristos otheruserparts, "d", "ALL", tag, pos, drepository); 1121b22328f9Schristos 1122b22328f9Schristos } 1123b22328f9Schristos else 1124b22328f9Schristos { 1125b22328f9Schristos cvs_output ("X ", 0); 1126b22328f9Schristos cvs_output (drepository, 0); 1127b22328f9Schristos cvs_output ("\n", 0); 1128b22328f9Schristos write_perms (muser, wperms, founduserpart, foundline, 1129b22328f9Schristos otheruserparts, "d", drepository, tag, pos, 1130b22328f9Schristos drepository); 1131b22328f9Schristos } 1132b22328f9Schristos } 1133b22328f9Schristos 1134b22328f9Schristos free (line); 1135b22328f9Schristos free (founduserpart); 1136b22328f9Schristos free (otheruserparts); 1137b22328f9Schristos free (wperms); 1138b22328f9Schristos 1139b22328f9Schristos return 0; 1140b22328f9Schristos } 1141b22328f9Schristos 1142b22328f9Schristos /* Open CVSROOT/access or defined CVSACLFileLocation file 1143b22328f9Schristos * Open access file In each directory if UseSeparateACLFileForEachDir=yes 1144b22328f9Schristos * returns file pointer to access file or NULL if access file not found */ 1145b22328f9Schristos FILE * 1146b22328f9Schristos open_accessfile (char *fmode, const char *adir, char **fname) 1147b22328f9Schristos { 1148b22328f9Schristos char *accessfile = NULL; 1149b22328f9Schristos FILE *accessfp; 1150b22328f9Schristos 1151b22328f9Schristos if (!use_separate_acl_file_for_each_dir) 1152b22328f9Schristos { 1153b22328f9Schristos if (cvs_acl_file_location == NULL) 1154b22328f9Schristos { 1155b22328f9Schristos accessfile = Xasprintf("%s/%s/%s", current_parsed_root->directory, 1156b22328f9Schristos CVSROOTADM, CVSROOTADM_ACCESS); 1157b22328f9Schristos } 1158b22328f9Schristos else 1159b22328f9Schristos { 1160b22328f9Schristos accessfile = xstrdup(cvs_acl_file_location); 1161b22328f9Schristos } 1162b22328f9Schristos } 1163b22328f9Schristos else 1164b22328f9Schristos { 1165b22328f9Schristos size_t accessfilelen = 0; 1166b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, 1167b22328f9Schristos current_parsed_root->directory); 1168b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, "/"); 1169b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, adir); 1170b22328f9Schristos xrealloc_and_strcat (&accessfile, &accessfilelen, "/access"); 1171b22328f9Schristos } 1172b22328f9Schristos 1173b22328f9Schristos accessfp = CVS_FOPEN (accessfile, fmode); 1174b22328f9Schristos 1175b22328f9Schristos if (fname != NULL) 1176b22328f9Schristos *fname = xstrdup (accessfile); 1177b22328f9Schristos 1178b22328f9Schristos free (accessfile); 1179b22328f9Schristos 1180b22328f9Schristos return accessfp; 1181b22328f9Schristos } 1182b22328f9Schristos 1183b22328f9Schristos /* Open /etc/group file if UseSystemGroups=yes in config file 1184b22328f9Schristos * Open CVSROOT/group file if UseCVSGroups=yes in config file 1185b22328f9Schristos * Open group file if specified in CVSGroupsFileLocation 1186b22328f9Schristos * returns group file pointer if UseSystemGroups=yes 1187b22328f9Schristos * returns NULL if UseSystemGroups=no or group file not found */ 1188b22328f9Schristos FILE * 1189b22328f9Schristos open_groupfile (char *fmode) 1190b22328f9Schristos { 1191b22328f9Schristos char *groupfile; 1192b22328f9Schristos FILE *groupfp; 1193b22328f9Schristos 1194b22328f9Schristos if (use_cvs_groups) 1195b22328f9Schristos { 1196b22328f9Schristos if (cvs_groups_file_location != NULL) 1197b22328f9Schristos { 1198b22328f9Schristos groupfile = xstrdup (cvs_groups_file_location); 1199b22328f9Schristos } 1200b22328f9Schristos else 1201b22328f9Schristos { 1202b22328f9Schristos groupfile = Xasprintf("%s/%s/%s", current_parsed_root->directory, 1203b22328f9Schristos CVSROOTADM, CVSROOTADM_GROUP); 1204b22328f9Schristos } 1205b22328f9Schristos } 1206b22328f9Schristos else 1207b22328f9Schristos { 1208b22328f9Schristos return NULL; 1209b22328f9Schristos } 1210b22328f9Schristos 1211b22328f9Schristos groupfp = CVS_FOPEN (groupfile, "r"); 1212b22328f9Schristos 1213b22328f9Schristos if (groupfp == NULL) 1214b22328f9Schristos error (0, 0, "cannot open file: %s", groupfile); 1215b22328f9Schristos 1216b22328f9Schristos free (groupfile); 1217b22328f9Schristos 1218b22328f9Schristos return groupfp; 1219b22328f9Schristos } 1220b22328f9Schristos 1221b22328f9Schristos 1222b22328f9Schristos /* Check whether given permissions are valid or not 1223b22328f9Schristos * Returns 1 if permissions are valid 1224b22328f9Schristos * Returns 0 if permissions are NOT valid */ 1225b22328f9Schristos int 1226b22328f9Schristos given_perms_valid (const char *cperms) 1227b22328f9Schristos { 1228b22328f9Schristos int cperms_len; 1229b22328f9Schristos int retval; 1230b22328f9Schristos int index, i; 1231b22328f9Schristos 1232b22328f9Schristos if (cperms[0] == '+' || cperms[0] == '-') 1233b22328f9Schristos index = 1; 1234b22328f9Schristos else 1235b22328f9Schristos index = 0; 1236b22328f9Schristos 1237b22328f9Schristos cperms_len = strlen (cperms); 1238b22328f9Schristos 1239b22328f9Schristos switch (cperms[index]) 1240b22328f9Schristos { 1241b22328f9Schristos case 'x': 1242b22328f9Schristos if ((cperms_len - index) == 1 && cperms_len == 1) 1243b22328f9Schristos retval = 1; 1244b22328f9Schristos else 1245b22328f9Schristos retval = 0; 1246b22328f9Schristos break; 1247b22328f9Schristos case 'n': 1248b22328f9Schristos if ((cperms_len - index) == 1 && cperms_len == 1) 1249b22328f9Schristos retval = 1; 1250b22328f9Schristos else 1251b22328f9Schristos retval = 0; 1252b22328f9Schristos break; 1253b22328f9Schristos case 'p': 1254b22328f9Schristos if ((cperms_len - index) == 1) 1255b22328f9Schristos retval = 1; 1256b22328f9Schristos else 1257b22328f9Schristos retval = 0; 1258b22328f9Schristos break; 1259b22328f9Schristos case 'a': 1260b22328f9Schristos if ((cperms_len - index) == 1) 1261b22328f9Schristos retval = 1; 1262b22328f9Schristos else 1263b22328f9Schristos retval = 0; 1264b22328f9Schristos break; 1265b22328f9Schristos case 'r': 1266b22328f9Schristos if ((cperms_len - index) == 1) 1267b22328f9Schristos retval = 1; 1268b22328f9Schristos else 1269b22328f9Schristos retval = 0; 1270b22328f9Schristos break; 1271b22328f9Schristos case 'w': 1272b22328f9Schristos if ((cperms_len - index) == 1) 1273b22328f9Schristos retval = 1; 1274b22328f9Schristos else 1275b22328f9Schristos for (i = index + 1; i < cperms_len; i++) 1276b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd') 1277b22328f9Schristos retval = 1; 1278b22328f9Schristos else 1279b22328f9Schristos retval = 0; 1280b22328f9Schristos break; 1281b22328f9Schristos case 't': 1282b22328f9Schristos if ((cperms_len - index) == 1) 1283b22328f9Schristos retval = 1; 1284b22328f9Schristos else 1285b22328f9Schristos for (i = index + 1; i < cperms_len; i++) 1286b22328f9Schristos if (cperms[i] == 'w' || cperms[i] == 'c' || cperms[i] == 'd') 1287b22328f9Schristos retval = 1; 1288b22328f9Schristos else 1289b22328f9Schristos retval = 0; 1290b22328f9Schristos break; 1291b22328f9Schristos case 'c': 1292b22328f9Schristos if ((cperms_len - index) == 1) 1293b22328f9Schristos retval = 1; 1294b22328f9Schristos else 1295b22328f9Schristos for (i = index + 1; i < cperms_len; i++) 1296b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'w' || cperms[i] == 'd') 1297b22328f9Schristos retval = 1; 1298b22328f9Schristos else 1299b22328f9Schristos retval = 0; 1300b22328f9Schristos break; 1301b22328f9Schristos case 'd': 1302b22328f9Schristos if ((cperms_len - index) == 1) 1303b22328f9Schristos retval = 1; 1304b22328f9Schristos else 1305b22328f9Schristos for (i = index + 1; i < cperms_len; i++) 1306b22328f9Schristos if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'w') 1307b22328f9Schristos retval = 1; 1308b22328f9Schristos else 1309b22328f9Schristos retval = 0; 1310b22328f9Schristos break; 1311b22328f9Schristos default: 1312b22328f9Schristos retval = 0; 1313b22328f9Schristos break; 1314b22328f9Schristos } 1315b22328f9Schristos 1316b22328f9Schristos return retval; 1317b22328f9Schristos } 1318b22328f9Schristos 1319b22328f9Schristos /* prepare permsissions string to be written to access file 1320b22328f9Schristos * returns permissions or NULL if */ 1321b22328f9Schristos char * 1322b22328f9Schristos make_perms (char *perms, char *founduserpart, char **xerrmsg) 1323b22328f9Schristos { 1324*cc7958a0Schristos char *fperms = NULL; 1325b22328f9Schristos size_t perms_len; 1326b22328f9Schristos size_t fperms_len; 1327b22328f9Schristos 1328b22328f9Schristos int i, j; 1329b22328f9Schristos int err = 0; 1330b22328f9Schristos char *errmsg = NULL; 1331b22328f9Schristos 1332b22328f9Schristos char *retperms; 1333*cc7958a0Schristos size_t retperms_len; 1334b22328f9Schristos 1335b22328f9Schristos perms_len = strlen (perms); 1336b22328f9Schristos if (perms[0] == '+' || perms[0] == '-') 1337b22328f9Schristos { 1338*cc7958a0Schristos retperms = xmalloc (retperms_len); 1339*cc7958a0Schristos retperms[0] = '\0'; 1340*cc7958a0Schristos retperms_len = 1; 1341*cc7958a0Schristos 1342b22328f9Schristos if (founduserpart) 1343b22328f9Schristos { 1344b22328f9Schristos char *tempfperms; 1345b22328f9Schristos size_t tempfperms_len; 1346b22328f9Schristos 1347b22328f9Schristos char *temp; 1348b22328f9Schristos int per = 0; 1349b22328f9Schristos temp = strtok (founduserpart, "!\t"); 1350b22328f9Schristos fperms = strtok (NULL, "!\t"); 1351b22328f9Schristos fperms_len = strlen (fperms); 1352b22328f9Schristos 1353b22328f9Schristos if (strncmp (fperms, "x", 1) == 0) 1354b22328f9Schristos { 1355b22328f9Schristos err = 1; 1356b22328f9Schristos if (perms[0] == '+') 1357b22328f9Schristos *xerrmsg = xstrdup ("cannot add default permission 'x'"); 1358b22328f9Schristos else 1359b22328f9Schristos *xerrmsg = xstrdup ("cannot remove default permission 'x'"); 1360b22328f9Schristos } 1361b22328f9Schristos 1362b22328f9Schristos /* go through perms */ 1363b22328f9Schristos for (i = 1; i < perms_len && !err; i++) 1364b22328f9Schristos { 1365b22328f9Schristos switch (perms[i]) 1366b22328f9Schristos { 1367b22328f9Schristos case 'n': 1368b22328f9Schristos err = 1; 1369b22328f9Schristos break; 1370b22328f9Schristos case 'p': 1371b22328f9Schristos if (perms[0] == '+') 1372b22328f9Schristos fperms = xstrdup ("p"); 1373b22328f9Schristos else if (perms[0] == '-') 1374b22328f9Schristos { 1375b22328f9Schristos fperms_len = 1; 1376b22328f9Schristos fperms = xmalloc (fperms_len); 1377b22328f9Schristos fperms[0] = '\0'; 1378b22328f9Schristos } 1379b22328f9Schristos break; 1380b22328f9Schristos case 'a': 1381b22328f9Schristos for (j = 0; j < fperms_len; j++) 1382b22328f9Schristos { 1383b22328f9Schristos if (fperms[j] == 'p') 1384b22328f9Schristos { 1385b22328f9Schristos err = 1; 1386b22328f9Schristos *xerrmsg = xstrdup ("user have admin rights," 1387b22328f9Schristos " cannot use +/- permissions"); 1388b22328f9Schristos } 1389b22328f9Schristos else if (fperms[j] == 'a' && perms[0] == '+') 1390b22328f9Schristos { 1391b22328f9Schristos err = 1; 1392b22328f9Schristos *xerrmsg = xstrdup ("user already has all ('a')" 1393b22328f9Schristos " permission"); 1394b22328f9Schristos } 1395b22328f9Schristos else if (fperms[j] != 'a' && perms[0] == '-') 1396b22328f9Schristos { 1397b22328f9Schristos err = 1; 1398b22328f9Schristos *xerrmsg = xstrdup ("user does not have all " 1399b22328f9Schristos "('a') permission"); 1400b22328f9Schristos } 1401b22328f9Schristos } 1402b22328f9Schristos if (perms[0] == '+') 1403b22328f9Schristos { 1404b22328f9Schristos fperms = xstrdup ("a"); 1405b22328f9Schristos fperms_len = strlen (fperms); 1406b22328f9Schristos } 1407b22328f9Schristos else if (perms[0] == '-') 1408b22328f9Schristos { 1409b22328f9Schristos fperms_len = 1; 1410b22328f9Schristos fperms = xmalloc (fperms_len); 1411b22328f9Schristos fperms[0] = '\0'; 1412b22328f9Schristos } 1413b22328f9Schristos break; 1414b22328f9Schristos case 'r': 1415b22328f9Schristos for (i = 0; i < fperms_len; i++) 1416b22328f9Schristos { 1417b22328f9Schristos if (fperms[i] == 'n' && perms[0] == '+') 1418b22328f9Schristos { 1419b22328f9Schristos fperms = xstrdup ("r"); 1420b22328f9Schristos fperms_len = strlen (fperms); 1421b22328f9Schristos } 1422b22328f9Schristos else if (fperms[i] == 'r' && perms[0] == '-') 1423b22328f9Schristos { 1424b22328f9Schristos fperms_len = 1; 1425b22328f9Schristos fperms = xmalloc (fperms_len); 1426b22328f9Schristos fperms[0] = '\0'; 1427b22328f9Schristos } 1428b22328f9Schristos else if (perms[0] == '-') 1429b22328f9Schristos { 1430b22328f9Schristos err = 1; 1431b22328f9Schristos *xerrmsg = xstrdup ("user has other permissions," 1432b22328f9Schristos " cannot remove read ('r')" 1433b22328f9Schristos " permission"); 1434b22328f9Schristos } 1435b22328f9Schristos else 1436b22328f9Schristos { 1437b22328f9Schristos err = 1; 1438b22328f9Schristos *xerrmsg = xstrdup ("user has other permissions," 1439b22328f9Schristos " cannot remove read ('r')" 1440b22328f9Schristos " permission"); 1441b22328f9Schristos } 1442b22328f9Schristos } 1443b22328f9Schristos break; 1444b22328f9Schristos case 'w': 1445b22328f9Schristos { 1446b22328f9Schristos tempfperms_len = 1; 1447b22328f9Schristos 1448b22328f9Schristos tempfperms = xmalloc (tempfperms_len); 1449b22328f9Schristos tempfperms[0] = '\0'; 1450b22328f9Schristos 1451b22328f9Schristos for (j = 0; j < fperms_len; j++) 1452b22328f9Schristos { 1453b22328f9Schristos if (fperms[j] == 't' || fperms[j] == 'c' || 1454b22328f9Schristos fperms[j] == 'd') 1455b22328f9Schristos { 1456b22328f9Schristos char *temp; 1457b22328f9Schristos temp = xmalloc (2); 1458b22328f9Schristos temp[0] = fperms[j]; 1459b22328f9Schristos temp[1] = '\0'; 1460b22328f9Schristos 1461b22328f9Schristos xrealloc_and_strcat (&tempfperms, 1462b22328f9Schristos &tempfperms_len, temp); 1463b22328f9Schristos free (temp); 1464b22328f9Schristos } 1465b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p') 1466b22328f9Schristos { 1467b22328f9Schristos err = 1; 1468b22328f9Schristos *xerrmsg = xstrdup ("user has higher" 1469b22328f9Schristos " permissions, cannot use" 1470b22328f9Schristos " +/- write permissions"); 1471b22328f9Schristos } 1472b22328f9Schristos else if (fperms[j] == 'n' || fperms[j] == 'r') 1473b22328f9Schristos { 1474b22328f9Schristos if (perms[0] == '-') 1475b22328f9Schristos { 1476b22328f9Schristos err = 1; 1477b22328f9Schristos *xerrmsg = xstrdup ("user does not have" 1478b22328f9Schristos " write ('w')" 1479b22328f9Schristos " permission"); 1480b22328f9Schristos } 1481b22328f9Schristos } 1482b22328f9Schristos else if (fperms[j] == 'w') 1483b22328f9Schristos { 1484b22328f9Schristos per = 1; 1485b22328f9Schristos if (perms[0] == '+') { 1486b22328f9Schristos err = 1; 1487b22328f9Schristos *xerrmsg = xstrdup ("user already have" 1488b22328f9Schristos " write ('w')" 1489b22328f9Schristos "permission"); 1490b22328f9Schristos } 1491b22328f9Schristos } 1492b22328f9Schristos } 1493b22328f9Schristos 1494*cc7958a0Schristos fperms = tempfperms; 1495b22328f9Schristos fperms_len = strlen (fperms); 1496b22328f9Schristos 1497b22328f9Schristos if (!per && !err && (perms[0] == '-')) { 1498b22328f9Schristos err = 1; 1499b22328f9Schristos *xerrmsg = xstrdup ("user does not have write" 1500b22328f9Schristos " ('w') permission"); 1501b22328f9Schristos } 1502b22328f9Schristos 1503b22328f9Schristos if (perms[0] == '+') 1504b22328f9Schristos { 1505b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "w"); 1506b22328f9Schristos } 1507b22328f9Schristos } 1508b22328f9Schristos break; 1509b22328f9Schristos case 't': 1510b22328f9Schristos { 1511b22328f9Schristos tempfperms_len = 1; 1512b22328f9Schristos 1513b22328f9Schristos tempfperms = xmalloc (tempfperms_len); 1514b22328f9Schristos tempfperms[0] = '\0'; 1515b22328f9Schristos 1516b22328f9Schristos for (j = 0; j < fperms_len; j++) 1517b22328f9Schristos { 1518b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 'c' || 1519b22328f9Schristos fperms[j] == 'd') 1520b22328f9Schristos { 1521b22328f9Schristos char *temp; 1522b22328f9Schristos temp = xmalloc (2); 1523b22328f9Schristos temp[0] = fperms[j]; 1524b22328f9Schristos temp[1] = '\0'; 1525b22328f9Schristos 1526b22328f9Schristos xrealloc_and_strcat (&tempfperms, 1527b22328f9Schristos &tempfperms_len, temp); 1528b22328f9Schristos free (temp); 1529b22328f9Schristos } 1530b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p') 1531b22328f9Schristos { 1532b22328f9Schristos err = 1; 1533b22328f9Schristos *xerrmsg = xstrdup ("user has higher" 1534b22328f9Schristos " permissions, cannot use" 1535b22328f9Schristos " +/- tag permissions"); 1536b22328f9Schristos } 1537b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r') 1538b22328f9Schristos { 1539b22328f9Schristos if (perms[0] == '-') 1540b22328f9Schristos *xerrmsg = xstrdup ("user does not have tag" 1541b22328f9Schristos " ('t') permission"); 1542b22328f9Schristos } 1543b22328f9Schristos else if (fperms[j] == 't') 1544b22328f9Schristos { 1545b22328f9Schristos per = 1; 1546b22328f9Schristos if (perms[0] == '+') 1547b22328f9Schristos { 1548b22328f9Schristos err = 1; 1549b22328f9Schristos *xerrmsg = xstrdup ("user already have tag" 1550b22328f9Schristos " ('t') permission"); 1551b22328f9Schristos } 1552b22328f9Schristos } 1553b22328f9Schristos } 1554b22328f9Schristos 1555*cc7958a0Schristos fperms = tempfperms; 1556b22328f9Schristos fperms_len = strlen (fperms); 1557b22328f9Schristos 1558b22328f9Schristos if (!per && !err && (perms[0] == '-')) 1559b22328f9Schristos { 1560b22328f9Schristos err = 1; 1561b22328f9Schristos *xerrmsg = xstrdup ("user does not have tag ('t')" 1562b22328f9Schristos " permission"); 1563b22328f9Schristos } 1564b22328f9Schristos 1565b22328f9Schristos if (perms[0] == '+') 1566b22328f9Schristos { 1567b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "t"); 1568b22328f9Schristos } 1569b22328f9Schristos } 1570b22328f9Schristos break; 1571b22328f9Schristos case 'c': 1572b22328f9Schristos { 1573b22328f9Schristos tempfperms_len = 1; 1574b22328f9Schristos 1575b22328f9Schristos tempfperms = xmalloc (tempfperms_len); 1576b22328f9Schristos tempfperms[0] = '\0'; 1577b22328f9Schristos 1578b22328f9Schristos for (j = 0; j < fperms_len; j++) 1579b22328f9Schristos { 1580b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 't' || 1581b22328f9Schristos fperms[j] == 'd') 1582b22328f9Schristos { 1583b22328f9Schristos char *temp; 1584b22328f9Schristos temp = xmalloc (2); 1585b22328f9Schristos temp[0] = fperms[j]; 1586b22328f9Schristos temp[1] = '\0'; 1587b22328f9Schristos 1588b22328f9Schristos xrealloc_and_strcat (&tempfperms, 1589b22328f9Schristos &tempfperms_len, temp); 1590b22328f9Schristos free (temp); 1591b22328f9Schristos } 1592b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p') 1593b22328f9Schristos { 1594b22328f9Schristos err = 1; 1595b22328f9Schristos *xerrmsg = xstrdup ("user has higher" 1596b22328f9Schristos " permissions, cannot use" 1597b22328f9Schristos " +/- create permissions"); 1598b22328f9Schristos } 1599b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r') 1600b22328f9Schristos { 1601b22328f9Schristos if (perms[0] == '-') 1602b22328f9Schristos err = 1; 1603b22328f9Schristos *xerrmsg = xstrdup ("user does not have create" 1604b22328f9Schristos " ('c') permission"); 1605b22328f9Schristos } 1606b22328f9Schristos else if (fperms[j] == 'c') 1607b22328f9Schristos { 1608b22328f9Schristos per = 1; 1609b22328f9Schristos if (perms[0] == '+') { 1610b22328f9Schristos err = 1; 1611b22328f9Schristos *xerrmsg = xstrdup ("user already have" 1612b22328f9Schristos " create ('c')" 1613b22328f9Schristos " permission"); 1614b22328f9Schristos } 1615b22328f9Schristos } 1616b22328f9Schristos } 1617b22328f9Schristos 1618*cc7958a0Schristos fperms = tempfperms; 1619b22328f9Schristos fperms_len = strlen (fperms); 1620b22328f9Schristos 1621b22328f9Schristos if (!per && !err && (perms[0] == '-')) { 1622b22328f9Schristos err = 1; 1623b22328f9Schristos *xerrmsg = xstrdup ("user does not have create" 1624b22328f9Schristos " ('c') permission"); 1625b22328f9Schristos } 1626b22328f9Schristos 1627b22328f9Schristos if (perms[0] == '+') 1628b22328f9Schristos { 1629b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "c"); 1630b22328f9Schristos } 1631b22328f9Schristos } 1632b22328f9Schristos break; 1633b22328f9Schristos case 'd': 1634b22328f9Schristos { 1635b22328f9Schristos tempfperms_len = 1; 1636b22328f9Schristos 1637b22328f9Schristos tempfperms = xmalloc (tempfperms_len); 1638b22328f9Schristos tempfperms[0] = '\0'; 1639b22328f9Schristos 1640b22328f9Schristos for (j = 0; j < fperms_len; j++) 1641b22328f9Schristos { 1642b22328f9Schristos if (fperms[j] == 'w' || fperms[j] == 'c' || 1643b22328f9Schristos fperms[j] == 't') 1644b22328f9Schristos { 1645b22328f9Schristos char *temp; 1646b22328f9Schristos temp = xmalloc (2); 1647b22328f9Schristos temp[0] = fperms[j]; 1648b22328f9Schristos temp[1] = '\0'; 1649b22328f9Schristos 1650b22328f9Schristos xrealloc_and_strcat (&tempfperms, 1651b22328f9Schristos &tempfperms_len, temp); 1652b22328f9Schristos free (temp); 1653b22328f9Schristos } 1654b22328f9Schristos else if (fperms[j] == 'a' || fperms[j] == 'p') 1655b22328f9Schristos { 1656b22328f9Schristos err = 1; 1657b22328f9Schristos *xerrmsg = xstrdup ("user has higher" 1658b22328f9Schristos " permissions, cannot use" 1659b22328f9Schristos " +/- delete permissions"); 1660b22328f9Schristos } 1661b22328f9Schristos else if (fperms[j] == 'n' || fperms[i] == 'r') 1662b22328f9Schristos { 1663b22328f9Schristos if (perms[0] == '-') 1664b22328f9Schristos err = 1; 1665b22328f9Schristos *xerrmsg = xstrdup ("user does not have delete" 1666b22328f9Schristos " ('d') permission"); 1667b22328f9Schristos } 1668b22328f9Schristos else if (fperms[j] == 'd') 1669b22328f9Schristos { 1670b22328f9Schristos per = 1; 1671b22328f9Schristos if (perms[0] == '+') { 1672b22328f9Schristos err = 1; 1673b22328f9Schristos *xerrmsg = xstrdup ("user already have" 1674b22328f9Schristos " delete ('d')" 1675b22328f9Schristos " permission"); 1676b22328f9Schristos } 1677b22328f9Schristos } 1678b22328f9Schristos } 1679b22328f9Schristos 1680*cc7958a0Schristos fperms = tempfperms; 1681b22328f9Schristos fperms_len = strlen (fperms); 1682b22328f9Schristos 1683b22328f9Schristos if (!per && !err && (perms[0] == '-')) { 1684b22328f9Schristos err = 1; 1685b22328f9Schristos *xerrmsg = xstrdup ("user does not have delete" 1686b22328f9Schristos " ('d') permission"); 1687b22328f9Schristos } 1688b22328f9Schristos 1689b22328f9Schristos if (perms[0] == '+') 1690b22328f9Schristos { 1691b22328f9Schristos xrealloc_and_strcat (&fperms, &fperms_len, "d"); 1692b22328f9Schristos } 1693b22328f9Schristos } 1694b22328f9Schristos break; 1695b22328f9Schristos default: 1696b22328f9Schristos err = 1; 1697b22328f9Schristos *xerrmsg = xstrdup ("error in 'access' file format"); 1698b22328f9Schristos break; 1699b22328f9Schristos } 1700b22328f9Schristos 1701b22328f9Schristos if (fperms[0] == '\0') 1702b22328f9Schristos retperms = xstrdup ("none"); 1703b22328f9Schristos else 1704b22328f9Schristos retperms = xstrdup (fperms); 1705b22328f9Schristos } 1706b22328f9Schristos } 1707b22328f9Schristos else 1708b22328f9Schristos { 1709b22328f9Schristos err = 1; 1710b22328f9Schristos *xerrmsg = xstrdup("user is not given any permissions to remove/add"); 1711b22328f9Schristos } 1712b22328f9Schristos } 1713b22328f9Schristos else 1714b22328f9Schristos { 1715b22328f9Schristos retperms = xstrdup (perms); 1716b22328f9Schristos } 1717*cc7958a0Schristos if (fperms) 1718*cc7958a0Schristos free (fperms); 1719*cc7958a0Schristos if (err && retperms) 1720*cc7958a0Schristos free (retperms); 1721b22328f9Schristos 1722b22328f9Schristos return (err ? NULL : retperms); 1723b22328f9Schristos } 1724b22328f9Schristos 1725b22328f9Schristos /* prepare and write resulting permissions to access file */ 1726b22328f9Schristos static int 1727b22328f9Schristos write_perms (const char *user, const char *perms, const char *founduserpart, 1728b22328f9Schristos int foundline, char *otheruserparts, 1729b22328f9Schristos const char *part_type, const char *part_object, 1730b22328f9Schristos const char *part_tag, int pos, const char *arepos) 1731b22328f9Schristos { 1732b22328f9Schristos char *accessfile; 1733b22328f9Schristos char *tmpaccessout; 1734b22328f9Schristos FILE *accessfpin; 1735b22328f9Schristos FILE *accessfpout; 1736b22328f9Schristos 1737b22328f9Schristos char *newline = NULL; 1738b22328f9Schristos size_t newlinelen = 1; 1739b22328f9Schristos char *object; 1740b22328f9Schristos 1741b22328f9Schristos char *line = NULL; 1742b22328f9Schristos size_t line_allocated = 0; 1743b22328f9Schristos 1744b22328f9Schristos newline = xmalloc (newlinelen); 1745b22328f9Schristos newline[0] = '\0'; 1746b22328f9Schristos 1747b22328f9Schristos if (!strcasecmp (part_tag, "ALL")) 1748b22328f9Schristos part_tag = "ALL"; 1749b22328f9Schristos 1750b22328f9Schristos /* strip any trailing slash if found */ 1751b22328f9Schristos object = xstrdup (part_object); 1752b22328f9Schristos if (object[strlen (object) - 1] == '/') 1753b22328f9Schristos object[strlen (object) - 1] = '\0'; 1754b22328f9Schristos 1755b22328f9Schristos /* first parts, part type, object, and tag */ 1756b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, part_type); 1757b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":"); 1758b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, object); 1759b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":"); 1760b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, part_tag); 1761b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":"); 1762b22328f9Schristos 1763b22328f9Schristos if (strncmp (perms, "none", 4) != 0) 1764b22328f9Schristos { 1765b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, user); 1766b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, "!"); 1767b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, perms); 1768b22328f9Schristos if (otheruserparts != NULL) 1769b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ","); 1770b22328f9Schristos } 1771b22328f9Schristos 1772b22328f9Schristos if (otheruserparts != NULL) 1773b22328f9Schristos { 1774b22328f9Schristos if (otheruserparts[strlen (otheruserparts) - 1] == '\n') 1775b22328f9Schristos otheruserparts[strlen (otheruserparts) - 1] = '\0'; 1776b22328f9Schristos 1777b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, otheruserparts); 1778b22328f9Schristos } 1779b22328f9Schristos 1780b22328f9Schristos xrealloc_and_strcat (&newline, &newlinelen, ":"); 1781b22328f9Schristos 1782b22328f9Schristos if (foundline) 1783b22328f9Schristos { 1784b22328f9Schristos accessfpout = cvs_temp_file (&tmpaccessout); 1785b22328f9Schristos if (accessfpout == NULL) 1786b22328f9Schristos error (1, errno, "cannot open temporary file: %s", tmpaccessout); 1787b22328f9Schristos 1788b22328f9Schristos accessfpin = open_accessfile ("r", arepos, &accessfile); 1789b22328f9Schristos if (accessfpout == NULL) 1790b22328f9Schristos error (1, errno, "cannot open access file: %s", accessfile); 1791b22328f9Schristos 1792b22328f9Schristos while (getline (&line, &line_allocated, accessfpin) >= 0) 1793b22328f9Schristos { 1794b22328f9Schristos if (pos != ftell (accessfpin)) 1795b22328f9Schristos { 1796b22328f9Schristos if (fprintf (accessfpout, "%s", line) < 0) 1797b22328f9Schristos error (1, errno, "writing temporary file: %s", tmpaccessout); 1798b22328f9Schristos } 1799b22328f9Schristos else 1800b22328f9Schristos { 1801b22328f9Schristos if (fprintf (accessfpout, "%s\n", newline) < 0) 1802b22328f9Schristos error (1, errno, "writing temporary file: %s", tmpaccessout); 1803b22328f9Schristos } 1804b22328f9Schristos 1805b22328f9Schristos } 1806b22328f9Schristos if (fclose (accessfpin) == EOF) 1807b22328f9Schristos error (1, errno, "cannot close access file: %s", accessfile); 1808b22328f9Schristos 1809b22328f9Schristos if (fclose (accessfpout) == EOF) 1810b22328f9Schristos error (1, errno, "cannot close temporary file: %s", tmpaccessout); 1811b22328f9Schristos 1812b22328f9Schristos if (CVS_UNLINK (accessfile) < 0) 1813b22328f9Schristos error (0, errno, "cannot remove %s", accessfile); 1814b22328f9Schristos 1815b22328f9Schristos copy_file (tmpaccessout, accessfile); 1816b22328f9Schristos 1817b22328f9Schristos if (CVS_UNLINK (tmpaccessout) < 0) 1818b22328f9Schristos error (0, errno, "cannot remove temporary file: %s", tmpaccessout); 1819b22328f9Schristos } 1820b22328f9Schristos else 1821b22328f9Schristos { 1822b22328f9Schristos accessfpout = open_accessfile ("r+", arepos, &accessfile); 1823b22328f9Schristos 1824b22328f9Schristos if (accessfpout == NULL) 1825b22328f9Schristos { 1826b22328f9Schristos if (existence_error (errno)) 1827b22328f9Schristos { 1828b22328f9Schristos accessfpout = open_accessfile ("w+", arepos, &accessfile); 1829b22328f9Schristos } 1830b22328f9Schristos if (accessfpout == NULL) 1831b22328f9Schristos error (1, errno, "cannot open access file: %s", accessfile); 1832b22328f9Schristos } 1833b22328f9Schristos else { 1834b22328f9Schristos if (fseek (accessfpout, 0, 2) != 0) 1835b22328f9Schristos error (1, errno, "cannot fseek access file: %s", accessfile); 1836b22328f9Schristos } 1837b22328f9Schristos 1838b22328f9Schristos if (fprintf (accessfpout, "%s\n", newline) < 0) 1839b22328f9Schristos error (1, errno, "writing access file: %s", accessfile); 1840b22328f9Schristos 1841b22328f9Schristos if (fclose (accessfpout) == EOF) 1842b22328f9Schristos error (1, errno, "cannot close access file: %s", accessfile); 1843b22328f9Schristos } 1844b22328f9Schristos 1845b22328f9Schristos free (line); 1846b22328f9Schristos free (newline); 1847b22328f9Schristos 1848b22328f9Schristos chmod (accessfile, 0644); 1849b22328f9Schristos 1850b22328f9Schristos return 0; 1851b22328f9Schristos } 1852b22328f9Schristos 1853b22328f9Schristos static int 1854b22328f9Schristos acllist_fileproc (void *callerdat, struct file_info *finfo) 1855b22328f9Schristos { 1856b22328f9Schristos char *filefullname; 1857b22328f9Schristos const char *frepository; 1858b22328f9Schristos char *line = NULL; 1859b22328f9Schristos int pos; 1860b22328f9Schristos 1861b22328f9Schristos if (!aclfile) 1862b22328f9Schristos return 0; 1863b22328f9Schristos 1864b22328f9Schristos frepository = Short_Repository (finfo->repository); 1865b22328f9Schristos 1866b22328f9Schristos filefullname = Xasprintf("%s/%s", frepository, finfo->file); 1867b22328f9Schristos 1868b22328f9Schristos /* check that user, which run acl/racl command, has admin permisson, 1869b22328f9Schristos * and also return the line with permissions from access file. */ 1870b22328f9Schristos if (!access_allowed (finfo->file, finfo->repository, tag, 5, &line, &pos, 1871b22328f9Schristos 0)) 1872b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'", frepository); 1873b22328f9Schristos 1874b22328f9Schristos acllist_print (line, filefullname); 1875b22328f9Schristos 1876b22328f9Schristos free (filefullname); 1877b22328f9Schristos 1878b22328f9Schristos return 0; 1879b22328f9Schristos } 1880b22328f9Schristos 1881b22328f9Schristos static Dtype 1882b22328f9Schristos acllist_dirproc (void *callerdat, const char *dir, const char *repos, 1883b22328f9Schristos const char *update_dir, List *entries) 1884b22328f9Schristos { 1885b22328f9Schristos char *line = NULL; 1886b22328f9Schristos const char *drepository; 1887b22328f9Schristos int pos; 1888b22328f9Schristos 1889b22328f9Schristos if (repos[0] == '\0') 1890b22328f9Schristos repos = Name_Repository (dir, NULL); 1891b22328f9Schristos 1892b22328f9Schristos if (!acldir) 1893b22328f9Schristos return 0; 1894b22328f9Schristos 1895b22328f9Schristos drepository = Short_Repository (repos); 1896b22328f9Schristos 1897b22328f9Schristos /* check that user, which run acl/racl command, has admin permisson, 1898b22328f9Schristos * and also return the line with permissions from access file. */ 1899b22328f9Schristos if (!access_allowed (NULL, repos, tag, 5, &line, &pos, 0)) 1900b22328f9Schristos error (1, 0, "You do not have admin rights on '%s'", drepository); 1901b22328f9Schristos 1902b22328f9Schristos acllist_print (line, drepository); 1903b22328f9Schristos 1904b22328f9Schristos return 0; 1905b22328f9Schristos } 1906b22328f9Schristos 1907b22328f9Schristos /* Prints permissions to screen with -l option */ 1908b22328f9Schristos void 1909b22328f9Schristos acllist_print (char *line, const char *obj) 1910b22328f9Schristos { 1911b22328f9Schristos char *temp; 1912b22328f9Schristos int c = 0; 1913b22328f9Schristos int def = 0; 1914b22328f9Schristos 1915b22328f9Schristos char *printedusers[255]; 1916b22328f9Schristos printedusers[0] = NULL; 1917b22328f9Schristos 1918b22328f9Schristos if (line != NULL) 1919b22328f9Schristos { 1920b22328f9Schristos temp = strtok (line, ":\t"); 1921b22328f9Schristos 1922b22328f9Schristos if (acldir) 1923b22328f9Schristos cvs_output ("d ", 0); 1924b22328f9Schristos else if (aclfile) 1925b22328f9Schristos cvs_output ("f ", 0); 1926b22328f9Schristos 1927b22328f9Schristos temp = strtok (NULL, ":\t"); 1928b22328f9Schristos 1929b22328f9Schristos cvs_output(obj, 0); 1930b22328f9Schristos cvs_output (" | ", 0); 1931b22328f9Schristos 1932b22328f9Schristos temp = strtok (NULL, ":\t"); 1933b22328f9Schristos cvs_output (temp, 0); 1934b22328f9Schristos cvs_output (" | ", 0); 1935b22328f9Schristos 1936b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL) 1937b22328f9Schristos { 1938b22328f9Schristos if (strncmp (temp, ":", 1) == 0) 1939b22328f9Schristos break; 1940b22328f9Schristos 1941b22328f9Schristos if (strcmp (temp, "ALL") == 0) 1942b22328f9Schristos { 1943b22328f9Schristos temp = strtok (NULL, ",\t"); 1944b22328f9Schristos continue; 1945b22328f9Schristos } 1946b22328f9Schristos 1947b22328f9Schristos cvs_output (temp, 0); 1948b22328f9Schristos cvs_output (":", 0); 1949b22328f9Schristos 1950b22328f9Schristos while (printedusers[c] != NULL) 1951b22328f9Schristos c++; 1952b22328f9Schristos 1953b22328f9Schristos printedusers[c] = xstrdup (temp); 1954b22328f9Schristos c++; 1955b22328f9Schristos printedusers[c] = NULL; 1956b22328f9Schristos 1957b22328f9Schristos temp = strtok (NULL, ",\t"); 1958b22328f9Schristos 1959b22328f9Schristos if (temp != NULL && temp[strlen (temp) - 2] == ':') 1960b22328f9Schristos temp[strlen (temp) - 2] = '\0'; 1961b22328f9Schristos 1962b22328f9Schristos cvs_output (temp, 0); 1963b22328f9Schristos cvs_output (" ", 0); 1964b22328f9Schristos } 1965b22328f9Schristos 1966b22328f9Schristos if (default_perms_object) 1967b22328f9Schristos { 1968b22328f9Schristos cvs_output ("| defaults ", 0); 1969b22328f9Schristos cvs_output ("ALL:", 0); 1970b22328f9Schristos cvs_output (default_perms_object, 0); 1971b22328f9Schristos def = 1; 1972b22328f9Schristos } 1973b22328f9Schristos if (default_part_perms_accessfile) 1974b22328f9Schristos { 1975b22328f9Schristos size_t i; 1976b22328f9Schristos i = strlen (default_part_perms_accessfile); 1977b22328f9Schristos xrealloc_and_strcat (&default_part_perms_accessfile, &i, ","); 1978b22328f9Schristos 1979b22328f9Schristos free (line); 1980b22328f9Schristos line = xstrdup (default_part_perms_accessfile); 1981b22328f9Schristos 1982b22328f9Schristos if (!def) 1983b22328f9Schristos cvs_output ("| defaults ", 0); 1984b22328f9Schristos else 1985b22328f9Schristos cvs_output (" ", 0); 1986b22328f9Schristos 1987b22328f9Schristos temp = strtok (line, "!\t"); 1988b22328f9Schristos cvs_output (temp, 0); 1989b22328f9Schristos cvs_output (":", 0); 1990b22328f9Schristos 1991b22328f9Schristos temp = strtok (NULL, ",\t"); 1992b22328f9Schristos 1993b22328f9Schristos cvs_output (temp, 0); 1994b22328f9Schristos cvs_output (" ", 0); 1995b22328f9Schristos 1996b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL) 1997b22328f9Schristos { 1998b22328f9Schristos int printed = 0; 1999b22328f9Schristos int c2 = 0; 2000b22328f9Schristos while (printedusers[c2] != NULL && printed == 0) 2001b22328f9Schristos { 2002b22328f9Schristos if (strcmp (printedusers[c2], temp) == 0) 2003b22328f9Schristos { 2004b22328f9Schristos printed = 1; 2005b22328f9Schristos break; 2006b22328f9Schristos } 2007b22328f9Schristos c2++; 2008b22328f9Schristos } 2009b22328f9Schristos 2010b22328f9Schristos if (printed == 0) 2011b22328f9Schristos { 2012b22328f9Schristos cvs_output (temp, 0); 2013b22328f9Schristos cvs_output (":", 0); 2014b22328f9Schristos } 2015b22328f9Schristos 2016b22328f9Schristos temp = strtok (NULL, ",\t"); 2017b22328f9Schristos 2018b22328f9Schristos if (temp[strlen (temp) - 2] == ':') 2019b22328f9Schristos temp[strlen (temp) - 2] = '\0'; 2020b22328f9Schristos 2021b22328f9Schristos if (printed == 0) 2022b22328f9Schristos { 2023b22328f9Schristos cvs_output (temp, 0); 2024b22328f9Schristos cvs_output (" ", 0); 2025b22328f9Schristos } 2026b22328f9Schristos } 2027b22328f9Schristos def = 1; 2028b22328f9Schristos } 2029b22328f9Schristos else if (cvs_acl_default_permissions) 2030b22328f9Schristos { 2031b22328f9Schristos cvs_output ("| defaults ", 0); 2032b22328f9Schristos cvs_output ("ALL: ", 0); 2033b22328f9Schristos cvs_output (cvs_acl_default_permissions, 0); 2034b22328f9Schristos } 2035b22328f9Schristos } 2036b22328f9Schristos else 2037b22328f9Schristos { 2038b22328f9Schristos if (acldir) 2039b22328f9Schristos cvs_output ("d ", 0); 2040b22328f9Schristos else if (aclfile) 2041b22328f9Schristos cvs_output ("f ", 0); 2042b22328f9Schristos cvs_output (obj, 0); 2043b22328f9Schristos cvs_output (" | ", 0); 2044b22328f9Schristos cvs_output (tag, 0); 2045b22328f9Schristos cvs_output (" | ", 0); 2046b22328f9Schristos 2047b22328f9Schristos if (default_perms_object) 2048b22328f9Schristos { 2049b22328f9Schristos cvs_output ("| defaults ", 0); 2050b22328f9Schristos cvs_output ("ALL:", 0); 2051b22328f9Schristos cvs_output (default_perms_object, 0); 2052b22328f9Schristos def = 1; 2053b22328f9Schristos } 2054b22328f9Schristos if (default_part_perms_accessfile) 2055b22328f9Schristos { 2056b22328f9Schristos free (line); 2057b22328f9Schristos line = xstrdup (default_part_perms_accessfile); 2058b22328f9Schristos 2059b22328f9Schristos if (!def) 2060b22328f9Schristos cvs_output ("| defaults ", 0); 2061b22328f9Schristos else 2062b22328f9Schristos cvs_output (" ", 0); 2063b22328f9Schristos 2064b22328f9Schristos temp = strtok (line, "!\t"); 2065b22328f9Schristos cvs_output (temp, 0); 2066b22328f9Schristos cvs_output (":", 0); 2067b22328f9Schristos 2068b22328f9Schristos temp = strtok (NULL, ",\t"); 2069b22328f9Schristos 2070b22328f9Schristos if (temp[strlen (temp) - 2] == ':') 2071b22328f9Schristos temp[strlen (temp) - 2] = '\0'; 2072b22328f9Schristos 2073b22328f9Schristos cvs_output (temp, 0); 2074b22328f9Schristos cvs_output (" ", 0); 2075b22328f9Schristos 2076b22328f9Schristos while ((temp = strtok (NULL, "!\t")) != NULL) 2077b22328f9Schristos { 2078b22328f9Schristos cvs_output (temp, 0); 2079b22328f9Schristos cvs_output (":", 0); 2080b22328f9Schristos 2081b22328f9Schristos if ((temp = strtok (NULL, ",\t")) != NULL) 2082b22328f9Schristos { 2083b22328f9Schristos if (temp[strlen (temp) - 2] == ':') 2084b22328f9Schristos temp[strlen (temp) - 2] = '\0'; 2085b22328f9Schristos 2086b22328f9Schristos cvs_output (temp, 0); 2087b22328f9Schristos cvs_output (" ", 0); 2088b22328f9Schristos } 2089b22328f9Schristos } 2090b22328f9Schristos cvs_output ("\n", 0); 2091b22328f9Schristos } 2092b22328f9Schristos else if (cvs_acl_default_permissions) 2093b22328f9Schristos { 2094b22328f9Schristos cvs_output ("| defaults ", 0); 2095b22328f9Schristos cvs_output ("ALL: ", 0); 2096b22328f9Schristos cvs_output (cvs_acl_default_permissions, 0); 2097b22328f9Schristos } 2098b22328f9Schristos else 2099b22328f9Schristos cvs_output ("default:p (no perms)", 0); 2100b22328f9Schristos } 2101b22328f9Schristos cvs_output ("\n", 0); 2102b22328f9Schristos 2103b22328f9Schristos while (c >= 0) { 2104b22328f9Schristos free (printedusers[c]); 2105b22328f9Schristos c--; 2106b22328f9Schristos } 2107b22328f9Schristos 2108b22328f9Schristos free (line); 2109b22328f9Schristos } 2110b22328f9Schristos 2111b22328f9Schristos /* find username 2112b22328f9Schristos * returns username with its permissions if user found 2113b22328f9Schristos * returns NULL if user not found */ 2114b22328f9Schristos char *findusername (const char *string1, const char *string2) 2115b22328f9Schristos { 2116b22328f9Schristos char *tmp1, *tmp2; 2117b22328f9Schristos 2118b22328f9Schristos if (string1 != NULL && string2 != NULL) 2119b22328f9Schristos { 2120b22328f9Schristos tmp1 = xstrdup (string1); 2121b22328f9Schristos tmp2 = strtok (tmp1, ",\t"); 2122b22328f9Schristos 2123b22328f9Schristos do 2124b22328f9Schristos { 2125b22328f9Schristos if (strncmp (tmp2, string2, strlen (string2)) == 0 && 2126b22328f9Schristos tmp2[strlen (string2)] == '!') 2127b22328f9Schristos { 2128*cc7958a0Schristos tmp2 = xstrdup (tmp2); 2129*cc7958a0Schristos free (tmp1); 2130b22328f9Schristos return tmp2; 2131b22328f9Schristos } 2132b22328f9Schristos tmp2 = strtok (NULL, ",\t"); 2133b22328f9Schristos } 2134b22328f9Schristos while (tmp2 != NULL); 2135b22328f9Schristos 2136b22328f9Schristos free (tmp1); 2137b22328f9Schristos 2138b22328f9Schristos return NULL; 2139b22328f9Schristos } 2140b22328f9Schristos else 2141b22328f9Schristos return NULL; 2142b22328f9Schristos } 2143b22328f9Schristos 2144b22328f9Schristos /* find user name in group file 2145b22328f9Schristos * returns group name if user found 2146b22328f9Schristos * returns NULL if user not found */ 2147b22328f9Schristos char *findgroupname (const char *string1, const char *string2) 2148b22328f9Schristos { 2149b22328f9Schristos char *tmp1, *tmp2; 2150b22328f9Schristos char *grpname; 2151b22328f9Schristos 2152b22328f9Schristos if (string1 != NULL && string2 != NULL) 2153b22328f9Schristos { 2154b22328f9Schristos tmp1 = xstrdup (string1); 2155b22328f9Schristos grpname = strtok (tmp1, ":\t"); 2156b22328f9Schristos 2157b22328f9Schristos while (tmp2 = strtok(NULL, ",\t")) 2158b22328f9Schristos { 2159b22328f9Schristos if (strcmp (tmp2, string2) == 0) 2160b22328f9Schristos { 2161*cc7958a0Schristos grpname = xstrdup (grpname); 2162*cc7958a0Schristos free (tmp1); 2163b22328f9Schristos return grpname; 2164b22328f9Schristos } 2165b22328f9Schristos } 2166b22328f9Schristos 2167b22328f9Schristos free (tmp1); 2168b22328f9Schristos 2169b22328f9Schristos return NULL; 2170b22328f9Schristos } 2171b22328f9Schristos else 2172b22328f9Schristos return NULL; 2173b22328f9Schristos } 2174