Lines 41-46
Link Here
|
41 |
# include <sys/resource.h> |
41 |
# include <sys/resource.h> |
42 |
#endif /* HAVE_SYS_RESOURCE_H */ |
42 |
#endif /* HAVE_SYS_RESOURCE_H */ |
43 |
|
43 |
|
|
|
44 |
/* Linux capabilities */ |
45 |
#include <sys/capability.h> |
46 |
#include <sys/prctl.h> |
47 |
#include <pwd.h> |
48 |
#include <grp.h> |
49 |
|
44 |
#ifdef SYS_VXWORKS |
50 |
#ifdef SYS_VXWORKS |
45 |
# include "ioLib.h" |
51 |
# include "ioLib.h" |
46 |
# include "sockLib.h" |
52 |
# include "sockLib.h" |
Lines 127-132
Link Here
|
127 |
int rate = 0; |
133 |
int rate = 0; |
128 |
|
134 |
|
129 |
/* |
135 |
/* |
|
|
136 |
* Use capabilities to drop privileges and switch uids |
137 |
*/ |
138 |
char *server_user; |
139 |
|
140 |
/* |
130 |
* Program name. |
141 |
* Program name. |
131 |
*/ |
142 |
*/ |
132 |
char *progname; |
143 |
char *progname; |
Lines 273-278
Link Here
|
273 |
static ni_namelist *getnetinfoservers P((void)); |
284 |
static ni_namelist *getnetinfoservers P((void)); |
274 |
#endif |
285 |
#endif |
275 |
|
286 |
|
|
|
287 |
/* This patch is adapted (copied) from Chris Wings drop root patch |
288 |
* for xntpd. |
289 |
*/ |
290 |
void drop_root(uid_t server_uid, gid_t server_gid) |
291 |
{ |
292 |
cap_t caps; |
293 |
|
294 |
if (prctl(PR_SET_KEEPCAPS, 1)) { |
295 |
if (syslogit) { |
296 |
msyslog(LOG_ERR, "prctl(PR_SET_KEEPCAPS, 1) failed"); |
297 |
} |
298 |
else { |
299 |
fprintf(stderr, "prctl(PR_SET_KEEPCAPS, 1) failed.\n"); |
300 |
} |
301 |
exit(1); |
302 |
} |
303 |
|
304 |
if ( setgroups(0, NULL) == -1 ) { |
305 |
if (syslogit) { |
306 |
msyslog(LOG_ERR, "setgroups failed."); |
307 |
} |
308 |
else { |
309 |
fprintf(stderr, "setgroups failed.\n"); |
310 |
} |
311 |
exit(1); |
312 |
} |
313 |
|
314 |
if ( setegid(server_gid) == -1 || seteuid(server_uid) == -1 ) { |
315 |
if (syslogit) { |
316 |
msyslog(LOG_ERR, "setegid/seteuid to uid=%d/gid=%d failed.", server_uid, |
317 |
server_gid); |
318 |
} |
319 |
else { |
320 |
fprintf(stderr, "setegid/seteuid to uid=%d/gid=%d failed.\n", server_uid, |
321 |
server_gid); |
322 |
} |
323 |
exit(1); |
324 |
} |
325 |
|
326 |
caps = cap_from_text("cap_sys_time=epi"); |
327 |
if (caps == NULL) { |
328 |
if (syslogit) { |
329 |
msyslog(LOG_ERR, "cap_from_text failed."); |
330 |
} |
331 |
else { |
332 |
fprintf(stderr, "cap_from_text failed.\n"); |
333 |
} |
334 |
exit(1); |
335 |
} |
336 |
|
337 |
if (cap_set_proc(caps) == -1) { |
338 |
if (syslogit) { |
339 |
msyslog(LOG_ERR, "cap_set_proc failed."); |
340 |
} |
341 |
else { |
342 |
fprintf(stderr, "cap_set_proc failed.\n"); |
343 |
} |
344 |
exit(1); |
345 |
} |
346 |
|
347 |
/* Try to free the memory from cap_from_text */ |
348 |
cap_free( caps ); |
349 |
|
350 |
if ( setregid(server_gid, server_gid) == -1 || |
351 |
setreuid(server_uid, server_uid) == -1 ) { |
352 |
if (syslogit) { |
353 |
msyslog(LOG_ERR, "setregid/setreuid to uid=%d/gid=%d failed.", |
354 |
server_uid, server_gid); |
355 |
} |
356 |
else { |
357 |
fprintf(stderr, "setregid/setreuid to uid=%d/gid=%d failed.\n", |
358 |
server_uid, server_gid); |
359 |
} |
360 |
exit(1); |
361 |
} |
362 |
|
363 |
if (syslogit) { |
364 |
msyslog(LOG_DEBUG, "running as uid(%d)/gid(%d) euid(%d)/egid(%d).", |
365 |
getuid(), getgid(), geteuid(), getegid()); |
366 |
} |
367 |
} |
368 |
|
276 |
/* |
369 |
/* |
277 |
* Main program. Initialize us and loop waiting for I/O and/or |
370 |
* Main program. Initialize us and loop waiting for I/O and/or |
278 |
* timer expiries. |
371 |
* timer expiries. |
Lines 323-329
Link Here
|
323 |
#ifdef NO_MAIN_ALLOWED |
416 |
#ifdef NO_MAIN_ALLOWED |
324 |
clear_globals(); |
417 |
clear_globals(); |
325 |
#endif |
418 |
#endif |
326 |
|
419 |
server_user = NULL; |
327 |
errflg = 0; |
420 |
errflg = 0; |
328 |
progname = argv[0]; |
421 |
progname = argv[0]; |
329 |
syslogit = 0; |
422 |
syslogit = 0; |
Lines 331-337
Link Here
|
331 |
/* |
424 |
/* |
332 |
* Decode argument list |
425 |
* Decode argument list |
333 |
*/ |
426 |
*/ |
334 |
while ((c = ntp_getopt(argc, argv, "a:bBde:k:o:p:qr:st:uv")) != EOF) |
427 |
while ((c = ntp_getopt(argc, argv, "a:bBde:k:o:p:qr:st:uvU:")) != EOF) |
335 |
switch (c) |
428 |
switch (c) |
336 |
{ |
429 |
{ |
337 |
case 'a': |
430 |
case 'a': |
Lines 417-429
Link Here
|
417 |
case '?': |
510 |
case '?': |
418 |
++errflg; |
511 |
++errflg; |
419 |
break; |
512 |
break; |
|
|
513 |
case 'U': |
514 |
if (ntp_optarg) { |
515 |
server_user = strdup(ntp_optarg); |
516 |
} |
517 |
else { |
518 |
++errflg; |
519 |
} |
520 |
break; |
521 |
|
420 |
default: |
522 |
default: |
421 |
break; |
523 |
break; |
422 |
} |
524 |
} |
423 |
|
525 |
|
424 |
if (errflg) { |
526 |
if (errflg) { |
425 |
(void) fprintf(stderr, |
527 |
(void) fprintf(stderr, |
426 |
"usage: %s [-bBdqsv] [-a key#] [-e delay] [-k file] [-p samples] [-o version#] [-r rate] [-t timeo] server ...\n", |
528 |
"usage: %s [-bBdqsv] [-a key#] [-e delay] [-k file] [-p samples] [-o version#] [-r rate] [-t timeo] [-U username] server ...\n", |
427 |
progname); |
529 |
progname); |
428 |
exit(2); |
530 |
exit(2); |
429 |
} |
531 |
} |
Lines 536-541
Link Here
|
536 |
initializing = 0; |
638 |
initializing = 0; |
537 |
|
639 |
|
538 |
was_alarmed = 0; |
640 |
was_alarmed = 0; |
|
|
641 |
|
642 |
if (server_user) { |
643 |
struct passwd *pwd = NULL; |
644 |
|
645 |
/* Lookup server_user uid/gid before chroot/chdir */ |
646 |
pwd = getpwnam( server_user ); |
647 |
if ( pwd == NULL ) { |
648 |
if (syslogit) { |
649 |
msyslog(LOG_ERR, "Failed to lookup user '%s'.", server_user); |
650 |
} |
651 |
else { |
652 |
fprintf(stderr, "Failed to lookup user '%s'.\n", server_user); |
653 |
} |
654 |
exit(1); |
655 |
} |
656 |
drop_root(pwd->pw_uid, pwd->pw_gid); |
657 |
} |
658 |
|
539 |
rbuflist = (struct recvbuf *)0; |
659 |
rbuflist = (struct recvbuf *)0; |
540 |
while (complete_servers < sys_numservers) { |
660 |
while (complete_servers < sys_numservers) { |
541 |
#ifdef HAVE_POLL_H |
661 |
#ifdef HAVE_POLL_H |