FreeRDP
sspicli.c
1 
20 #include <winpr/config.h>
21 
22 #include <winpr/assert.h>
23 #include <winpr/sspicli.h>
24 
54 #ifndef _WIN32
55 
56 #include <winpr/crt.h>
57 
58 #ifdef WINPR_HAVE_UNISTD_H
59 #include <unistd.h>
60 #endif
61 
62 #if defined(WINPR_HAVE_GETPWUID_R)
63 #include <sys/types.h>
64 #endif
65 
66 #include <pthread.h>
67 
68 #include <pwd.h>
69 #include <grp.h>
70 
71 #include "../handle/handle.h"
72 
73 #include "../security/security.h"
74 
75 static BOOL LogonUserCloseHandle(HANDLE handle);
76 
77 static BOOL LogonUserIsHandled(HANDLE handle)
78 {
79  return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_ACCESS_TOKEN, FALSE);
80 }
81 
82 static int LogonUserGetFd(HANDLE handle)
83 {
84  WINPR_ACCESS_TOKEN* pLogonUser = (WINPR_ACCESS_TOKEN*)handle;
85 
86  if (!LogonUserIsHandled(handle))
87  return -1;
88 
89  /* TODO: File fd not supported */
90  (void)pLogonUser;
91  return -1;
92 }
93 
94 BOOL LogonUserCloseHandle(HANDLE handle)
95 {
96  WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)handle;
97 
98  if (!handle || !LogonUserIsHandled(handle))
99  return FALSE;
100 
101  free(token->Username);
102  free(token->Domain);
103  free(token);
104  return TRUE;
105 }
106 
107 static HANDLE_OPS ops = { LogonUserIsHandled,
108  LogonUserCloseHandle,
109  LogonUserGetFd,
110  NULL, /* CleanupHandle */
111  NULL,
112  NULL,
113  NULL,
114  NULL,
115  NULL,
116  NULL,
117  NULL,
118  NULL,
119  NULL,
120  NULL,
121  NULL,
122  NULL,
123  NULL,
124  NULL,
125  NULL,
126  NULL,
127  NULL };
128 
129 BOOL LogonUserA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType,
130  DWORD dwLogonProvider, PHANDLE phToken)
131 {
132  if (!lpszUsername)
133  return FALSE;
134 
135  WINPR_ACCESS_TOKEN* token = (WINPR_ACCESS_TOKEN*)calloc(1, sizeof(WINPR_ACCESS_TOKEN));
136 
137  if (!token)
138  return FALSE;
139 
140  WINPR_HANDLE_SET_TYPE_AND_MODE(token, HANDLE_TYPE_ACCESS_TOKEN, WINPR_FD_READ);
141  token->common.ops = &ops;
142  token->Username = _strdup(lpszUsername);
143 
144  if (!token->Username)
145  goto fail;
146 
147  if (lpszDomain)
148  {
149  token->Domain = _strdup(lpszDomain);
150 
151  if (!token->Domain)
152  goto fail;
153  }
154 
155  long buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
156  if (buflen < 0)
157  buflen = 8196;
158 
159  const size_t s = 1ULL + (size_t)buflen;
160  char* buf = (char*)calloc(s, sizeof(char));
161  if (!buf)
162  goto fail;
163 
164  struct passwd pwd = { 0 };
165  struct passwd* pw = NULL;
166  const int rc =
167  getpwnam_r(lpszUsername, &pwd, buf, WINPR_ASSERTING_INT_CAST(size_t, buflen), &pw);
168  free(buf);
169  if ((rc == 0) && pw)
170  {
171  token->UserId = (DWORD)pw->pw_uid;
172  token->GroupId = (DWORD)pw->pw_gid;
173  }
174 
175  *((ULONG_PTR*)phToken) = (ULONG_PTR)token;
176  return TRUE;
177 
178 fail:
179  free(token->Username);
180  free(token->Domain);
181  free(token);
182  return FALSE;
183 }
184 
185 BOOL LogonUserW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
186  DWORD dwLogonProvider, PHANDLE phToken)
187 {
188  return TRUE;
189 }
190 
191 BOOL LogonUserExA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType,
192  DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
193  LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
194 {
195  return TRUE;
196 }
197 
198 BOOL LogonUserExW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
199  DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
200  LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
201 {
202  return TRUE;
203 }
204 
205 BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
206 {
207  WINPR_ASSERT(lpNameBuffer);
208  WINPR_ASSERT(nSize);
209 
210  switch (NameFormat)
211  {
212  case NameSamCompatible:
213 #if defined(WINPR_HAVE_GETPWUID_R)
214  {
215  int rc = 0;
216  struct passwd pwd = { 0 };
217  struct passwd* result = NULL;
218  uid_t uid = getuid();
219 
220  rc = getpwuid_r(uid, &pwd, lpNameBuffer, *nSize, &result);
221  if (rc != 0)
222  return FALSE;
223  if (result == NULL)
224  return FALSE;
225  }
226 #elif defined(WINPR_HAVE_GETLOGIN_R)
227  if (getlogin_r(lpNameBuffer, *nSize) != 0)
228  return FALSE;
229 #else
230  {
231  const char* name = getlogin();
232  if (!name)
233  return FALSE;
234  strncpy(lpNameBuffer, name, strnlen(name, *nSize));
235  }
236 #endif
237  const size_t len = strnlen(lpNameBuffer, *nSize);
238  if (len > UINT32_MAX)
239  return FALSE;
240  *nSize = (ULONG)len;
241  return TRUE;
242 
243  case NameFullyQualifiedDN:
244  case NameDisplay:
245  case NameUniqueId:
246  case NameCanonical:
247  case NameUserPrincipal:
248  case NameCanonicalEx:
249  case NameServicePrincipal:
250  case NameDnsDomain:
251  break;
252 
253  default:
254  break;
255  }
256 
257  return FALSE;
258 }
259 
260 BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
261 {
262  BOOL rc = FALSE;
263  char* name = NULL;
264 
265  WINPR_ASSERT(nSize);
266  WINPR_ASSERT(lpNameBuffer);
267 
268  name = calloc(1, *nSize + 1);
269  if (!name)
270  goto fail;
271 
272  if (!GetUserNameExA(NameFormat, name, nSize))
273  goto fail;
274 
275  const SSIZE_T res = ConvertUtf8ToWChar(name, lpNameBuffer, *nSize);
276  if ((res < 0) || (res >= UINT32_MAX))
277  goto fail;
278 
279  *nSize = (UINT32)res + 1;
280  rc = TRUE;
281 fail:
282  free(name);
283  return rc;
284 }
285 
286 #endif