| 关键词: nbsp char argv fprintf void return cmd argc cp command |
01./* 02.** sudo - run a command as root 03.*/ 04. 05.#include <stdio.h> 06.#include <strings.h> 07.#include <ctype.h> 08.#include <sys/time.h> 09.#include <sys/types.h> 10.#include <sys/stat.h> 11.#include <sys/param.h> 12.#include <pwd.h> 13. 14.#ifndef MAXHOSTNAMELEN 15.#define MAXHOSTNAMELEN 64 16.#endif MAXHOSTNAMELEN 17. 18./* terryh */ 19./*#define ALERTMAIL "root"*/ 20.#define ALERTMAIL "terryh" 21./* terryh */ 22./* #define LOGFILE "/usr/local/adm/logs/sudo.log"*/ 23.#define LOGFILE "/nfs/juno/u5/etc/bfdo/logs/bfdo.log" 24. 25.extern char *ctime(); 26.extern long time(); 27. 28./* terryh */ 29./*char *userfile = "/usr/local/adm/sudoers";*/ 30.char *userfile = "/nfs/juno/u5/etc/bfdo/bfdoers"; 31.char *progname; 32.long now; 33. 34.void log(), errexit(), firsthostname(); 35.int checkdoer(); 36.char *isadoer(); 37. 38.main(argc, argv) 39. 40.int argc; 41.char *argv[]; 42. 43.{ 44. char doerline[512]; 45. char cmd[512]; 46. char *dp; 47. struct passwd *pw; 48. int uid, pid; 49. 50. progname = argv[0]; 51. 52. if(argc < 2) 53. { 54. fprintf(stderr, "usage: %s cmd\n", progname); 55. exit(1); 56. } 57. 58. /* remember who this user really is */ 59. 60. uid = getuid(); 61. 62. /* Set userid to be root and group id to be daemon */ 63. 64./* terryh if((setuid(0)) < 0) 65. { 66. eperror("setuid"); 67. }*/ 68. 69./* terryh if((setgid(3)) < 0) 70. { 71. eperror("setgid"); 72. }*/ 73. 74. dp = &doerline[0]; 75. pw = getpwuid(uid); 76. now = time((long*) 0); 77. 78. if ((dp = isadoer(pw->pw_name,pw->pw_passwd)) == NULL) 79. { 80. log(pw->pw_name,"FAIL",argc,argv); 81. 82. fprintf(stderr,"%s:I don't know you, and I'm telling!\n",*argv); 83. 84. if ((pid = fork()) == 0) 85. mailmsg(pw->pw_name,argv,argc); 86. if (pid == -1) 87. eperror("fork"); 88. 89. exit(1); 90. } 91. 92. argv++, argc--; 93. 94. checkdoer(dp,*argv,cmd); 95. 96. if (strcmp(cmd,"all") == 0) 97. { 98. log(pw->pw_name,"",argc, argv); 99. execvp(*argv, argv); /* then do it */ 100. eperror(*argv); 101. } 102. 103. if (cmd[0] == '\0') 104. { 105. log(pw->pw_name,"FAIL",argc,argv); 106. fprintf(stderr, 107. "%s: I know you, but I can't let you: %s\n",progname,*argv); 108. exit(1); 109. } 110. 111. /* do a specific command with hard-coded path from doer file */ 112. 113. log(pw->pw_name,"",argc,argv); 114. execv(cmd, argv); /* then do it */ 115. eperror(*argv); 116.} 117. 118./* 119.** isadoer(name, encrypted password) - look for a user in USERFILE 120.** return doer entry on success, else NULL. 121.*/ 122. 123.char *isadoer(name,password) 124. 125.char *name; 126.char *password; 127. 128.{ 129. register FILE *fp; 130. char buf[BUFSIZ]; 131. struct stat statb; 132. 133. if (stat(userfile, &statb)) 134. eperror(userfile); 135. 136. /* terryh 137. if (statb.st_uid != 0) 138. errexit("%s must be owned by root\n", userfile);*/ 139. 140. /* terryh 141. if (statb.st_mode & 022)*/ /* should be og-w */ 142. /*errexit("bad modes on %s\n", userfile);*/ 143. 144. if ((fp = fopen(userfile,"r")) == 0 ) 145. errexit("Couldn't open %s\n",userfile); 146. 147. while ((fgets(buf,BUFSIZ,fp)) != NULL) 148. { 149. if(buf[0] == '#') /* munch comments */ 150. { 151. continue; 152. } 153. 154. if((strncmp(buf,name,strlen(name))) == 0) 155. { 156. /* terryh */ 157. /* if (not_timed_out(name,password)) */ 158. { 159. return(buf); 160. } 161. return(NULL); 162. } 163. } 164. 165. return(NULL); 166.} 167. 168./* 169.** log this command in the log file 170.*/ 171. 172.void 173.log(username, info, argc, argv) 174. 175.char *username; 176.char *info; 177.int argc; 178.char **argv; 179. 180.{ 181. register FILE *fp; 182. fp = fopen(LOGFILE,"a"); 183. 184. if (fp == NULL) 185. { 186. errexit("can't open %s.\n", LOGFILE); 187. } 188. 189. fprintf (fp, "%20.20s :", ctime(&now)); 190. fprintf (fp,"%s",info); 191. fprintf (fp,"%7.7s :",username); 192. 193. while (argc--) 194. { 195. fprintf (fp,"%s ",*argv++); 196. } 197. 198. fprintf (fp,"\n"); 199. (void) fclose (fp); 200. return; 201.} 202. 203./* 204.** eperror - print system error message and exit 205.** string s is printed too. 206.*/ 207. 208.eperror(s) 209. 210.register char *s; 211. 212.{ 213. fprintf(stderr,"%s: ",progname); 214. perror(s); 215. exit(1); 216.} 217. 218./* 219.** errexit(format, message) - print formatted error and exit 220.** also send mail 221.*/ 222. 223.void 224.errexit(fmt, arg) 225. 226.register char *fmt, *arg; 227. 228.{ 229. FILE *popen(); 230. FILE *fd; 231. char hostname[MAXHOSTNAMELEN]; 232. char cmd[80]; 233. 234. fprintf(stderr,"%s: ", progname); 235. fprintf(stderr, fmt, arg); 236. 237. if ((fd = popen(cmd, "w")) == NULL) 238. { 239. return; 240. } 241. 242. firsthostname(hostname, MAXHOSTNAMELEN); 243. 244. (void) sprintf(cmd, 245. "/usr/ucb/mail -s \"HELP! %s@%s has problems.\" %s ", 246. progname,hostname,ALERTMAIL); 247. 248. if ((fd = popen(cmd, "w")) == NULL) 249. { 250. return; 251. } 252. 253. fprintf(fd,"%s: ", progname); 254. fprintf(fd, fmt, arg); 255. (void) pclose(fd); 256. exit(1); 257.} 258. 259./* 260.** checkdoer - check to see if user is permitted to do command requested. 261.** dp points to a sudoer file entry of the form: 262.** 'user ['all,','/dir/dir/cmd1,/dir/dir/cmd2,/dir/dir/cmdN'] ie) 263.** coggs /bin/wall,/etc/vipassw,/etc/adduser 264.** operator shutdown 265.** If 'all' is found, then string "all" is returned in res. 266.** If command passed in ap is found, then that command, along 267.** with its full path are passed back in res. If nothing is 268.** found, then NULL is returned in res. 269.*/ 270. 271.checkdoer(dp,ap,res) 272. 273.char *dp; /* doer file entry: 'user cmd1,cmd2,cmdN' */ 274.char *ap; 275.char *res; 276.{ 277. char *cp0, *cp1, *cp2; 278. 279. cp0 = dp; 280. 281. while(isalnum(*cp0)) /* skip past user field */ 282. { 283. cp0++; 284. } 285. 286. while(*cp0) /* search until end of line */ 287. { 288. while(isspace(*cp0)) /* skip to beg of cmd field */ 289. { 290. cp0++; 291. } 292. 293. if (strncmp(cp0,"all",3) == 0) /* if cmd field is "all" */ 294. { 295. (void) strcpy(res,"all"); /* then pass it back */ 296. return; 297. } 298. 299. cp1 = cp0; 300. 301. /* find end of this entry */ 302. 303. while (*cp1 != '\n' && !isspace(*cp1)) 304. { 305. cp1++; 306. } 307. 308. cp1--; /* point to last character of cmd */ 309. cp2 = cp1; 310. 311. while (*cp2 != '/') /* backup to head of command */ 312. { 313. cp2--; 314. } 315. 316. cp2++; 317. 318. cp1++; /* point cp1 to last character + 1 */ 319. 320. /* if command issued is found then pass whole path back */ 321. 322. if (strncmp(cp2,ap,strlen(ap)) == 0) 323. { 324. (void) strncpy(res,cp0,cp1-cp0); /* copy command back */ 325. *(res+(cp1-cp0)) = '\0'; /* terryh */ 326. return; 327. } 328. 329. /* 330. * if it got to here, then command not found *yet* 331. * move pointer past next comma and keep looking 332. */ 333. 334. while (!isspace(*cp0) && *cp0 != '\n') 335. { 336. cp0++; 337. } 338. 339. if (*cp0 == '\n') /* if at endo of line then fail */ 340. { 341. break; 342. } 343. else 344. { 345. continue; 346. } 347. } 348. 349. *res = NULL; 350. return; 351.} 352. 353./* 354.** mailmsg - Snitch on person 355.*/ 356. 357.mailmsg (user,argv,argc) 358. 359.char *user, **argv; 360.int argc; 361. 362.{ 363. FILE *popen(); 364. FILE *fd; 365. char *p; 366. char cmd[80]; 367. char hostname[MAXHOSTNAMELEN]; 368. 369. firsthostname(hostname, MAXHOSTNAMELEN); 370. 371. (void) sprintf(cmd, 372. "/usr/ucb/mail -s \"*SECURITY* %s@%s tried to execute %s\" %s ", 373. user,hostname,*argv,ALERTMAIL); 374. 375. if ((fd = popen(cmd, "w")) == NULL) 376. { 377. return; 378. } 379. 380. fprintf(fd,"%s\@%s tried to do a\n\n ",user,hostname); 381. 382. while(argc--) 383. { 384. for (p = *argv++; *p; p++) 385. { 386. *p &= 0177; 387. (void) fputc(*p, fd); 388. if (*p == '\n') (void) fputc('+', fd); 389. } 390. (void) fputc(' ', fd); 391. } 392. 393. (void) fputs("\n\nThought you might want to know.",fd); 394. 395. (void) pclose(fd); 396.} 397. 398./* 399.** firsthostname() - return hostname without domain stuff. 400.** Parameters - pointer to char array for name, and length of array. 401.*/ 402. 403.void 404.firsthostname(n, l) 405. 406.char *n; 407.int l; 408. 409.{ 410. (void) gethostname(n, l); /* get full hostname */ 411. n[l-1] = 0; /* make sure null terminated */ 412. if (n = index(n, '.')) *n = 0; /* blat null on top of '.' if any */ 413.} 本文来自: cool kid's blog http://www.cnredhat.com/?action=show&id=219 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|