PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/source3/lib/username.c

http://github.com/ccrisan/samba
C | 196 lines | 104 code | 35 blank | 57 comment | 21 complexity | 1e57f1e33ad6219211a93635f463c1f9 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, LGPL-2.1
  1. /*
  2. Unix SMB/CIFS implementation.
  3. Username handling
  4. Copyright (C) Andrew Tridgell 1992-1998
  5. Copyright (C) Jeremy Allison 1997-2001.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "includes.h"
  18. /* internal functions */
  19. static struct passwd *uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
  20. struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
  21. int N);
  22. static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, int offset,
  23. struct passwd * (*fn) (TALLOC_CTX *mem_ctx, const char *),
  24. int N);
  25. /****************************************************************************
  26. Get a users home directory.
  27. ****************************************************************************/
  28. char *get_user_home_dir(TALLOC_CTX *mem_ctx, const char *user)
  29. {
  30. struct passwd *pass;
  31. char *result;
  32. /* Ensure the user exists. */
  33. pass = Get_Pwnam_alloc(mem_ctx, user);
  34. if (!pass)
  35. return(NULL);
  36. /* Return home directory from struct passwd. */
  37. result = talloc_move(mem_ctx, &pass->pw_dir);
  38. TALLOC_FREE(pass);
  39. return result;
  40. }
  41. /****************************************************************************
  42. * A wrapper for sys_getpwnam(). The following variations are tried:
  43. * - as transmitted
  44. * - in all lower case if this differs from transmitted
  45. * - in all upper case if this differs from transmitted
  46. * - using lp_usernamelevel() for permutations.
  47. ****************************************************************************/
  48. static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx,
  49. const char *user, char *user2)
  50. {
  51. struct passwd *ret = NULL;
  52. if (!user2 || !(*user2))
  53. return(NULL);
  54. if (!user || !(*user))
  55. return(NULL);
  56. /* Try in all lower case first as this is the most
  57. common case on UNIX systems */
  58. strlower_m(user2);
  59. DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2));
  60. ret = getpwnam_alloc(mem_ctx, user2);
  61. if(ret)
  62. goto done;
  63. /* Try as given, if username wasn't originally lowercase */
  64. if(strcmp(user, user2) != 0) {
  65. DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",
  66. user));
  67. ret = getpwnam_alloc(mem_ctx, user);
  68. if(ret)
  69. goto done;
  70. }
  71. /* Try as uppercase, if username wasn't originally uppercase */
  72. strupper_m(user2);
  73. if(strcmp(user, user2) != 0) {
  74. DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",
  75. user2));
  76. ret = getpwnam_alloc(mem_ctx, user2);
  77. if(ret)
  78. goto done;
  79. }
  80. /* Try all combinations up to usernamelevel */
  81. strlower_m(user2);
  82. DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",
  83. lp_usernamelevel(), user2));
  84. ret = uname_string_combinations(user2, mem_ctx, getpwnam_alloc,
  85. lp_usernamelevel());
  86. done:
  87. DEBUG(5,("Get_Pwnam_internals %s find user [%s]!\n",ret ?
  88. "did":"didn't", user));
  89. return ret;
  90. }
  91. /****************************************************************************
  92. Get_Pwnam wrapper without modification.
  93. NOTE: This with NOT modify 'user'!
  94. This will return an allocated structure
  95. ****************************************************************************/
  96. struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user)
  97. {
  98. fstring user2;
  99. struct passwd *ret;
  100. if ( *user == '\0' ) {
  101. DEBUG(10,("Get_Pwnam: empty username!\n"));
  102. return NULL;
  103. }
  104. fstrcpy(user2, user);
  105. DEBUG(5,("Finding user %s\n", user));
  106. ret = Get_Pwnam_internals(mem_ctx, user, user2);
  107. return ret;
  108. }
  109. /* The functions below have been taken from password.c and slightly modified */
  110. /****************************************************************************
  111. Apply a function to upper/lower case combinations
  112. of a string and return true if one of them returns true.
  113. Try all combinations with N uppercase letters.
  114. offset is the first char to try and change (start with 0)
  115. it assumes the string starts lowercased
  116. ****************************************************************************/
  117. static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx,
  118. int offset,
  119. struct passwd *(*fn)(TALLOC_CTX *mem_ctx, const char *),
  120. int N)
  121. {
  122. ssize_t len = (ssize_t)strlen(s);
  123. int i;
  124. struct passwd *ret;
  125. if (N <= 0 || offset >= len)
  126. return(fn(mem_ctx, s));
  127. for (i=offset;i<(len-(N-1));i++) {
  128. char c = s[i];
  129. if (!islower_ascii((int)c))
  130. continue;
  131. s[i] = toupper_ascii(c);
  132. ret = uname_string_combinations2(s, mem_ctx, i+1, fn, N-1);
  133. if(ret)
  134. return(ret);
  135. s[i] = c;
  136. }
  137. return(NULL);
  138. }
  139. /****************************************************************************
  140. Apply a function to upper/lower case combinations
  141. of a string and return true if one of them returns true.
  142. Try all combinations with up to N uppercase letters.
  143. offset is the first char to try and change (start with 0)
  144. it assumes the string starts lowercased
  145. ****************************************************************************/
  146. static struct passwd * uname_string_combinations(char *s, TALLOC_CTX *mem_ctx,
  147. struct passwd * (*fn)(TALLOC_CTX *mem_ctx, const char *),
  148. int N)
  149. {
  150. int n;
  151. struct passwd *ret;
  152. for (n=1;n<=N;n++) {
  153. ret = uname_string_combinations2(s,mem_ctx,0,fn,n);
  154. if(ret)
  155. return(ret);
  156. }
  157. return(NULL);
  158. }