Add primitive format string support to the lbuf code to make translations

simpler.
This commit is contained in:
Todd C. Miller
2011-05-20 15:25:03 -04:00
parent 681547c5fa
commit bd36d4f2ab
6 changed files with 207 additions and 241 deletions

View File

@@ -69,81 +69,89 @@ lbuf_destroy(struct lbuf *lbuf)
} }
/* /*
* Append strings to the buffer, expanding it as needed. * Parse the format and append strings, only %s and %% escapes are supported.
* Any characters in set are quoted with a backslash.
*/ */
void void
lbuf_append_quoted(struct lbuf *lbuf, const char *set, ...) lbuf_append_quoted(struct lbuf *lbuf, const char *set, const char *fmt, ...)
{ {
va_list ap; va_list ap;
int len = 0; int len;
char *cp, *s; char *cp, *s = NULL;
va_start(ap, set); va_start(ap, fmt);
while ((s = va_arg(ap, char *)) != NULL) { while (*fmt != '\0') {
len += strlen(s); len = 1;
for (cp = s; (cp = strpbrk(cp, set)) != NULL; cp++) if (fmt[0] == '%' && fmt[1] == 's') {
len++; s = va_arg(ap, char *);
}
va_end(ap);
/* Expand buffer as needed. */
if (lbuf->len + len >= lbuf->size) {
do {
lbuf->size += 256;
} while (lbuf->len + len >= lbuf->size);
lbuf->buf = erealloc(lbuf->buf, lbuf->size);
}
va_start(ap, set);
/* Append each string. */
while ((s = va_arg(ap, char *)) != NULL) {
while ((cp = strpbrk(s, set)) != NULL) {
len = (int)(cp - s);
memcpy(lbuf->buf + lbuf->len, s, len);
lbuf->len += len;
lbuf->buf[lbuf->len++] = '\\';
lbuf->buf[lbuf->len++] = *cp;
s = cp + 1;
}
if (*s != '\0') {
len = strlen(s); len = strlen(s);
memcpy(lbuf->buf + lbuf->len, s, len);
lbuf->len += len;
} }
/* Assume worst case that all chars must be escaped. */
if (lbuf->len + (len * 2) + 1 >= lbuf->size) {
do {
lbuf->size += 256;
} while (lbuf->len + len + 1 >= lbuf->size);
lbuf->buf = erealloc(lbuf->buf, lbuf->size);
}
if (*fmt == '%') {
if (*(++fmt) == 's') {
while ((cp = strpbrk(s, set)) != NULL) {
len = (int)(cp - s);
memcpy(lbuf->buf + lbuf->len, s, len);
lbuf->len += len;
lbuf->buf[lbuf->len++] = '\\';
lbuf->buf[lbuf->len++] = *cp;
s = cp + 1;
}
if (*s != '\0') {
len = strlen(s);
memcpy(lbuf->buf + lbuf->len, s, len);
lbuf->len += len;
}
fmt++;
continue;
}
}
if (strchr(set, *fmt) != NULL)
lbuf->buf[lbuf->len++] = '\\';
lbuf->buf[lbuf->len++] = *fmt++;
} }
lbuf->buf[lbuf->len] = '\0'; lbuf->buf[lbuf->len] = '\0';
va_end(ap); va_end(ap);
} }
/* /*
* Append strings to the buffer, expanding it as needed. * Parse the format and append strings, only %s and %% escapes are supported.
*/ */
void void
lbuf_append(struct lbuf *lbuf, ...) lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
{ {
va_list ap; va_list ap;
int len = 0; int len;
char *s; char *s = NULL;
va_start(ap, lbuf); va_start(ap, fmt);
while ((s = va_arg(ap, char *)) != NULL) while (*fmt != '\0') {
len += strlen(s); len = 1;
va_end(ap); if (fmt[0] == '%' && fmt[1] == 's') {
s = va_arg(ap, char *);
/* Expand buffer as needed. */ len = strlen(s);
if (lbuf->len + len >= lbuf->size) { }
do { if (lbuf->len + len + 1 >= lbuf->size) {
lbuf->size += 256; do {
} while (lbuf->len + len >= lbuf->size); lbuf->size += 256;
lbuf->buf = erealloc(lbuf->buf, lbuf->size); } while (lbuf->len + len + 1 >= lbuf->size);
} lbuf->buf = erealloc(lbuf->buf, lbuf->size);
}
va_start(ap, lbuf); if (*fmt == '%') {
/* Append each string. */ if (*(++fmt) == 's') {
while ((s = va_arg(ap, char *)) != NULL) { memcpy(lbuf->buf + lbuf->len, s, len);
len = strlen(s); lbuf->len += len;
memcpy(lbuf->buf + lbuf->len, s, len); fmt++;
lbuf->len += len; continue;
}
}
lbuf->buf[lbuf->len++] = *fmt++;
} }
lbuf->buf[lbuf->len] = '\0'; lbuf->buf[lbuf->len] = '\0';
va_end(ap); va_end(ap);

View File

@@ -34,8 +34,8 @@ struct lbuf {
void lbuf_init(struct lbuf *, int (*)(const char *), int, const char *, int); void lbuf_init(struct lbuf *, int (*)(const char *), int, const char *, int);
void lbuf_destroy(struct lbuf *); void lbuf_destroy(struct lbuf *);
void lbuf_append(struct lbuf *, ...); void lbuf_append(struct lbuf *, const char *, ...) __printflike(2, 3);
void lbuf_append_quoted(struct lbuf *, const char *, ...); void lbuf_append_quoted(struct lbuf *, const char *, const char *, ...) __printflike(3, 4);
void lbuf_print(struct lbuf *); void lbuf_print(struct lbuf *);
#endif /* _SUDO_LBUF_H */ #endif /* _SUDO_LBUF_H */

View File

@@ -1430,7 +1430,7 @@ sudo_ldap_display_defaults(struct sudo_nss *nss, struct passwd *pw,
else else
prefix = ", "; prefix = ", ";
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
lbuf_append(lbuf, prefix, (*p)->bv_val, NULL); lbuf_append(lbuf, "%s%s", prefix, (*p)->bv_val);
prefix = ", "; prefix = ", ";
count++; count++;
} }
@@ -1464,7 +1464,7 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
struct berval **bv, **p; struct berval **bv, **p;
int count = 0; int count = 0;
lbuf_append(lbuf, " (", NULL); lbuf_append(lbuf, " (");
/* get the RunAsUser Values from the entry */ /* get the RunAsUser Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser"); bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
@@ -1472,26 +1472,22 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
bv = ldap_get_values_len(ld, entry, "sudoRunAs"); bv = ldap_get_values_len(ld, entry, "sudoRunAs");
if (bv != NULL) { if (bv != NULL) {
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} else } else
lbuf_append(lbuf, def_runas_default, NULL); lbuf_append(lbuf, "%s", def_runas_default);
/* get the RunAsGroup Values from the entry */ /* get the RunAsGroup Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup"); bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
if (bv != NULL) { if (bv != NULL) {
lbuf_append(lbuf, " : ", NULL); lbuf_append(lbuf, " : ");
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} }
lbuf_append(lbuf, ") ", NULL); lbuf_append(lbuf, ") ");
/* get the Option Values from the entry */ /* get the Option Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoOption"); bv = ldap_get_values_len(ld, entry, "sudoOption");
@@ -1513,7 +1509,7 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
tag = (*p)->bv_val[0] == '!' ? tag = (*p)->bv_val[0] == '!' ?
"NOSETENV: " : "SETENV: "; "NOSETENV: " : "SETENV: ";
if (tag != NULL) if (tag != NULL)
lbuf_append(lbuf, tag, NULL); lbuf_append(lbuf, tag);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} }
@@ -1522,14 +1518,12 @@ sudo_ldap_display_entry_short(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
bv = ldap_get_values_len(ld, entry, "sudoCommand"); bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (bv != NULL) { if (bv != NULL) {
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
count++; count++;
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} }
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
return count; return count;
} }
@@ -1547,52 +1541,46 @@ sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
/* extract the dn, only show the first rdn */ /* extract the dn, only show the first rdn */
rdn = sudo_ldap_get_first_rdn(ld, entry); rdn = sudo_ldap_get_first_rdn(ld, entry);
if (rdn != NULL) if (rdn != NULL)
lbuf_append(lbuf, _("\nLDAP Role: "), rdn, "\n", NULL); lbuf_append(lbuf, _("\nLDAP Role: %s\n"), rdn);
else else
lbuf_append(lbuf, _("\nLDAP Role: UNKNOWN\n"), NULL); lbuf_append(lbuf, _("\nLDAP Role: UNKNOWN\n"));
if (rdn) if (rdn)
ldap_memfree(rdn); ldap_memfree(rdn);
/* get the RunAsUser Values from the entry */ /* get the RunAsUser Values from the entry */
lbuf_append(lbuf, " RunAsUsers: ", NULL); lbuf_append(lbuf, " RunAsUsers: ");
bv = ldap_get_values_len(ld, entry, "sudoRunAsUser"); bv = ldap_get_values_len(ld, entry, "sudoRunAsUser");
if (bv == NULL) if (bv == NULL)
bv = ldap_get_values_len(ld, entry, "sudoRunAs"); bv = ldap_get_values_len(ld, entry, "sudoRunAs");
if (bv != NULL) { if (bv != NULL) {
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} else } else
lbuf_append(lbuf, def_runas_default, NULL); lbuf_append(lbuf, "%s", def_runas_default);
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
/* get the RunAsGroup Values from the entry */ /* get the RunAsGroup Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup"); bv = ldap_get_values_len(ld, entry, "sudoRunAsGroup");
if (bv != NULL) { if (bv != NULL) {
lbuf_append(lbuf, " RunAsGroups: ", NULL); lbuf_append(lbuf, " RunAsGroups: ");
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
} }
/* get the Option Values from the entry */ /* get the Option Values from the entry */
bv = ldap_get_values_len(ld, entry, "sudoOption"); bv = ldap_get_values_len(ld, entry, "sudoOption");
if (bv != NULL) { if (bv != NULL) {
lbuf_append(lbuf, " Options: ", NULL); lbuf_append(lbuf, " Options: ");
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
if (p != bv) lbuf_append(lbuf, "%s%s", p != bv ? ", " : "", (*p)->bv_val);
lbuf_append(lbuf, ", ", NULL);
lbuf_append(lbuf, (*p)->bv_val, NULL);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
} }
/* /*
@@ -1602,7 +1590,7 @@ sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
bv = ldap_get_values_len(ld, entry, "sudoOrder"); bv = ldap_get_values_len(ld, entry, "sudoOrder");
if (bv != NULL) { if (bv != NULL) {
if (*bv != NULL) { if (*bv != NULL) {
lbuf_append(lbuf, " Order: ", (*bv)->bv_val, "\n", NULL); lbuf_append(lbuf, _(" Order: %s\n"), (*bv)->bv_val);
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);
} }
@@ -1610,9 +1598,9 @@ sudo_ldap_display_entry_long(LDAP *ld, LDAPMessage *entry, struct lbuf *lbuf)
/* Get the command values from the entry. */ /* Get the command values from the entry. */
bv = ldap_get_values_len(ld, entry, "sudoCommand"); bv = ldap_get_values_len(ld, entry, "sudoCommand");
if (bv != NULL) { if (bv != NULL) {
lbuf_append(lbuf, " Commands:\n", NULL); lbuf_append(lbuf, _(" Commands:\n"));
for (p = bv; *p != NULL; p++) { for (p = bv; *p != NULL; p++) {
lbuf_append(lbuf, "\t", (*p)->bv_val, "\n", NULL); lbuf_append(lbuf, "\t%s\n", (*p)->bv_val);
count++; count++;
} }
ldap_value_free_len(bv); ldap_value_free_len(bv);

View File

@@ -266,33 +266,28 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (cs->role) if (cs->role)
lbuf_append(lbuf, "ROLE=", cs->role, " ", NULL); lbuf_append(lbuf, "ROLE=%s ", cs->role);
if (cs->type) if (cs->type)
lbuf_append(lbuf, "TYPE=", cs->type, " ", NULL); lbuf_append(lbuf, "TYPE=%s ", cs->type);
#endif /* HAVE_SELINUX */ #endif /* HAVE_SELINUX */
if (TAG_CHANGED(setenv)) { if (TAG_CHANGED(setenv)) {
lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : lbuf_append(lbuf, cs->tags.setenv ? "SETENV: " : "NOSETENV: ");
"NOSETENV: ", NULL);
tags->setenv = cs->tags.setenv; tags->setenv = cs->tags.setenv;
} }
if (TAG_CHANGED(noexec)) { if (TAG_CHANGED(noexec)) {
lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : lbuf_append(lbuf, cs->tags.noexec ? "NOEXEC: " : "EXEC: ");
"EXEC: ", NULL);
tags->noexec = cs->tags.noexec; tags->noexec = cs->tags.noexec;
} }
if (TAG_CHANGED(nopasswd)) { if (TAG_CHANGED(nopasswd)) {
lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : lbuf_append(lbuf, cs->tags.nopasswd ? "NOPASSWD: " : "PASSWD: ");
"PASSWD: ", NULL);
tags->nopasswd = cs->tags.nopasswd; tags->nopasswd = cs->tags.nopasswd;
} }
if (TAG_CHANGED(log_input)) { if (TAG_CHANGED(log_input)) {
lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " : "NOLOG_INPUT: ");
"NOLOG_INPUT: ", NULL);
tags->log_input = cs->tags.log_input; tags->log_input = cs->tags.log_input;
} }
if (TAG_CHANGED(log_output)) { if (TAG_CHANGED(log_output)) {
lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " : "NOLOG_OUTPUT: ");
"NOLOG_OUTPUT: ", NULL);
tags->log_output = cs->tags.log_output; tags->log_output = cs->tags.log_output;
} }
m = cs->cmnd; m = cs->cmnd;
@@ -318,37 +313,37 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
tags.nopasswd = UNSPEC; tags.nopasswd = UNSPEC;
tags.log_input = UNSPEC; tags.log_input = UNSPEC;
tags.log_output = UNSPEC; tags.log_output = UNSPEC;
lbuf_append(lbuf, " ", NULL); lbuf_append(lbuf, " ");
tq_foreach_fwd(&priv->cmndlist, cs) { tq_foreach_fwd(&priv->cmndlist, cs) {
if (cs != tq_first(&priv->cmndlist)) if (cs != tq_first(&priv->cmndlist))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
lbuf_append(lbuf, "(", NULL); lbuf_append(lbuf, "(");
if (!tq_empty(&cs->runasuserlist)) { if (!tq_empty(&cs->runasuserlist)) {
tq_foreach_fwd(&cs->runasuserlist, m) { tq_foreach_fwd(&cs->runasuserlist, m) {
if (m != tq_first(&cs->runasuserlist)) if (m != tq_first(&cs->runasuserlist))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
print_member(lbuf, m->name, m->type, m->negated, print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS); RUNASALIAS);
} }
} else if (tq_empty(&cs->runasgrouplist)) { } else if (tq_empty(&cs->runasgrouplist)) {
lbuf_append(lbuf, def_runas_default, NULL); lbuf_append(lbuf, "%s", def_runas_default);
} else { } else {
lbuf_append(lbuf, pw->pw_name, NULL); lbuf_append(lbuf, "%s", pw->pw_name);
} }
if (!tq_empty(&cs->runasgrouplist)) { if (!tq_empty(&cs->runasgrouplist)) {
lbuf_append(lbuf, " : ", NULL); lbuf_append(lbuf, " : ");
tq_foreach_fwd(&cs->runasgrouplist, m) { tq_foreach_fwd(&cs->runasgrouplist, m) {
if (m != tq_first(&cs->runasgrouplist)) if (m != tq_first(&cs->runasgrouplist))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
print_member(lbuf, m->name, m->type, m->negated, print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS); RUNASALIAS);
} }
} }
lbuf_append(lbuf, ") ", NULL); lbuf_append(lbuf, ") ");
sudo_file_append_cmnd(cs, &tags, lbuf); sudo_file_append_cmnd(cs, &tags, lbuf);
nfound++; nfound++;
} }
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
} }
return nfound; return nfound;
} }
@@ -371,35 +366,35 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
tags.nopasswd = UNSPEC; tags.nopasswd = UNSPEC;
tags.log_input = UNSPEC; tags.log_input = UNSPEC;
tags.log_output = UNSPEC; tags.log_output = UNSPEC;
lbuf_append(lbuf, _("\nSudoers entry:\n"), NULL); lbuf_append(lbuf, _("\nSudoers entry:\n"));
tq_foreach_fwd(&priv->cmndlist, cs) { tq_foreach_fwd(&priv->cmndlist, cs) {
lbuf_append(lbuf, " ", _("RunAsUsers: "), NULL); lbuf_append(lbuf, _(" RunAsUsers: "));
if (!tq_empty(&cs->runasuserlist)) { if (!tq_empty(&cs->runasuserlist)) {
tq_foreach_fwd(&cs->runasuserlist, m) { tq_foreach_fwd(&cs->runasuserlist, m) {
if (m != tq_first(&cs->runasuserlist)) if (m != tq_first(&cs->runasuserlist))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
print_member(lbuf, m->name, m->type, m->negated, print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS); RUNASALIAS);
} }
} else if (tq_empty(&cs->runasgrouplist)) { } else if (tq_empty(&cs->runasgrouplist)) {
lbuf_append(lbuf, def_runas_default, NULL); lbuf_append(lbuf, "%s", def_runas_default);
} else { } else {
lbuf_append(lbuf, pw->pw_name, NULL); lbuf_append(lbuf, "%s", pw->pw_name);
} }
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
if (!tq_empty(&cs->runasgrouplist)) { if (!tq_empty(&cs->runasgrouplist)) {
lbuf_append(lbuf, " ", _("RunAsGroups: "), NULL); lbuf_append(lbuf, _(" RunAsGroups: "));
tq_foreach_fwd(&cs->runasgrouplist, m) { tq_foreach_fwd(&cs->runasgrouplist, m) {
if (m != tq_first(&cs->runasgrouplist)) if (m != tq_first(&cs->runasgrouplist))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
print_member(lbuf, m->name, m->type, m->negated, print_member(lbuf, m->name, m->type, m->negated,
RUNASALIAS); RUNASALIAS);
} }
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
} }
lbuf_append(lbuf, " ", _("Commands:\n\t"), NULL); lbuf_append(lbuf, _(" Commands:\n\t"));
sudo_file_append_cmnd(cs, &tags, lbuf); sudo_file_append_cmnd(cs, &tags, lbuf);
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
nfound++; nfound++;
} }
} }
@@ -462,18 +457,18 @@ sudo_file_display_defaults(struct sudo_nss *nss, struct passwd *pw,
case DEFAULTS_CMND: case DEFAULTS_CMND:
continue; continue;
} }
lbuf_append(lbuf, prefix, NULL); lbuf_append(lbuf, prefix);
if (d->val != NULL) { if (d->val != NULL) {
lbuf_append(lbuf, d->var, d->op == '+' ? "+=" : lbuf_append(lbuf, "%s%s", d->var, d->op == '+' ? "+=" :
d->op == '-' ? "-=" : "=", NULL); d->op == '-' ? "-=" : "=");
if (strpbrk(d->val, " \t") != NULL) { if (strpbrk(d->val, " \t") != NULL) {
lbuf_append(lbuf, "\"", NULL); lbuf_append(lbuf, "\"");
lbuf_append_quoted(lbuf, "\"", d->val, NULL); lbuf_append_quoted(lbuf, "\"", "%s", d->val);
lbuf_append(lbuf, "\"", NULL); lbuf_append(lbuf, "\"");
} else } else
lbuf_append_quoted(lbuf, SUDOERS_QUOTED, d->val, NULL); lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", d->val);
} else } else
lbuf_append(lbuf, d->op == FALSE ? "!" : "", d->var, NULL); lbuf_append(lbuf, "%s%s", d->op == FALSE ? "!" : "", d->var);
prefix = ", "; prefix = ", ";
nfound++; nfound++;
} }
@@ -541,21 +536,21 @@ display_bound_defaults(int dtype, struct lbuf *lbuf)
if (binding != tq_first(&d->binding)) { if (binding != tq_first(&d->binding)) {
binding = tq_first(&d->binding); binding = tq_first(&d->binding);
if (nfound != 1) if (nfound != 1)
lbuf_append(lbuf, "\n", NULL); lbuf_append(lbuf, "\n");
lbuf_append(lbuf, " Defaults", dsep, NULL); lbuf_append(lbuf, " Defaults%s", dsep);
for (m = binding; m != NULL; m = m->next) { for (m = binding; m != NULL; m = m->next) {
if (m != binding) if (m != binding)
lbuf_append(lbuf, ",", NULL); lbuf_append(lbuf, ",");
print_member(lbuf, m->name, m->type, m->negated, atype); print_member(lbuf, m->name, m->type, m->negated, atype);
lbuf_append(lbuf, " ", NULL); lbuf_append(lbuf, " ");
} }
} else } else
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
if (d->val != NULL) { if (d->val != NULL) {
lbuf_append(lbuf, d->var, d->op == '+' ? "+=" : lbuf_append(lbuf, "%s%s%s", d->var, d->op == '+' ? "+=" :
d->op == '-' ? "-=" : "=", d->val, NULL); d->op == '-' ? "-=" : "=", d->val);
} else } else
lbuf_append(lbuf, d->op == FALSE ? "!" : "", d->var, NULL); lbuf_append(lbuf, "%s%s", d->op == FALSE ? "!" : "", d->var);
} }
return nfound; return nfound;
@@ -619,23 +614,23 @@ _print_member(struct lbuf *lbuf, char *name, int type, int negated,
switch (type) { switch (type) {
case ALL: case ALL:
lbuf_append(lbuf, negated ? "!ALL" : "ALL", NULL); lbuf_append(lbuf, "%sALL", negated ? "!" : "");
break; break;
case COMMAND: case COMMAND:
c = (struct sudo_command *) name; c = (struct sudo_command *) name;
if (negated) if (negated)
lbuf_append(lbuf, "!", NULL); lbuf_append(lbuf, "!");
lbuf_append_quoted(lbuf, SUDOERS_QUOTED, c->cmnd, NULL); lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->cmnd);
if (c->args) { if (c->args) {
lbuf_append(lbuf, " ", NULL); lbuf_append(lbuf, " ");
lbuf_append_quoted(lbuf, SUDOERS_QUOTED, c->args, NULL); lbuf_append_quoted(lbuf, SUDOERS_QUOTED, "%s", c->args);
} }
break; break;
case ALIAS: case ALIAS:
if ((a = alias_find(name, alias_type)) != NULL) { if ((a = alias_find(name, alias_type)) != NULL) {
tq_foreach_fwd(&a->members, m) { tq_foreach_fwd(&a->members, m) {
if (m != tq_first(&a->members)) if (m != tq_first(&a->members))
lbuf_append(lbuf, ", ", NULL); lbuf_append(lbuf, ", ");
_print_member(lbuf, m->name, m->type, _print_member(lbuf, m->name, m->type,
negated ? !m->negated : m->negated, alias_type); negated ? !m->negated : m->negated, alias_type);
} }
@@ -643,7 +638,7 @@ _print_member(struct lbuf *lbuf, char *name, int type, int negated,
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
lbuf_append(lbuf, negated ? "!" : "", name, NULL); lbuf_append(lbuf, "%s%s", negated ? "!" : "", name);
break; break;
} }
} }

View File

@@ -263,33 +263,34 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
lbuf_init(&privs, output, 4, NULL, sudo_user.cols); lbuf_init(&privs, output, 4, NULL, sudo_user.cols);
/* Display defaults from all sources. */ /* Display defaults from all sources. */
lbuf_append(&defs, _("Matching Defaults entries for "), pw->pw_name, lbuf_append(&defs, _("Matching Defaults entries for %s on this host:\n"),
_(" on this host:\n"), NULL); pw->pw_name);
count = 0; count = 0;
tq_foreach_fwd(snl, nss) { tq_foreach_fwd(snl, nss) {
count += nss->display_defaults(nss, pw, &defs); count += nss->display_defaults(nss, pw, &defs);
} }
if (count) if (count)
lbuf_append(&defs, "\n\n", NULL); lbuf_append(&defs, "\n\n");
else else
defs.len = 0; defs.len = 0;
/* Display Runas and Cmnd-specific defaults from all sources. */ /* Display Runas and Cmnd-specific defaults from all sources. */
olen = defs.len; olen = defs.len;
lbuf_append(&defs, _("Runas and Command-specific defaults for "), lbuf_append(&defs, _("Runas and Command-specific defaults for %s:\n"),
pw->pw_name, ":\n", NULL); pw->pw_name);
count = 0; count = 0;
tq_foreach_fwd(snl, nss) { tq_foreach_fwd(snl, nss) {
count += nss->display_bound_defaults(nss, pw, &defs); count += nss->display_bound_defaults(nss, pw, &defs);
} }
if (count) if (count)
lbuf_append(&defs, "\n\n", NULL); lbuf_append(&defs, "\n\n");
else else
defs.len = olen; defs.len = olen;
/* Display privileges from all sources. */ /* Display privileges from all sources. */
lbuf_append(&privs, _("User "), pw->pw_name, lbuf_append(&privs,
_(" may run the following commands on this host:\n"), NULL); _("User %s may run the following commands on this host:\n"),
pw->pw_name);
count = 0; count = 0;
tq_foreach_fwd(snl, nss) { tq_foreach_fwd(snl, nss) {
count += nss->display_privs(nss, pw, &privs); count += nss->display_privs(nss, pw, &privs);

View File

@@ -485,7 +485,7 @@ usage(int fatal)
lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL, lbuf_init(&lbuf, fatal ? usage_err : usage_out, ulen, NULL,
user_details.ts_cols); user_details.ts_cols);
for (i = 0; uvec[i] != NULL; i++) { for (i = 0; uvec[i] != NULL; i++) {
lbuf_append(&lbuf, "usage: ", getprogname(), uvec[i], NULL); lbuf_append(&lbuf, "usage: %s%s", getprogname(), uvec[i]);
lbuf_print(&lbuf); lbuf_print(&lbuf);
} }
lbuf_destroy(&lbuf); lbuf_destroy(&lbuf);
@@ -512,100 +512,74 @@ help(void)
lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols); lbuf_init(&lbuf, usage_out, indent, NULL, user_details.ts_cols);
if (strcmp(pname, "sudoedit") == 0) if (strcmp(pname, "sudoedit") == 0)
lbuf_append(&lbuf, pname, _(" - edit files as another user\n\n"), NULL); lbuf_append(&lbuf, _("%s - edit files as another user\n\n"), pname);
else else
lbuf_append(&lbuf, pname, _(" - execute a command as another user\n\n"), NULL); lbuf_append(&lbuf, _("%s - execute a command as another user\n\n"), pname);
lbuf_print(&lbuf); lbuf_print(&lbuf);
usage(0); usage(0);
lbuf_append(&lbuf, _("\nOptions:\n"), NULL); lbuf_append(&lbuf, _("\nOptions:\n"));
#ifdef HAVE_BSD_AUTH_H #ifdef HAVE_BSD_AUTH_H
lbuf_append(&lbuf, lbuf_append(&lbuf, " -A %s",
" -A ", _("use helper program for password prompting\n"));
_("use helper program for password prompting\n"), NULL);
#endif #endif
lbuf_append(&lbuf, lbuf_append(&lbuf, " -a type %s",
" -a type ", _("use specified BSD authentication type\n"));
_("use specified BSD authentication type\n"), NULL); lbuf_append(&lbuf, " -b %s",
lbuf_append(&lbuf, _("run command in the background\n"));
" -b ", lbuf_append(&lbuf, " -C fd %s",
_("run command in the background\n"), NULL); _("close all file descriptors >= fd\n"));
lbuf_append(&lbuf,
" -C fd ",
_("close all file descriptors >= fd\n"), NULL);
#ifdef HAVE_LOGIN_CAP_H #ifdef HAVE_LOGIN_CAP_H
lbuf_append(&lbuf, lbuf_append(&lbuf, " -c class %s",
" -c class ", _("run command with specified login class\n"));
_("run command with specified login class\n"), NULL);
#endif #endif
lbuf_append(&lbuf, lbuf_append(&lbuf, " -E %s",
" -E ", _("preserve user environment when executing command\n"));
_("preserve user environment when executing command\n"), NULL); lbuf_append(&lbuf, " -e %s",
lbuf_append(&lbuf, _("edit files instead of running a command\n"));
" -e ", lbuf_append(&lbuf, " -g group %s",
_("edit files instead of running a command\n"), NULL); _("execute command as the specified group\n"));
lbuf_append(&lbuf, lbuf_append(&lbuf, " -H %s",
" -g group ", _("set HOME variable to target user's home dir.\n"));
_("execute command as the specified group\n"), NULL); lbuf_append(&lbuf, " -h %s",
lbuf_append(&lbuf, _("display help message and exit\n"));
" -H ", lbuf_append(&lbuf, " -i [command] %s",
_("set HOME variable to target user's home dir.\n"), NULL); _("run a login shell as target user\n"));
lbuf_append(&lbuf, lbuf_append(&lbuf, " -K %s",
" -h ", _("remove timestamp file completely\n"));
_("display help message and exit\n"), NULL); lbuf_append(&lbuf, " -k %s",
lbuf_append(&lbuf, _("invalidate timestamp file\n"));
" -i [command] ", lbuf_append(&lbuf, " -l[l] command %s",
_("run a login shell as target user\n"), NULL); _("list user's available commands\n"));
lbuf_append(&lbuf, lbuf_append(&lbuf, " -n %s",
" -K ", _("non-interactive mode, will not prompt user\n"));
_("remove timestamp file completely\n"), NULL); lbuf_append(&lbuf, " -P %s",
lbuf_append(&lbuf, _("preserve group vector instead of setting to target's\n"));
" -k ", lbuf_append(&lbuf, " -p prompt %s",
_("invalidate timestamp file\n"), NULL); _("use specified password prompt\n"));
lbuf_append(&lbuf,
" -l[l] command ",
_("list user's available commands\n"), NULL);
lbuf_append(&lbuf,
" -n ",
_("non-interactive mode, will not prompt user\n"), NULL);
lbuf_append(&lbuf,
" -P ",
_("preserve group vector instead of setting to target's\n"), NULL);
lbuf_append(&lbuf,
" -p prompt ",
_("use specified password prompt\n"), NULL);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
lbuf_append(&lbuf, lbuf_append(&lbuf, " -r role %s",
" -r role ", _("create SELinux security context with specified role\n"));
_("create SELinux security context with specified role\n"), NULL);
#endif #endif
lbuf_append(&lbuf, " -S %s",
_("read password from standard input\n"));
lbuf_append(&lbuf, lbuf_append(&lbuf,
" -S ", " -s [command] %s", _("run a shell as target user\n"));
_("read password from standard input\n"), NULL);
lbuf_append(&lbuf,
" -s [command] ",
_("run a shell as target user\n"), NULL);
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
lbuf_append(&lbuf, lbuf_append(&lbuf, " -t type %s",
" -t type ", _("create SELinux security context with specified role\n"));
_("create SELinux security context with specified role\n"), NULL);
#endif #endif
lbuf_append(&lbuf, lbuf_append(&lbuf, " -U user %s",
" -U user ", _("when listing, list specified user's privileges\n"));
_("when listing, list specified user's privileges\n"), NULL); lbuf_append(&lbuf, " -u user %s",
lbuf_append(&lbuf, _("run command (or edit file) as specified user\n"));
" -u user ", lbuf_append(&lbuf, " -V %s",
_("run command (or edit file) as specified user\n"), NULL); _("display version information and exit\n"));
lbuf_append(&lbuf, lbuf_append(&lbuf, " -v %s",
" -V ", _("update user's timestamp without running a command\n"));
_("display version information and exit\n"), NULL); lbuf_append(&lbuf, " -- %s",
lbuf_append(&lbuf, _("stop processing command line arguments\n"));
" -v ",
_("update user's timestamp without running a command\n"), NULL);
lbuf_append(&lbuf,
" -- ",
_("stop processing command line arguments\n"), NULL);
lbuf_print(&lbuf); lbuf_print(&lbuf);
lbuf_destroy(&lbuf); lbuf_destroy(&lbuf);
exit(0); exit(0);