#include <config.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <pwd.h>
#include <grp.h>
#include "sudoers.h"
char *
expand_prompt(const char *old_prompt, const char *auth_user)
{
size_t len, n;
int subst;
const char *p;
char *np, *new_prompt, *endp;
debug_decl(expand_prompt, SUDOERS_DEBUG_AUTH)
subst = 0;
for (p = old_prompt, len = strlen(old_prompt); *p; p++) {
if (p[0] =='%') {
switch (p[1]) {
case 'h':
p++;
len += strlen(user_shost) - 2;
subst = 1;
break;
case 'H':
p++;
len += strlen(user_host) - 2;
subst = 1;
break;
case 'p':
p++;
len += strlen(auth_user) - 2;
subst = 1;
break;
case 'u':
p++;
len += strlen(user_name) - 2;
subst = 1;
break;
case 'U':
p++;
len += strlen(runas_pw->pw_name) - 2;
subst = 1;
break;
case '%':
p++;
len--;
subst = 1;
break;
default:
break;
}
}
}
if ((new_prompt = malloc(++len)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
debug_return_str(NULL);
}
if (subst) {
endp = new_prompt + len;
for (p = old_prompt, np = new_prompt; *p; p++) {
if (p[0] =='%') {
switch (p[1]) {
case 'h':
p++;
n = strlcpy(np, user_shost, np - endp);
if (n >= (size_t)(np - endp))
goto oflow;
np += n;
continue;
case 'H':
p++;
n = strlcpy(np, user_host, np - endp);
if (n >= (size_t)(np - endp))
goto oflow;
np += n;
continue;
case 'p':
p++;
n = strlcpy(np, auth_user, np - endp);
if (n >= (size_t)(np - endp))
goto oflow;
np += n;
continue;
case 'u':
p++;
n = strlcpy(np, user_name, np - endp);
if (n >= (size_t)(np - endp))
goto oflow;
np += n;
continue;
case 'U':
p++;
n = strlcpy(np, runas_pw->pw_name, np - endp);
if (n >= (size_t)(np - endp))
goto oflow;
np += n;
continue;
case '%':
p++;
break;
default:
break;
}
}
*np++ = *p;
if (np >= endp)
goto oflow;
}
*np = '\0';
} else {
memcpy(new_prompt, old_prompt, len);
}
debug_return_str(new_prompt);
oflow:
free(new_prompt);
sudo_warnx(U_("internal error, %s overflow"), __func__);
debug_return_str(NULL);
}