1 /* 2 * Copyright (c) 2001 Proofpoint, Inc. and its suppliers. 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 11 /* 12 ** This program checks to see if your version of setgid works. 13 ** Compile it, make it set-group-ID guest, and run it as yourself (NOT as 14 ** root and not as member of the group guest). 15 ** 16 ** Compilation is trivial -- just "cc t_dropgid.c". Make it set-group-ID 17 ** guest and then execute it as a non-root user. 18 */ 19 20 #include <sys/types.h> 21 #include <unistd.h> 22 #include <stdio.h> 23 24 #ifndef lint 25 static char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $"; 26 #endif /* ! lint */ 27 28 static void 29 printgids(str, r, e) 30 char *str; 31 gid_t r, e; 32 { 33 printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e, 34 (int) getgid(), (int) getegid()); 35 } 36 37 /* define only one of these */ 38 #if HASSETEGID 39 # define SETGIDCALL "setegid" 40 #endif /* HASSETEGID */ 41 #if HASSETREGID 42 # define SETGIDCALL "setregid" 43 #endif /* HASSETREGID */ 44 #if HASSETRESGID 45 # define SETGIDCALL "setresgid" 46 #endif /* HASSETRESGID */ 47 48 #ifndef SETGIDCALL 49 # define SETGIDCALL "setgid" 50 #endif /* ! SETGIDCALL */ 51 52 int 53 main(argc, argv) 54 int argc; 55 char **argv; 56 { 57 int fail = 0; 58 int res; 59 gid_t realgid = getgid(); 60 gid_t effgid = getegid(); 61 char *prg = argv[0]; 62 63 printgids("initial gids", realgid, effgid); 64 65 if (effgid == realgid) 66 { 67 printf("SETUP ERROR: re-run set-group-ID guest\n"); 68 printf("Use chgrp(1) and chmod(1)\n"); 69 printf("For example, do this as root "); 70 printf("(nobody is the name of a group in this example):\n"); 71 printf("# chgrp nobody %s\n", prg); 72 printf("# chmod g+s nobody %s\n", prg); 73 exit(1); 74 } 75 76 #if HASSETREGID 77 res = setregid(realgid, realgid); 78 printf("setregid(%d)=%d %s\n", (int) realgid, res, 79 res < 0 ? "failure" : "ok"); 80 printgids("after setregid()", realgid, realgid); 81 #endif /* HASSETREGID */ 82 #if HASSETRESGID 83 res = setresgid(realgid, realgid, realgid); 84 printf("setresgid(%d)=%d %s\n", (int) realgid, res, 85 res < 0 ? "failure" : "ok"); 86 printgids("after setresgid()", realgid, realgid); 87 #endif /* HASSETRESGID */ 88 #if HASSETEGID 89 res = setegid(realgid); 90 printf("setegid(%d)=%d %s\n", (int) realgid, res, 91 res < 0 ? "failure" : "ok"); 92 printgids("after setegid()", realgid, realgid); 93 #endif /* HASSETEGID */ 94 res = setgid(realgid); 95 printf("setgid(%d)=%d %s\n", (int) realgid, res, 96 res < 0 ? "failure" : "ok"); 97 printgids("after setgid()", realgid, realgid); 98 99 if (getegid() != realgid) 100 { 101 fail++; 102 printf("MAYDAY! Wrong effective gid\n"); 103 } 104 105 if (getgid() != realgid) 106 { 107 fail++; 108 printf("MAYDAY! Wrong real gid\n"); 109 } 110 111 /* do activity here */ 112 if (setgid(effgid) == 0) 113 { 114 fail++; 115 printf("MAYDAY! setgid(%d) succeeded (should have failed)\n", 116 effgid); 117 } 118 else 119 { 120 printf("setgid(%d) failed (this is correct)\n", effgid); 121 } 122 printgids("after setgid() to egid", realgid, realgid); 123 124 if (getegid() != realgid) 125 { 126 fail++; 127 printf("MAYDAY! Wrong effective gid\n"); 128 } 129 if (getgid() != realgid) 130 { 131 fail++; 132 printf("MAYDAY! Wrong real gid\n"); 133 } 134 printf("\n"); 135 136 if (fail > 0) 137 { 138 printf("\nThis system cannot use %s to give up set-group-ID rights\n", 139 SETGIDCALL); 140 #if !HASSETEGID 141 printf("Maybe compile with -DHASSETEGID and try again\n"); 142 #endif /* !HASSETEGID */ 143 #if !HASSETREGID 144 printf("Maybe compile with -DHASSETREGID and try again\n"); 145 #endif /* !HASSETREGID */ 146 #if !HASSETRESGID 147 printf("Maybe compile with -DHASSETRESGID and try again\n"); 148 #endif /* !HASSETRESGID */ 149 exit(1); 150 } 151 152 printf("\nIt is possible to use %s on this system\n", SETGIDCALL); 153 exit(0); 154 } 155