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 = getpwnam_r(lpszUsername, &pwd, buf, buflen, &pw);
167  free(buf);
168  if ((rc == 0) && pw)
169  {
170  token->UserId = (DWORD)pw->pw_uid;
171  token->GroupId = (DWORD)pw->pw_gid;
172  }
173 
174  *((ULONG_PTR*)phToken) = (ULONG_PTR)token;
175  return TRUE;
176 
177 fail:
178  free(token->Username);
179  free(token->Domain);
180  free(token);
181  return FALSE;
182 }
183 
184 BOOL LogonUserW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
185  DWORD dwLogonProvider, PHANDLE phToken)
186 {
187  return TRUE;
188 }
189 
190 BOOL LogonUserExA(LPCSTR lpszUsername, LPCSTR lpszDomain, LPCSTR lpszPassword, DWORD dwLogonType,
191  DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
192  LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
193 {
194  return TRUE;
195 }
196 
197 BOOL LogonUserExW(LPCWSTR lpszUsername, LPCWSTR lpszDomain, LPCWSTR lpszPassword, DWORD dwLogonType,
198  DWORD dwLogonProvider, PHANDLE phToken, PSID* ppLogonSid, PVOID* ppProfileBuffer,
199  LPDWORD pdwProfileLength, PQUOTA_LIMITS pQuotaLimits)
200 {
201  return TRUE;
202 }
203 
204 BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
205 {
206  WINPR_ASSERT(lpNameBuffer);
207  WINPR_ASSERT(nSize);
208 
209  switch (NameFormat)
210  {
211  case NameSamCompatible:
212 #if defined(WINPR_HAVE_GETPWUID_R)
213  {
214  int rc = 0;
215  struct passwd pwd = { 0 };
216  struct passwd* result = NULL;
217  uid_t uid = getuid();
218 
219  rc = getpwuid_r(uid, &pwd, lpNameBuffer, *nSize, &result);
220  if (rc != 0)
221  return FALSE;
222  if (result == NULL)
223  return FALSE;
224  }
225 #elif defined(WINPR_HAVE_GETLOGIN_R)
226  if (getlogin_r(lpNameBuffer, *nSize) != 0)
227  return FALSE;
228 #else
229  {
230  const char* name = getlogin();
231  if (!name)
232  return FALSE;
233  strncpy(lpNameBuffer, name, strnlen(name, *nSize));
234  }
235 #endif
236  const size_t len = strnlen(lpNameBuffer, *nSize);
237  if (len > UINT32_MAX)
238  return FALSE;
239  *nSize = (ULONG)len;
240  return TRUE;
241 
242  case NameFullyQualifiedDN:
243  case NameDisplay:
244  case NameUniqueId:
245  case NameCanonical:
246  case NameUserPrincipal:
247  case NameCanonicalEx:
248  case NameServicePrincipal:
249  case NameDnsDomain:
250  break;
251 
252  default:
253  break;
254  }
255 
256  return FALSE;
257 }
258 
259 BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
260 {
261  BOOL rc = FALSE;
262  char* name = NULL;
263 
264  WINPR_ASSERT(nSize);
265  WINPR_ASSERT(lpNameBuffer);
266 
267  name = calloc(1, *nSize + 1);
268  if (!name)
269  goto fail;
270 
271  if (!GetUserNameExA(NameFormat, name, nSize))
272  goto fail;
273 
274  const SSIZE_T res = ConvertUtf8ToWChar(name, lpNameBuffer, *nSize);
275  if ((res < 0) || (res >= UINT32_MAX))
276  goto fail;
277 
278  *nSize = (UINT32)res + 1;
279  rc = TRUE;
280 fail:
281  free(name);
282  return rc;
283 }
284 
285 #endif