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 #include <stdlib.h> 24 25 #ifndef lint 26 static char id[] = "@(#)$Id: t_dropgid.c,v 1.7 2013-11-22 20:52:01 ca Exp $"; 27 #endif 28 29 static void 30 printgids(str, r, e) 31 char *str; 32 gid_t r, e; 33 { 34 printf("%s (should be %d/%d): r/egid=%d/%d\n", str, (int) r, (int) e, 35 (int) getgid(), (int) getegid()); 36 } 37 38 /* define only one of these */ 39 #if HASSETEGID 40 # define SETGIDCALL "setegid" 41 #endif 42 #if HASSETREGID 43 # define SETGIDCALL "setregid" 44 #endif 45 #if HASSETRESGID 46 # define SETGIDCALL "setresgid" 47 #endif 48 49 #ifndef SETGIDCALL 50 # define SETGIDCALL "setgid" 51 #endif 52 53 int 54 main(argc, argv) 55 int argc; 56 char **argv; 57 { 58 int fail = 0; 59 int res; 60 gid_t realgid = getgid(); 61 gid_t effgid = getegid(); 62 char *prg = argv[0]; 63 64 printgids("initial gids", realgid, effgid); 65 66 if (effgid == realgid) 67 { 68 printf("SETUP ERROR: re-run set-group-ID guest\n"); 69 printf("Use chgrp(1) and chmod(1)\n"); 70 printf("For example, do this as root "); 71 printf("(nobody is the name of a group in this example):\n"); 72 printf("# chgrp nobody %s\n", prg); 73 printf("# chmod g+s nobody %s\n", prg); 74 exit(1); 75 } 76 77 #if HASSETREGID 78 res = setregid(realgid, realgid); 79 printf("setregid(%d)=%d %s\n", (int) realgid, res, 80 res < 0 ? "failure" : "ok"); 81 printgids("after setregid()", realgid, realgid); 82 #endif /* HASSETREGID */ 83 #if HASSETRESGID 84 res = setresgid(realgid, realgid, realgid); 85 printf("setresgid(%d)=%d %s\n", (int) realgid, res, 86 res < 0 ? "failure" : "ok"); 87 printgids("after setresgid()", realgid, realgid); 88 #endif /* HASSETRESGID */ 89 #if HASSETEGID 90 res = setegid(realgid); 91 printf("setegid(%d)=%d %s\n", (int) realgid, res, 92 res < 0 ? "failure" : "ok"); 93 printgids("after setegid()", realgid, realgid); 94 #endif /* HASSETEGID */ 95 res = setgid(realgid); 96 printf("setgid(%d)=%d %s\n", (int) realgid, res, 97 res < 0 ? "failure" : "ok"); 98 printgids("after setgid()", realgid, realgid); 99 100 if (getegid() != realgid) 101 { 102 fail++; 103 printf("MAYDAY! Wrong effective gid\n"); 104 } 105 106 if (getgid() != realgid) 107 { 108 fail++; 109 printf("MAYDAY! Wrong real gid\n"); 110 } 111 112 /* do activity here */ 113 if (setgid(effgid) == 0) 114 { 115 fail++; 116 printf("MAYDAY! setgid(%d) succeeded (should have failed)\n", 117 effgid); 118 } 119 else 120 { 121 printf("setgid(%d) failed (this is correct)\n", effgid); 122 } 123 printgids("after setgid() to egid", realgid, realgid); 124 125 if (getegid() != realgid) 126 { 127 fail++; 128 printf("MAYDAY! Wrong effective gid\n"); 129 } 130 if (getgid() != realgid) 131 { 132 fail++; 133 printf("MAYDAY! Wrong real gid\n"); 134 } 135 printf("\n"); 136 137 if (fail > 0) 138 { 139 printf("\nThis system cannot use %s to give up set-group-ID rights\n", 140 SETGIDCALL); 141 #if !HASSETEGID 142 printf("Maybe compile with -DHASSETEGID and try again\n"); 143 #endif 144 #if !HASSETREGID 145 printf("Maybe compile with -DHASSETREGID and try again\n"); 146 #endif 147 #if !HASSETRESGID 148 printf("Maybe compile with -DHASSETRESGID and try again\n"); 149 #endif 150 exit(1); 151 } 152 153 printf("\nIt is possible to use %s on this system\n", SETGIDCALL); 154 exit(0); 155 } 156