setuid.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:7k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* @(#)setuid.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt */
  2. #ifndef lint
  3. static char     sccsid[] =
  4. "@(#)setuid.c 1.2 99/12/19 Copyright 1998,1999 Heiko Eissfeldt";
  5. #endif
  6. /* Security functions by zblaxell
  7.    If these functions fail, it is because there was an installation error
  8.    or a programming error, and we can't be sure about what privileges
  9.    we do or do not have.  This means we might not be able to recover
  10.    the privileges we need to fix anything that may be broken (e.g. the
  11.    CDDA state of some interface types), and we may in fact do something
  12.    quite dangerous (like write to the WAV file as root).
  13.    In any case, it is unsafe to do anything but exit *now*.  Ideally we'd
  14.    kill -9 our process group too, just to be sure.  Root privileges are not
  15.    something you want floating around at random in user-level applications.
  16.    If any signal handlers or child processes are introduced into this
  17.    program, it will be necessary to call dontneedroot() or neverneedroot()
  18.    on entry, respectively; otherwise, it will be possible to trick
  19.    the program into executing the signal handler or child process with
  20.    root privileges by sending signals at the right time.
  21.  */
  22. #include "config.h"
  23. #if defined (HAVE_UNISTD_H) && (HAVE_UNISTD_H == 1)
  24. #include <sys/types.h>
  25. #include <unistd.h>
  26. #endif
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include "setuid.h"
  30. #undef DEBUG
  31. /* True at return from initsecurity */
  32. static uid_t real_uid = (uid_t) (-1);
  33. static uid_t effective_uid = (uid_t) (-1);
  34. static gid_t real_gid = (gid_t) (-1);
  35. static gid_t effective_gid = (gid_t) (-1);
  36. /* Run this at the beginning of the program to initialize this code and
  37.    to drop privileges before someone uses them to shoot us in the foot.
  38.    Do not pass(go), do not dollars += 200. */
  39. void initsecurity()
  40. {
  41.     int leffective_uid;
  42.     alarm(0); /* can be inherited from parent process */
  43.     real_uid = getuid();
  44.     leffective_uid = geteuid();
  45.     if ((int) real_uid != leffective_uid && leffective_uid != 0) { /* sanity check */
  46.         fprintf(stderr, "Warning: setuid but not to root (uid=%ld, euid=%d)n", (long) real_uid, leffective_uid);
  47.         fprintf(stderr, "Dropping setuid privileges now.n");
  48.         neverneedroot();
  49.     } else {
  50.         effective_uid = leffective_uid;
  51.     }
  52.     real_gid = getgid();
  53.     effective_gid = getegid();
  54.     dontneedroot();
  55.     dontneedgroup();
  56. }
  57. /* Temporarily gain root privileges. */
  58. #if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID) && defined SCO
  59. /* SCO seems to lack the prototypes... */
  60. int seteuid __PR((uid_t euid));
  61. int setegid __PR((gid_t guid));
  62. #endif
  63. void needroot(necessary)
  64. int necessary;
  65. {
  66. #ifdef DEBUG
  67.     fprintf(stderr, "call to     needroot (_euid_=%d, uid=%d), current=%dn",effective_uid, real_uid, geteuid());
  68. #endif
  69.     if (effective_uid) {
  70.         if (necessary) {
  71.   fprintf(stderr, "Fatal error:  require root privilege but not setuid root.n");
  72.   exit(1);
  73. } else
  74.   return;
  75.     }
  76.     if (real_uid == (uid_t) (-1)) {
  77. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  78. exit(1);
  79.     }
  80.     if (geteuid() == 0) return; /* nothing to do */
  81. #if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID)
  82.     if (seteuid(effective_uid)) {
  83. perror("seteuid in needroot()");
  84. exit(1);
  85.     }
  86. #else
  87. #if defined (HAVE_SETREUID)
  88.     if (setreuid(real_uid, effective_uid)) {
  89. perror("setreuid in needroot()");
  90. exit(1);
  91.     }
  92. #endif
  93. #endif
  94.     if (geteuid() != 0 && necessary) {
  95. fprintf(stderr, "Fatal error:  did not get root privilege.n");
  96. exit(1);
  97.     }
  98. }
  99. /* Temporarily drop root privileges.  */
  100. void dontneedroot()
  101. {
  102. #ifdef DEBUG
  103.     fprintf(stderr, "call to dontneedroot (euid=%d, _uid_=%d), current=%dn",effective_uid, real_uid, geteuid());
  104. #endif
  105.     if (effective_uid)
  106. return;
  107.     if (real_uid == (uid_t) (-1)) {
  108. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  109. exit(1);
  110.     }
  111.     if (geteuid() != 0) return; /* nothing to do */
  112. #if defined _POSIX_SAVED_IDS && defined (HAVE_SETEUID)
  113.     if (seteuid(real_uid)) {
  114. perror("seteuid in dontneedroot()");
  115. exit(1);
  116.     }
  117. #else
  118. #if defined (HAVE_SETREUID)
  119.     if (setreuid(effective_uid, real_uid)) {
  120. perror("setreuid in dontneedroot()");
  121. exit(1);
  122.     }
  123. #endif
  124. #endif
  125.     if (geteuid() != real_uid) {
  126. fprintf(stderr, "Fatal error:  did not drop root privilege.n");
  127. exit(1);
  128.     }
  129. }
  130. /* Permanently drop root privileges.  */
  131. void neverneedroot()
  132. {
  133. #ifdef DEBUG
  134.     fprintf(stderr, "call to neverneedroot (euid=%d, uid=%d)n",effective_uid, real_uid);
  135. #endif
  136.     if (real_uid == (uid_t) (-1)) {
  137. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  138. exit(1);
  139.     }
  140.     if (geteuid() == 0) {
  141. #if defined (HAVE_SETUID)
  142.       if (setuid(real_uid)) {
  143.   perror("setuid in neverneedroot()");
  144.   exit(1);
  145.       }
  146. #endif
  147.     }
  148.     if (geteuid() != real_uid || getuid() != real_uid) {
  149. fprintf(stderr, "Fatal error:  did not drop root privilege.n");
  150. exit(1);
  151.     }
  152.     effective_uid = real_uid;
  153. }
  154. /* Temporarily gain group privileges. */
  155. void needgroup(necessary)
  156. int necessary;
  157. {
  158. #ifdef DEBUG
  159.     fprintf(stderr, "call to needgroup (egid=%d, gid=%d)n",effective_gid, real_gid);
  160. #endif
  161.     if (real_gid == (gid_t) (-1)) {
  162. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  163. exit(1);
  164.     }
  165.     if (getegid() == effective_gid) return; /* nothing to do */
  166. #if defined _POSIX_SAVED_IDS && defined (HAVE_SETEGID)
  167.     if (setegid(effective_gid)) {
  168. perror("setegid in needgroup()");
  169. exit(1);
  170.     }
  171. #else
  172. #if defined (HAVE_SETREGID)
  173.     if (setregid(real_gid, effective_gid)) {
  174. perror("setregid in needgroup()");
  175. exit(1);
  176.     }
  177. #endif
  178. #endif
  179.     if (necessary && getegid() != effective_gid) {
  180. fprintf(stderr, "Fatal error:  did not get group privilege.n");
  181. exit(1);
  182.     }
  183. }
  184. /* Temporarily drop group privileges.  */
  185. void dontneedgroup()
  186. {
  187. #ifdef DEBUG
  188.     fprintf(stderr, "call to dontneedgroup (egid=%d, gid=%d)n",effective_gid, real_gid);
  189. #endif
  190.     if (real_gid == (gid_t) (-1)) {
  191. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  192. exit(1);
  193.     }
  194.     if (getegid() != effective_gid) return; /* nothing to do */
  195. #if defined _POSIX_SAVED_IDS && defined (HAVE_SETEGID)
  196.     if (setegid(real_gid)) {
  197. perror("setegid in dontneedgroup()");
  198. exit(1);
  199.     }
  200. #else
  201. #if defined (HAVE_SETREGID)
  202.     if (setregid(effective_gid, real_gid)) {
  203. perror("setregid in dontneedgroup()");
  204. exit(1);
  205.     }
  206. #endif
  207. #endif
  208.     if (getegid() != real_gid) {
  209. fprintf(stderr, "Fatal error:  did not drop group privilege.n");
  210. exit(1);
  211.     }
  212. }
  213. /* Permanently drop group privileges.  */
  214. void neverneedgroup()
  215. {
  216. #ifdef DEBUG
  217.     fprintf(stderr, "call to neverneedgroup (egid=%d, gid=%d)n",effective_gid, real_gid);
  218. #endif
  219.     if (real_gid == (gid_t) (-1)) {
  220. fprintf(stderr, "Fatal error:  initsecurity() not called.n");
  221. exit(1);
  222.     }
  223.     if (getegid() != effective_gid) {
  224. #if defined (HAVE_SETUID)
  225.       if (setgid(real_gid)) {
  226.   perror("setgid in neverneedgroup()");
  227.   exit(1);
  228.       }
  229. #endif
  230.     }
  231.     if (getegid() != real_gid || getgid() != real_gid) {
  232. fprintf(stderr, "Fatal error:  did not drop group privilege.n");
  233. exit(1);
  234.     }
  235.     effective_gid = real_gid;
  236. }
  237. #if defined (HPUX)
  238. int seteuid(uid)
  239. uid_t uid;
  240. {
  241.   return setresuid(-1, uid, -1);
  242. }
  243. int setreuid(uid1, uid2)
  244. uid_t uid1;
  245. uid_t uid2;
  246. {
  247.   return setresuid(uid2, uid2, uid1 == uid2 ? uid2 : 0);
  248. }
  249. int setregid(gid1, gid2)
  250. gid_t gid1;
  251. gid_t gid2;
  252. {
  253.   return setresgid(gid2, gid2, gid1 == gid2 ? gid2 : 0);
  254. }
  255. #endif