Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. sysdb.c
  5. Abstract:
  6. Client side of system database (password and group) access routines.
  7. Author:
  8. Matthew Bradburn (mattbr) 04-Mar-1992
  9. Revision History:
  10. --*/
  11. #include <unistd.h>
  12. #include <pwd.h>
  13. #include <grp.h>
  14. #include <stdio.h>
  15. #include "psxdll.h"
  16. extern PVOID PsxPortMemoryBase;
  17. static char pwbuf[ARG_MAX];
  18. static char grbuf[ARG_MAX];
  19. struct passwd *
  20. __cdecl
  21. getpwuid(uid_t uid)
  22. {
  23. PSX_API_MSG m;
  24. PPSX_GETPWUID_MSG args;
  25. NTSTATUS Status;
  26. struct passwd *tmpbuf;
  27. args = &m.u.GetPwUid;
  28. PSX_FORMAT_API_MSG(m, PsxGetPwUidApi, sizeof(*args));
  29. args->Uid = uid;
  30. args->PwBuf = RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
  31. ASSERT(args->PwBuf != NULL);
  32. args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf +
  33. PsxPortMemoryRemoteDelta);
  34. Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  35. (PPORT_MESSAGE)&m);
  36. args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
  37. PsxPortMemoryRemoteDelta);
  38. if (0 != m.Error) {
  39. RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
  40. return NULL;
  41. }
  42. (void)memcpy(pwbuf, args->PwBuf, args->Length);
  43. RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
  44. tmpbuf = (struct passwd *)pwbuf;
  45. tmpbuf->pw_name += (ULONG_PTR)tmpbuf;
  46. tmpbuf->pw_dir += (ULONG_PTR)tmpbuf;
  47. tmpbuf->pw_shell += (ULONG_PTR)tmpbuf;
  48. return tmpbuf;
  49. }
  50. struct passwd *
  51. __cdecl
  52. getpwnam(const char *name)
  53. {
  54. PSX_API_MSG m;
  55. PPSX_GETPWNAM_MSG args;
  56. NTSTATUS Status;
  57. struct passwd *tmpbuf;
  58. args = &m.u.GetPwNam;
  59. PSX_FORMAT_API_MSG(m, PsxGetPwNamApi, sizeof(*args));
  60. if ('\0' == *name) {
  61. return NULL;
  62. }
  63. args->Name = (PCHAR)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
  64. if (! args->Name) {
  65. errno = ENOMEM;
  66. return NULL;
  67. }
  68. strcpy(args->Name,name);
  69. args->Name += PsxPortMemoryRemoteDelta;
  70. args->PwBuf = (struct passwd *)(args->Name + strlen(name) + 1);
  71. //
  72. // Make sure buffer is properly aligned.
  73. //
  74. while ((ULONG_PTR)args->PwBuf & 0x3)
  75. args->PwBuf = (PVOID)((ULONG_PTR)args->PwBuf + 1);
  76. Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  77. (PPORT_MESSAGE)&m);
  78. args->Name = args->Name - PsxPortMemoryRemoteDelta;
  79. args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
  80. PsxPortMemoryRemoteDelta);
  81. if (0 != m.Error) {
  82. RtlFreeHeap(PdxPortHeap, 0, args->Name);
  83. return NULL;
  84. }
  85. (void)memcpy(pwbuf, args->PwBuf, args->Length);
  86. RtlFreeHeap(PdxPortHeap, 0, args->Name);
  87. tmpbuf = (struct passwd *)pwbuf;
  88. tmpbuf->pw_name += (ULONG_PTR)tmpbuf;
  89. tmpbuf->pw_dir += (ULONG_PTR)tmpbuf;
  90. tmpbuf->pw_shell += (ULONG_PTR)tmpbuf;
  91. return tmpbuf;
  92. }
  93. struct group *
  94. __cdecl
  95. getgrgid(gid_t gid)
  96. {
  97. PSX_API_MSG m;
  98. PPSX_GETGRGID_MSG args;
  99. NTSTATUS Status;
  100. struct group *tmpbuf;
  101. char **ppch;
  102. args = &m.u.GetGrGid;
  103. PSX_FORMAT_API_MSG(m, PsxGetGrGidApi, sizeof(*args));
  104. args->Gid = gid;
  105. args->GrBuf = RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
  106. if (NULL == args->GrBuf) {
  107. errno = ENOMEM;
  108. return NULL;
  109. }
  110. args->GrBuf = (struct group *)((PCHAR)args->GrBuf +
  111. PsxPortMemoryRemoteDelta);
  112. Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  113. (PPORT_MESSAGE)&m);
  114. args->GrBuf = (struct group *)((PCHAR)args->GrBuf -
  115. PsxPortMemoryRemoteDelta);
  116. if (0 != m.Error) {
  117. RtlFreeHeap(PdxPortHeap, 0, args->GrBuf);
  118. return NULL;
  119. }
  120. (void)memcpy(grbuf, args->GrBuf, args->Length);
  121. RtlFreeHeap(PdxPortHeap, 0, args->GrBuf);
  122. tmpbuf = (void *)grbuf;
  123. tmpbuf->gr_name = (PCHAR)((ULONG_PTR)grbuf + (ULONG_PTR)tmpbuf->gr_name);
  124. tmpbuf->gr_mem = (PCHAR *)((ULONG_PTR)grbuf + (ULONG_PTR)tmpbuf->gr_mem);
  125. for (ppch = tmpbuf->gr_mem; NULL != *ppch; ++ppch) {
  126. *ppch = (PCHAR)((ULONG_PTR)grbuf + (ULONG_PTR)*ppch);
  127. }
  128. return tmpbuf;
  129. }
  130. struct group *
  131. __cdecl
  132. getgrnam(const char *name)
  133. {
  134. PSX_API_MSG m;
  135. PPSX_GETGRNAM_MSG args;
  136. NTSTATUS Status;
  137. struct group *tmpbuf;
  138. char **ppch;
  139. args = &m.u.GetGrNam;
  140. PSX_FORMAT_API_MSG(m, PsxGetGrNamApi, sizeof(*args));
  141. if ('\0' == *name) {
  142. //
  143. // We need to take special care of this case, because
  144. // SAM will find a match for the null name.
  145. //
  146. return NULL;
  147. }
  148. args->Name = (PCHAR)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
  149. if (! args->Name) {
  150. errno = ENOMEM;
  151. return NULL;
  152. }
  153. strcpy(args->Name,name);
  154. args->Name += PsxPortMemoryRemoteDelta;
  155. args->GrBuf = (struct group *)(args->Name + strlen(name) + 1);
  156. //
  157. // Make sure buffer is properly aligned.
  158. //
  159. while ((ULONG_PTR)args->GrBuf & 0x3)
  160. args->GrBuf = (PVOID)((ULONG_PTR)args->GrBuf + 1);
  161. Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  162. (PPORT_MESSAGE)&m);
  163. args->Name = args->Name - PsxPortMemoryRemoteDelta;
  164. args->GrBuf = (struct group *)((PCHAR)args->GrBuf -
  165. PsxPortMemoryRemoteDelta);
  166. if (0 != m.Error) {
  167. RtlFreeHeap(PdxPortHeap, 0, args->Name);
  168. return NULL;
  169. }
  170. (void)memcpy(grbuf, args->GrBuf, args->Length);
  171. tmpbuf = (void *)grbuf;
  172. tmpbuf->gr_name = (PCHAR)((ULONG_PTR)grbuf + (ULONG_PTR)tmpbuf->gr_name);
  173. tmpbuf->gr_mem = (PCHAR *)((ULONG_PTR)grbuf + (ULONG_PTR)tmpbuf->gr_mem);
  174. for (ppch = tmpbuf->gr_mem; NULL != *ppch; ++ppch) {
  175. *ppch = (PCHAR)((ULONG_PTR)grbuf + (ULONG_PTR)*ppch);
  176. }
  177. RtlFreeHeap(PdxPortHeap, 0, (PVOID)args->Name);
  178. return tmpbuf;
  179. }
  180. char *
  181. __cdecl
  182. getlogin(void)
  183. {
  184. static char name[32];
  185. PSX_API_MSG m;
  186. PPSX_GETPWUID_MSG args;
  187. NTSTATUS Status;
  188. //
  189. // We just do the equivalent of getpwuid(getuid()) and then
  190. // throw away everything but the name.
  191. //
  192. //
  193. // XXX.mjb: do I need to use a name outside the POSIX namespace
  194. // for this? Like, what happens if the user has re-defined getuid()?
  195. //
  196. args = &m.u.GetPwUid;
  197. PSX_FORMAT_API_MSG(m, PsxGetPwUidApi, sizeof(*args));
  198. args->Uid = getuid();
  199. args->PwBuf = (struct passwd *)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
  200. ASSERT(args->PwBuf != NULL);
  201. args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf +
  202. PsxPortMemoryRemoteDelta);
  203. Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
  204. (PPORT_MESSAGE)&m);
  205. args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
  206. PsxPortMemoryRemoteDelta);
  207. if (0 != m.Error) {
  208. RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
  209. return NULL;
  210. }
  211. strcpy(name, (PCHAR)((ULONG_PTR)(args->PwBuf->pw_name) + (ULONG_PTR)args->PwBuf));
  212. RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
  213. return name;
  214. }
  215. #ifndef L_cuserid
  216. #define L_cuserid 32
  217. #endif
  218. char *
  219. __cdecl
  220. cuserid(char *s)
  221. {
  222. static char ReturnSpace[ L_cuserid ];
  223. struct passwd *PassWd;
  224. char *Dest;
  225. PassWd = getpwuid( getuid() );
  226. if( PassWd == NULL ) {
  227. *s = '\0';
  228. return( ( s == NULL ) ? NULL : s );
  229. } else {
  230. Dest = ( ( s == NULL ) ? ReturnSpace : s );
  231. strncpy( Dest, PassWd->pw_name, L_cuserid - 1 );
  232. Dest[ L_cuserid - 1 ] = '\0';
  233. return Dest;
  234. }
  235. }