FreeRDP
Loading...
Searching...
No Matches
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
46BOOL 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
104BOOL 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