die_if_bad_username.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Check user and group names for illegal characters
  4. *
  5. * Copyright (C) 2008 Tito Ragusa <farmatito@tiscali.it>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. #include "libbb.h"
  10. /* To avoid problems, the username should consist only of
  11. * letters, digits, underscores, periods, at signs and dashes,
  12. * and not start with a dash (as defined by IEEE Std 1003.1-2001).
  13. * For compatibility with Samba machine accounts $ is also supported
  14. * at the end of the username.
  15. */
  16. void FAST_FUNC die_if_bad_username(const char *name)
  17. {
  18. const char *start = name;
  19. /* 1st char being dash or dot isn't valid:
  20. * for example, name like ".." can make adduser
  21. * chown "/home/.." recursively - NOT GOOD.
  22. * Name of just a single "$" is also rejected.
  23. */
  24. goto skip;
  25. do {
  26. unsigned char ch;
  27. /* These chars are valid unless they are at the 1st pos: */
  28. if (*name == '-'
  29. || *name == '.'
  30. /* $ is allowed if it's the last char: */
  31. || (*name == '$' && !name[1])
  32. ) {
  33. continue;
  34. }
  35. skip:
  36. ch = *name;
  37. if (ch == '_'
  38. /* || ch == '@' -- we disallow this too. Think about "user@host" */
  39. /* open-coded isalnum: */
  40. || (ch >= '0' && ch <= '9')
  41. || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z')
  42. ) {
  43. continue;
  44. }
  45. bb_error_msg_and_die("illegal character with code %u at position %u",
  46. (unsigned)ch, (unsigned)(name - start));
  47. } while (*++name);
  48. /* The minimum size of the login name is one char or two if
  49. * last char is the '$'. Violations of this are caught above.
  50. * The maximum size of the login name is LOGIN_NAME_MAX
  51. * including the terminating null byte.
  52. */
  53. if (name - start >= LOGIN_NAME_MAX)
  54. bb_error_msg_and_die("name is too long");
  55. }