version 1.7, 2002/04/25 15:49:03 |
version 1.8, 2003/03/15 21:23:53 |
|
|
/* |
/* |
* Copyright (c) 1993-1996,1998-2001 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1993-1996,1998-2003 Todd C. Miller <Todd.Miller@courtesan.com> |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
#include "sudo.h" |
#include "sudo.h" |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: check.c,v 1.203 2002/04/25 15:30:12 millert Exp $"; |
static const char rcsid[] = "$Sudo: check.c,v 1.210 2003/03/15 20:31:01 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* Status codes for timestamp_status() */ |
/* Status codes for timestamp_status() */ |
|
|
char *timestampfile; |
char *timestampfile; |
{ |
{ |
|
|
|
if (timestamp_uid != 0) |
|
set_perms(PERM_TIMESTAMP); |
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) { |
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) { |
if (timestampfile) { |
if (timestampfile) { |
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600); |
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600); |
|
|
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir); |
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir); |
} |
} |
} |
} |
|
if (timestamp_uid != 0) |
|
set_perms(PERM_ROOT); |
} |
} |
|
|
/* |
/* |
|
|
char *user; |
char *user; |
char *host; |
char *host; |
{ |
{ |
size_t len; |
size_t len, n; |
int subst; |
int subst; |
char *p, *np, *new_prompt, lastchar; |
char *p, *np, *new_prompt, *endp; |
|
|
/* How much space do we need to malloc for the prompt? */ |
/* How much space do we need to malloc for the prompt? */ |
subst = 0; |
subst = 0; |
for (p = old_prompt, len = strlen(old_prompt), lastchar = '\0'; *p; p++) { |
for (p = old_prompt, len = strlen(old_prompt); *p; p++) { |
if (lastchar == '%') { |
if (p[0] =='%') { |
if (*p == 'h') { |
switch (p[1]) { |
len += strlen(user_shost) - 2; |
case 'h': |
subst = 1; |
p++; |
} else if (*p == 'u') { |
len += strlen(user_shost) - 2; |
len += strlen(user_name) - 2; |
subst = 1; |
subst = 1; |
break; |
|
case 'H': |
|
p++; |
|
len += strlen(user_host) - 2; |
|
subst = 1; |
|
break; |
|
case 'u': |
|
p++; |
|
len += strlen(user_name) - 2; |
|
subst = 1; |
|
break; |
|
case 'U': |
|
p++; |
|
len += strlen(*user_runas) - 2; |
|
subst = 1; |
|
break; |
|
case '%': |
|
p++; |
|
len--; |
|
subst = 1; |
|
break; |
|
default: |
|
break; |
} |
} |
} |
} |
|
|
if (lastchar == '%' && *p == '%') { |
|
lastchar = '\0'; |
|
len--; |
|
} else |
|
lastchar = *p; |
|
} |
} |
|
|
if (subst) { |
if (subst) { |
new_prompt = (char *) emalloc(len + 1); |
new_prompt = (char *) emalloc(++len); |
for (p = old_prompt, np = new_prompt, lastchar = '\0'; *p; p++) { |
*new_prompt = '\0'; |
if (lastchar == '%' && (*p == 'h' || *p == 'u' || *p == '%')) { |
endp = new_prompt + len - 1; |
/* substitute user/host name */ |
for (p = old_prompt, np = new_prompt; *p; p++) { |
if (*p == 'h') { |
if (p[0] =='%') { |
np--; |
switch (p[1]) { |
strcpy(np, user_shost); |
case 'h': |
np += strlen(user_shost); |
p++; |
} else if (*p == 'u') { |
if ((n = strlcat(new_prompt, user_shost, len)) >= len) |
np--; |
goto oflow; |
strcpy(np, user_name); |
np += n; |
np += strlen(user_name); |
continue; |
|
case 'H': |
|
p++; |
|
if ((n = strlcat(new_prompt, user_host, len)) >= len) |
|
goto oflow; |
|
np += n; |
|
continue; |
|
case 'u': |
|
p++; |
|
if ((n = strlcat(new_prompt, user_name, len)) >= len) |
|
goto oflow; |
|
np += n; |
|
continue; |
|
case 'U': |
|
p++; |
|
if ((n = strlcat(new_prompt, *user_runas, len)) >= len) |
|
goto oflow; |
|
np += n; |
|
continue; |
|
case '%': |
|
/* convert %% -> % */ |
|
p++; |
|
break; |
|
default: |
|
/* no conversion */ |
|
break; |
} |
} |
} else |
} |
*np++ = *p; |
if (np >= endp) |
|
goto oflow; |
if (lastchar == '%' && *p == '%') |
*np++ = *p; |
lastchar = '\0'; |
|
else |
|
lastchar = *p; |
|
} |
} |
*np = '\0'; |
*np = '\0'; |
} else |
} else |
new_prompt = old_prompt; |
new_prompt = old_prompt; |
|
|
return(new_prompt); |
return(new_prompt); |
|
|
|
oflow: |
|
/* We pre-allocate enough space, so this should never happen. */ |
|
(void) fprintf(stderr, "%s: internal error, expand_prompt() overflow\n", |
|
Argv[0]); |
|
exit(1); |
} |
} |
|
|
/* |
/* |
|
|
char *dirparent = def_str(I_TIMESTAMPDIR); |
char *dirparent = def_str(I_TIMESTAMPDIR); |
int status = TS_ERROR; /* assume the worst */ |
int status = TS_ERROR; /* assume the worst */ |
|
|
|
if (timestamp_uid != 0) |
|
set_perms(PERM_TIMESTAMP); |
|
|
/* |
/* |
* Sanity check dirparent and make it if it doesn't already exist. |
* Sanity check dirparent and make it if it doesn't already exist. |
* We start out assuming the worst (that the dir is not sane) and |
* We start out assuming the worst (that the dir is not sane) and |
|
|
if (!S_ISDIR(sb.st_mode)) |
if (!S_ISDIR(sb.st_mode)) |
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", |
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", |
dirparent, sb.st_mode); |
dirparent, sb.st_mode); |
else if (sb.st_uid != 0) |
else if (sb.st_uid != timestamp_uid) |
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root", |
log_error(NO_EXIT, "%s owned by uid %lu, should be uid %lu", |
dirparent, (long) sb.st_uid); |
dirparent, (unsigned long) sb.st_uid, |
|
(unsigned long) timestamp_uid); |
else if ((sb.st_mode & 0000022)) |
else if ((sb.st_mode & 0000022)) |
log_error(NO_EXIT, |
log_error(NO_EXIT, |
"%s writable by non-owner (0%o), should be mode 0700", |
"%s writable by non-owner (0%o), should be mode 0700", |
|
|
status = TS_MISSING; |
status = TS_MISSING; |
} |
} |
} |
} |
if (status == TS_ERROR) |
if (status == TS_ERROR) { |
|
if (timestamp_uid != 0) |
|
set_perms(PERM_ROOT); |
return(status); |
return(status); |
|
} |
|
|
/* |
/* |
* Sanity check the user's ticket dir. We start by downgrading |
* Sanity check the user's ticket dir. We start by downgrading |
|
|
} else |
} else |
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", |
log_error(NO_EXIT, "%s exists but is not a directory (0%o)", |
timestampdir, sb.st_mode); |
timestampdir, sb.st_mode); |
} else if (sb.st_uid != 0) |
} else if (sb.st_uid != timestamp_uid) |
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root", |
log_error(NO_EXIT, "%s owned by uid %lu, should be uid %lu", |
timestampdir, (long) sb.st_uid); |
timestampdir, (unsigned long) sb.st_uid, |
|
(unsigned long) timestamp_uid); |
else if ((sb.st_mode & 0000022)) |
else if ((sb.st_mode & 0000022)) |
log_error(NO_EXIT, |
log_error(NO_EXIT, |
"%s writable by non-owner (0%o), should be mode 0700", |
"%s writable by non-owner (0%o), should be mode 0700", |
|
|
timestampfile, sb.st_mode); |
timestampfile, sb.st_mode); |
} else { |
} else { |
/* If bad uid or file mode, complain and kill the bogus file. */ |
/* If bad uid or file mode, complain and kill the bogus file. */ |
if (sb.st_uid != 0) { |
if (sb.st_uid != timestamp_uid) { |
log_error(NO_EXIT, |
log_error(NO_EXIT, |
"%s owned by uid %ld, should be owned by root", |
"%s owned by uid %ud, should be uid %lu", |
timestampfile, (long) sb.st_uid); |
timestampfile, (unsigned long) sb.st_uid, |
|
(unsigned long) timestamp_uid); |
(void) unlink(timestampfile); |
(void) unlink(timestampfile); |
} else if ((sb.st_mode & 0000022)) { |
} else if ((sb.st_mode & 0000022)) { |
log_error(NO_EXIT, |
log_error(NO_EXIT, |
|
|
} |
} |
} |
} |
|
|
|
if (timestamp_uid != 0) |
|
set_perms(PERM_ROOT); |
return(status); |
return(status); |
} |
} |
|
|