FreeRDP
shell/shell.c
1 
20 #include <winpr/config.h>
21 #include <winpr/cast.h>
22 #include <winpr/shell.h>
23 
31 #ifndef _WIN32
32 
33 #include <winpr/crt.h>
34 
35 #ifdef WINPR_HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 
39 #include <pwd.h>
40 #include <grp.h>
41 
42 #include "../handle/handle.h"
43 
44 #include "../security/security.h"
45 
46 BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize)
47 {
48  struct passwd pwd = { 0 };
49  struct passwd* pw = NULL;
50  WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)hToken;
51 
52  if (!AccessTokenIsValid(hToken))
53  return FALSE;
54 
55  if (!lpcchSize)
56  {
57  SetLastError(ERROR_INVALID_PARAMETER);
58  return FALSE;
59  }
60 
61  long buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
62  if (buflen < 0)
63  buflen = 8196;
64 
65  const size_t s = 1ULL + (size_t)buflen;
66  char* buf = calloc(s, sizeof(char));
67 
68  if (!buf)
69  return FALSE;
70 
71  const int status =
72  getpwnam_r(token->Username, &pwd, buf, WINPR_ASSERTING_INT_CAST(size_t, buflen), &pw);
73 
74  if ((status != 0) || !pw)
75  {
76  SetLastError(ERROR_INVALID_PARAMETER);
77  free(buf);
78  return FALSE;
79  }
80 
81  const size_t cchDirSize = strlen(pw->pw_dir) + 1;
82  if (cchDirSize > UINT32_MAX)
83  {
84  SetLastError(ERROR_INVALID_PARAMETER);
85  free(buf);
86  return FALSE;
87  }
88 
89  if (!lpProfileDir || (*lpcchSize < cchDirSize))
90  {
91  *lpcchSize = (UINT32)cchDirSize;
92  SetLastError(ERROR_INSUFFICIENT_BUFFER);
93  free(buf);
94  return FALSE;
95  }
96 
97  ZeroMemory(lpProfileDir, *lpcchSize);
98  (void)sprintf_s(lpProfileDir, *lpcchSize, "%s", pw->pw_dir);
99  *lpcchSize = (UINT32)cchDirSize;
100  free(buf);
101  return TRUE;
102 }
103 
104 BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize)
105 {
106  BOOL bStatus = 0;
107  DWORD cchSizeA = 0;
108  LPSTR lpProfileDirA = NULL;
109 
110  if (!lpcchSize)
111  {
112  SetLastError(ERROR_INVALID_PARAMETER);
113  return FALSE;
114  }
115 
116  cchSizeA = *lpcchSize;
117  lpProfileDirA = NULL;
118 
119  if (lpProfileDir)
120  {
121  lpProfileDirA = (LPSTR)malloc(cchSizeA);
122 
123  if (lpProfileDirA == NULL)
124  {
125  SetLastError(ERROR_OUTOFMEMORY);
126  return FALSE;
127  }
128  }
129 
130  bStatus = GetUserProfileDirectoryA(hToken, lpProfileDirA, &cchSizeA);
131 
132  if (bStatus)
133  {
134  SSIZE_T size = ConvertUtf8NToWChar(lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize);
135  bStatus = size >= 0;
136  }
137 
138  if (lpProfileDirA)
139  {
140  free(lpProfileDirA);
141  }
142 
143  *lpcchSize = cchSizeA;
144  return bStatus;
145 }
146 
147 #endif