ReactOS  0.4.14-dev-49-gfb4591c
cred.c
Go to the documentation of this file.
1 /*
2  * Credential Management APIs
3  *
4  * Copyright 2007 Robert Shearman for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #ifdef __REACTOS__
22 #include <advapi32.h>
23 
24 #include <wincred.h>
25 #else
26 #include <stdarg.h>
27 #include <time.h>
28 #include <limits.h>
29 
30 #ifdef __APPLE__
31 # include <Security/SecKeychain.h>
32 # include <Security/SecKeychainItem.h>
33 # include <Security/SecKeychainSearch.h>
34 #endif
35 
36 #include "windef.h"
37 #include "winbase.h"
38 #include "winreg.h"
39 #include "wincred.h"
40 #include "winternl.h"
41 
42 #include "crypt.h"
43 
44 #include "wine/unicode.h"
45 #include "wine/debug.h"
46 
47 #include "advapi32_misc.h"
48 #endif /* __REACTOS__ */
49 
51 
52 /* the size of the ARC4 key used to encrypt the password data */
53 #define KEY_SIZE 8
54 
55 static const WCHAR wszCredentialManagerKey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
56  'C','r','e','d','e','n','t','i','a','l',' ','M','a','n','a','g','e','r',0};
57 static const WCHAR wszEncryptionKeyValue[] = {'E','n','c','r','y','p','t','i','o','n','K','e','y',0};
58 
59 static const WCHAR wszFlagsValue[] = {'F','l','a','g','s',0};
60 static const WCHAR wszTypeValue[] = {'T','y','p','e',0};
61 static const WCHAR wszCommentValue[] = {'C','o','m','m','e','n','t',0};
62 static const WCHAR wszLastWrittenValue[] = {'L','a','s','t','W','r','i','t','t','e','n',0};
63 static const WCHAR wszPersistValue[] = {'P','e','r','s','i','s','t',0};
64 static const WCHAR wszTargetAliasValue[] = {'T','a','r','g','e','t','A','l','i','a','s',0};
65 static const WCHAR wszUserNameValue[] = {'U','s','e','r','N','a','m','e',0};
66 static const WCHAR wszPasswordValue[] = {'P','a','s','s','w','o','r','d',0};
67 
68 static DWORD read_credential_blob(HKEY hkey, const BYTE key_data[KEY_SIZE],
69  LPBYTE credential_blob,
70  DWORD *credential_blob_size)
71 {
72  DWORD ret;
73  DWORD type;
74 
75  *credential_blob_size = 0;
76  ret = RegQueryValueExW(hkey, wszPasswordValue, 0, &type, NULL, credential_blob_size);
77  if (ret != ERROR_SUCCESS)
78  return ret;
79  else if (type != REG_BINARY)
81  if (credential_blob)
82  {
83  struct ustring data;
84  struct ustring key;
85 
86  ret = RegQueryValueExW(hkey, wszPasswordValue, 0, &type, credential_blob,
87  credential_blob_size);
88  if (ret != ERROR_SUCCESS)
89  return ret;
90  else if (type != REG_BINARY)
92 
93  key.Length = key.MaximumLength = KEY_SIZE;
94  key.Buffer = (unsigned char *)key_data;
95 
96  data.Length = data.MaximumLength = *credential_blob_size;
97  data.Buffer = credential_blob;
99  }
100  return ERROR_SUCCESS;
101 }
102 
104  const BYTE key_data[KEY_SIZE],
105  char *buffer, DWORD *len)
106 {
107  DWORD type;
108  DWORD ret;
109  DWORD count;
110 
111  ret = RegQueryValueExW(hkey, NULL, 0, &type, NULL, &count);
112  if (ret != ERROR_SUCCESS)
113  return ret;
114  else if (type != REG_SZ)
115  return ERROR_REGISTRY_CORRUPT;
116  *len += count;
117  if (credential)
118  {
119  credential->TargetName = (LPWSTR)buffer;
120  ret = RegQueryValueExW(hkey, NULL, 0, &type, (LPVOID)credential->TargetName,
121  &count);
122 #ifdef __REACTOS__
123  if (ret != ERROR_SUCCESS)
124  return ret;
125  else if (type != REG_SZ)
126  return ERROR_REGISTRY_CORRUPT;
127 #else
128  if (ret != ERROR_SUCCESS || type != REG_SZ) return ret;
129 #endif
130  buffer += count;
131  }
132 
134 #ifdef __REACTOS__
135  if (ret != ERROR_FILE_NOT_FOUND)
136  {
137  if (ret != ERROR_SUCCESS)
138  return ret;
139  else if (type != REG_SZ)
140  return ERROR_REGISTRY_CORRUPT;
141  *len += count;
142  }
143 #else
145  return ret;
146  else if (type != REG_SZ)
147  return ERROR_REGISTRY_CORRUPT;
148  *len += count;
149 #endif
150  if (credential)
151  {
152  credential->Comment = (LPWSTR)buffer;
153  ret = RegQueryValueExW(hkey, wszCommentValue, 0, &type, (LPVOID)credential->Comment,
154  &count);
155  if (ret == ERROR_FILE_NOT_FOUND)
156  credential->Comment = NULL;
157  else if (ret != ERROR_SUCCESS)
158  return ret;
159  else if (type != REG_SZ)
160  return ERROR_REGISTRY_CORRUPT;
161  else
162  buffer += count;
163  }
164 
166 #ifdef __REACTOS__
167  if (ret != ERROR_FILE_NOT_FOUND)
168  {
169  if (ret != ERROR_SUCCESS)
170  return ret;
171  else if (type != REG_SZ)
172  return ERROR_REGISTRY_CORRUPT;
173  *len += count;
174  }
175 #else
177  return ret;
178  else if (type != REG_SZ)
179  return ERROR_REGISTRY_CORRUPT;
180  *len += count;
181 #endif
182  if (credential)
183  {
184  credential->TargetAlias = (LPWSTR)buffer;
185  ret = RegQueryValueExW(hkey, wszTargetAliasValue, 0, &type, (LPVOID)credential->TargetAlias,
186  &count);
187  if (ret == ERROR_FILE_NOT_FOUND)
188  credential->TargetAlias = NULL;
189  else if (ret != ERROR_SUCCESS)
190  return ret;
191  else if (type != REG_SZ)
192  return ERROR_REGISTRY_CORRUPT;
193  else
194  buffer += count;
195  }
196 
198 #ifdef __REACTOS__
199  if (ret != ERROR_FILE_NOT_FOUND)
200  {
201  if (ret != ERROR_SUCCESS)
202  return ret;
203  else if (type != REG_SZ)
204  return ERROR_REGISTRY_CORRUPT;
205  *len += count;
206  }
207 #else
209  return ret;
210  else if (type != REG_SZ)
211  return ERROR_REGISTRY_CORRUPT;
212  *len += count;
213 #endif
214  if (credential)
215  {
216  credential->UserName = (LPWSTR)buffer;
217  ret = RegQueryValueExW(hkey, wszUserNameValue, 0, &type, (LPVOID)credential->UserName,
218  &count);
219  if (ret == ERROR_FILE_NOT_FOUND)
220  credential->UserName = NULL;
221  else if (ret != ERROR_SUCCESS)
222  return ret;
223  else if (type != REG_SZ)
224  return ERROR_REGISTRY_CORRUPT;
225  else
226  buffer += count;
227  }
228 
229  ret = read_credential_blob(hkey, key_data, NULL, &count);
230 #ifdef __REACTOS__
231  if (ret != ERROR_FILE_NOT_FOUND)
232  {
233  if (ret != ERROR_SUCCESS)
234  return ret;
235  *len += count;
236  }
237 #else
239  return ret;
240  *len += count;
241 #endif
242  if (credential)
243  {
244  credential->CredentialBlob = (LPBYTE)buffer;
245  ret = read_credential_blob(hkey, key_data, credential->CredentialBlob, &count);
246  if (ret == ERROR_FILE_NOT_FOUND)
247  credential->CredentialBlob = NULL;
248  else if (ret != ERROR_SUCCESS)
249  return ret;
250  credential->CredentialBlobSize = count;
251  }
252 
253  /* FIXME: Attributes */
254  if (credential)
255  {
256  credential->AttributeCount = 0;
257  credential->Attributes = NULL;
258  }
259 
260  if (!credential) return ERROR_SUCCESS;
261 
262  count = sizeof(credential->Flags);
263  ret = RegQueryValueExW(hkey, wszFlagsValue, NULL, &type, (LPVOID)&credential->Flags,
264  &count);
265  if (ret != ERROR_SUCCESS)
266  return ret;
267  else if (type != REG_DWORD)
268  return ERROR_REGISTRY_CORRUPT;
269  count = sizeof(credential->Type);
270  ret = RegQueryValueExW(hkey, wszTypeValue, NULL, &type, (LPVOID)&credential->Type,
271  &count);
272  if (ret != ERROR_SUCCESS)
273  return ret;
274  else if (type != REG_DWORD)
275  return ERROR_REGISTRY_CORRUPT;
276 
277  count = sizeof(credential->LastWritten);
279  &count);
280  if (ret != ERROR_SUCCESS)
281  return ret;
282  else if (type != REG_BINARY)
283  return ERROR_REGISTRY_CORRUPT;
284  count = sizeof(credential->Persist);
285  ret = RegQueryValueExW(hkey, wszPersistValue, NULL, &type, (LPVOID)&credential->Persist,
286  &count);
287  if (ret == ERROR_SUCCESS && type != REG_DWORD)
288  return ERROR_REGISTRY_CORRUPT;
289  return ret;
290 }
291 
292 #ifdef __APPLE__
293 static DWORD mac_read_credential_from_item(SecKeychainItemRef item, BOOL require_password,
294  PCREDENTIALW credential, char *buffer,
295  DWORD *len)
296 {
297  int status;
298  UInt32 i, cred_blob_len;
299  void *cred_blob;
300  WCHAR *user = NULL;
301  BOOL user_name_present = FALSE;
302  SecKeychainAttributeInfo info;
303  SecKeychainAttributeList *attr_list;
304  UInt32 info_tags[] = { kSecServiceItemAttr, kSecAccountItemAttr,
305  kSecCommentItemAttr, kSecCreationDateItemAttr };
306  info.count = sizeof(info_tags)/sizeof(info_tags[0]);
307  info.tag = info_tags;
308  info.format = NULL;
309  status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, &cred_blob_len, &cred_blob);
310  if (status == errSecAuthFailed && !require_password)
311  {
312  cred_blob_len = 0;
313  cred_blob = NULL;
314  status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, &cred_blob_len, NULL);
315  }
316  if (status != noErr)
317  {
318  WARN("SecKeychainItemCopyAttributesAndData returned status %d\n", status);
319  return ERROR_NOT_FOUND;
320  }
321 
322  for (i = 0; i < attr_list->count; i++)
323  if (attr_list->attr[i].tag == kSecAccountItemAttr && attr_list->attr[i].data)
324  {
325  user_name_present = TRUE;
326  break;
327  }
328  if (!user_name_present)
329  {
330  WARN("no kSecAccountItemAttr for item\n");
331  SecKeychainItemFreeAttributesAndData(attr_list, cred_blob);
332  return ERROR_NOT_FOUND;
333  }
334 
335  if (buffer)
336  {
337  credential->Flags = 0;
338  credential->Type = CRED_TYPE_DOMAIN_PASSWORD;
339  credential->TargetName = NULL;
340  credential->Comment = NULL;
341  memset(&credential->LastWritten, 0, sizeof(credential->LastWritten));
342  credential->CredentialBlobSize = 0;
343  credential->CredentialBlob = NULL;
344  credential->Persist = CRED_PERSIST_LOCAL_MACHINE;
345  credential->AttributeCount = 0;
346  credential->Attributes = NULL;
347  credential->TargetAlias = NULL;
348  credential->UserName = NULL;
349  }
350  for (i = 0; i < attr_list->count; i++)
351  {
352  switch (attr_list->attr[i].tag)
353  {
354  case kSecServiceItemAttr:
355  TRACE("kSecServiceItemAttr: %.*s\n", (int)attr_list->attr[i].length,
356  (char *)attr_list->attr[i].data);
357  if (!attr_list->attr[i].data) continue;
358  if (buffer)
359  {
360  INT str_len;
361  credential->TargetName = (LPWSTR)buffer;
362  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
363  attr_list->attr[i].length, (LPWSTR)buffer, 0xffff);
364  credential->TargetName[str_len] = '\0';
365  buffer += (str_len + 1) * sizeof(WCHAR);
366  *len += (str_len + 1) * sizeof(WCHAR);
367  }
368  else
369  {
370  INT str_len;
371  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
372  attr_list->attr[i].length, NULL, 0);
373  *len += (str_len + 1) * sizeof(WCHAR);
374  }
375  break;
376  case kSecAccountItemAttr:
377  {
378  INT str_len;
379  TRACE("kSecAccountItemAttr: %.*s\n", (int)attr_list->attr[i].length,
380  (char *)attr_list->attr[i].data);
381  if (!attr_list->attr[i].data) continue;
382  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
383  attr_list->attr[i].length, NULL, 0);
384  user = heap_alloc((str_len + 1) * sizeof(WCHAR));
385  MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
386  attr_list->attr[i].length, user, str_len);
387  user[str_len] = '\0';
388  break;
389  }
390  case kSecCommentItemAttr:
391  TRACE("kSecCommentItemAttr: %.*s\n", (int)attr_list->attr[i].length,
392  (char *)attr_list->attr[i].data);
393  if (!attr_list->attr[i].data) continue;
394  if (buffer)
395  {
396  INT str_len;
397  credential->Comment = (LPWSTR)buffer;
398  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
399  attr_list->attr[i].length, (LPWSTR)buffer, 0xffff);
400  credential->Comment[str_len] = '\0';
401  buffer += (str_len + 1) * sizeof(WCHAR);
402  *len += (str_len + 1) * sizeof(WCHAR);
403  }
404  else
405  {
406  INT str_len;
407  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[i].data,
408  attr_list->attr[i].length, NULL, 0);
409  *len += (str_len + 1) * sizeof(WCHAR);
410  }
411  break;
412  case kSecCreationDateItemAttr:
413  TRACE("kSecCreationDateItemAttr: %.*s\n", (int)attr_list->attr[i].length,
414  (char *)attr_list->attr[i].data);
415  if (!attr_list->attr[i].data) continue;
416  if (buffer)
417  {
418  LARGE_INTEGER win_time;
419  struct tm tm;
420  time_t time;
421  memset(&tm, 0, sizeof(tm));
422  strptime(attr_list->attr[i].data, "%Y%m%d%H%M%SZ", &tm);
423  time = mktime(&tm);
424  RtlSecondsSince1970ToTime(time, &win_time);
425  credential->LastWritten.dwLowDateTime = win_time.u.LowPart;
426  credential->LastWritten.dwHighDateTime = win_time.u.HighPart;
427  }
428  break;
429  default:
430  FIXME("unhandled attribute %u\n", (unsigned)attr_list->attr[i].tag);
431  break;
432  }
433  }
434 
435  if (user)
436  {
437  INT str_len;
438  if (buffer)
439  credential->UserName = (LPWSTR)buffer;
440  str_len = strlenW(user);
441  *len += (str_len + 1) * sizeof(WCHAR);
442  if (buffer)
443  {
444  memcpy(buffer, user, (str_len + 1) * sizeof(WCHAR));
445  buffer += (str_len + 1) * sizeof(WCHAR);
446  TRACE("UserName = %s\n", debugstr_w(credential->UserName));
447  }
448  }
449  heap_free(user);
450 
451  if (cred_blob)
452  {
453  if (buffer)
454  {
455  INT str_len;
456  credential->CredentialBlob = (BYTE *)buffer;
457  str_len = MultiByteToWideChar(CP_UTF8, 0, cred_blob, cred_blob_len,
458  (LPWSTR)buffer, 0xffff);
459  credential->CredentialBlobSize = str_len * sizeof(WCHAR);
460  *len += str_len * sizeof(WCHAR);
461  }
462  else
463  {
464  INT str_len;
465  str_len = MultiByteToWideChar(CP_UTF8, 0, cred_blob, cred_blob_len,
466  NULL, 0);
467  *len += str_len * sizeof(WCHAR);
468  }
469  }
470  SecKeychainItemFreeAttributesAndData(attr_list, cred_blob);
471  return ERROR_SUCCESS;
472 }
473 #endif
474 
475 static DWORD write_credential_blob(HKEY hkey, LPCWSTR target_name, DWORD type,
476  const BYTE key_data[KEY_SIZE],
477  const BYTE *credential_blob, DWORD credential_blob_size)
478 {
479  LPBYTE encrypted_credential_blob;
480  struct ustring data;
481  struct ustring key;
482  DWORD ret;
483 
484  key.Length = key.MaximumLength = KEY_SIZE;
485  key.Buffer = (unsigned char *)key_data;
486 
487  encrypted_credential_blob = heap_alloc(credential_blob_size);
488  if (!encrypted_credential_blob) return ERROR_OUTOFMEMORY;
489 
490  memcpy(encrypted_credential_blob, credential_blob, credential_blob_size);
491  data.Length = data.MaximumLength = credential_blob_size;
492  data.Buffer = encrypted_credential_blob;
494 
495  ret = RegSetValueExW(hkey, wszPasswordValue, 0, REG_BINARY, encrypted_credential_blob, credential_blob_size);
496  heap_free(encrypted_credential_blob);
497 
498  return ret;
499 }
500 
501 static DWORD registry_write_credential(HKEY hkey, const CREDENTIALW *credential,
502  const BYTE key_data[KEY_SIZE], BOOL preserve_blob)
503 {
504  DWORD ret;
505  FILETIME LastWritten;
506 
507  GetSystemTimeAsFileTime(&LastWritten);
508 
509  ret = RegSetValueExW(hkey, wszFlagsValue, 0, REG_DWORD, (const BYTE*)&credential->Flags,
510  sizeof(credential->Flags));
511  if (ret != ERROR_SUCCESS) return ret;
512  ret = RegSetValueExW(hkey, wszTypeValue, 0, REG_DWORD, (const BYTE*)&credential->Type,
513  sizeof(credential->Type));
514  if (ret != ERROR_SUCCESS) return ret;
515  ret = RegSetValueExW(hkey, NULL, 0, REG_SZ, (LPVOID)credential->TargetName,
516  sizeof(WCHAR)*(strlenW(credential->TargetName)+1));
517  if (ret != ERROR_SUCCESS) return ret;
518  if (credential->Comment)
519  {
520  ret = RegSetValueExW(hkey, wszCommentValue, 0, REG_SZ, (LPVOID)credential->Comment,
521  sizeof(WCHAR)*(strlenW(credential->Comment)+1));
522  if (ret != ERROR_SUCCESS) return ret;
523  }
524  ret = RegSetValueExW(hkey, wszLastWrittenValue, 0, REG_BINARY, (LPVOID)&LastWritten,
525  sizeof(LastWritten));
526  if (ret != ERROR_SUCCESS) return ret;
527  ret = RegSetValueExW(hkey, wszPersistValue, 0, REG_DWORD, (const BYTE*)&credential->Persist,
528  sizeof(credential->Persist));
529  if (ret != ERROR_SUCCESS) return ret;
530  /* FIXME: Attributes */
531  if (credential->TargetAlias)
532  {
534  sizeof(WCHAR)*(strlenW(credential->TargetAlias)+1));
535  if (ret != ERROR_SUCCESS) return ret;
536  }
537  if (credential->UserName)
538  {
539  ret = RegSetValueExW(hkey, wszUserNameValue, 0, REG_SZ, (LPVOID)credential->UserName,
540  sizeof(WCHAR)*(strlenW(credential->UserName)+1));
541  if (ret != ERROR_SUCCESS) return ret;
542  }
543  if (!preserve_blob)
544  {
545  ret = write_credential_blob(hkey, credential->TargetName, credential->Type,
546  key_data, credential->CredentialBlob,
547  credential->CredentialBlobSize);
548  }
549  return ret;
550 }
551 
552 #ifdef __APPLE__
553 static DWORD mac_write_credential(const CREDENTIALW *credential, BOOL preserve_blob)
554 {
555  int status;
556  SecKeychainItemRef keychain_item;
557  char *username, *password, *servername;
558  UInt32 userlen, pwlen, serverlen;
559  SecKeychainAttribute attrs[1];
560  SecKeychainAttributeList attr_list;
561 
562  if (credential->Flags)
563  FIXME("Flags 0x%x not written\n", credential->Flags);
564  if (credential->Type != CRED_TYPE_DOMAIN_PASSWORD)
565  FIXME("credential type of %d not supported\n", credential->Type);
566  if (credential->Persist != CRED_PERSIST_LOCAL_MACHINE)
567  FIXME("persist value of %d not supported\n", credential->Persist);
568  if (credential->AttributeCount)
569  FIXME("custom attributes not supported\n");
570 
571  userlen = WideCharToMultiByte(CP_UTF8, 0, credential->UserName, -1, NULL, 0, NULL, NULL);
572  username = heap_alloc(userlen * sizeof(*username));
573  WideCharToMultiByte(CP_UTF8, 0, credential->UserName, -1, username, userlen, NULL, NULL);
574 
575  serverlen = WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, NULL, 0, NULL, NULL);
576  servername = heap_alloc(serverlen * sizeof(*servername));
577  WideCharToMultiByte(CP_UTF8, 0, credential->TargetName, -1, servername, serverlen, NULL, NULL);
578  pwlen = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)credential->CredentialBlob,
579  credential->CredentialBlobSize / sizeof(WCHAR), NULL, 0, NULL, NULL);
580  password = heap_alloc(pwlen * sizeof(*password));
582  credential->CredentialBlobSize / sizeof(WCHAR), password, pwlen, NULL, NULL);
583 
584  TRACE("adding server %s, username %s using Keychain\n", servername, username);
585  status = SecKeychainAddGenericPassword(NULL, strlen(servername), servername, strlen(username),
586  username, strlen(password), password, &keychain_item);
587  if (status != noErr)
588  ERR("SecKeychainAddGenericPassword returned %d\n", status);
589  if (status == errSecDuplicateItem)
590  {
591  status = SecKeychainFindGenericPassword(NULL, strlen(servername), servername, strlen(username),
592  username, NULL, NULL, &keychain_item);
593  if (status != noErr)
594  ERR("SecKeychainFindGenericPassword returned %d\n", status);
595  }
597  heap_free(servername);
598  if (status != noErr)
599  {
601  return ERROR_GEN_FAILURE;
602  }
603  if (credential->Comment)
604  {
605  attr_list.count = 1;
606  attr_list.attr = attrs;
607  attrs[0].tag = kSecCommentItemAttr;
608  attrs[0].length = WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, NULL, 0, NULL, NULL);
609  if (attrs[0].length) attrs[0].length--;
610  attrs[0].data = heap_alloc(attrs[0].length);
611  WideCharToMultiByte(CP_UTF8, 0, credential->Comment, -1, attrs[0].data, attrs[0].length, NULL, NULL);
612  }
613  else
614  {
615  attr_list.count = 0;
616  attr_list.attr = NULL;
617  }
618  status = SecKeychainItemModifyAttributesAndData(keychain_item, &attr_list,
619  preserve_blob ? 0 : strlen(password),
620  preserve_blob ? NULL : password);
621  if (credential->Comment)
622  heap_free(attrs[0].data);
624  /* FIXME: set TargetAlias attribute */
625  CFRelease(keychain_item);
626  if (status != noErr)
627  return ERROR_GEN_FAILURE;
628  return ERROR_SUCCESS;
629 }
630 #endif
631 
632 static DWORD open_cred_mgr_key(HKEY *hkey, BOOL open_for_write)
633 {
636  KEY_READ | (open_for_write ? KEY_WRITE : 0), NULL, hkey, NULL);
637 }
638 
640 {
641  static const BYTE my_key_data[KEY_SIZE] = { 0 };
642  DWORD type;
643  DWORD count;
644  FILETIME ft;
645  ULONG seed;
646  ULONG value;
647  DWORD ret;
648 
649  memcpy(key_data, my_key_data, KEY_SIZE);
650 
651  count = KEY_SIZE;
652  ret = RegQueryValueExW(hkeyMgr, wszEncryptionKeyValue, NULL, &type, key_data,
653  &count);
654  if (ret == ERROR_SUCCESS)
655  {
656  if (type != REG_BINARY)
657  return ERROR_REGISTRY_CORRUPT;
658  else
659  return ERROR_SUCCESS;
660  }
661  if (ret != ERROR_FILE_NOT_FOUND)
662  return ret;
663 
665  seed = ft.dwLowDateTime;
666  value = RtlUniform(&seed);
667  *(DWORD *)key_data = value;
668  seed = ft.dwHighDateTime;
669  value = RtlUniform(&seed);
670  *(DWORD *)(key_data + 4) = value;
671 
673  key_data, KEY_SIZE);
674  if (ret == ERROR_ACCESS_DENIED)
675  {
676  ret = open_cred_mgr_key(&hkeyMgr, TRUE);
677  if (ret == ERROR_SUCCESS)
678  {
680  key_data, KEY_SIZE);
681  RegCloseKey(hkeyMgr);
682  }
683  }
684  return ret;
685 }
686 
688 {
689  static const WCHAR wszGenericPrefix[] = {'G','e','n','e','r','i','c',':',' ',0};
690  static const WCHAR wszDomPasswdPrefix[] = {'D','o','m','P','a','s','s','w','d',':',' ',0};
691  INT len;
692  LPCWSTR prefix = NULL;
693  LPWSTR key_name, p;
694 
695  len = strlenW(target_name);
696  if (type == CRED_TYPE_GENERIC)
697  {
698  prefix = wszGenericPrefix;
699  len += sizeof(wszGenericPrefix)/sizeof(wszGenericPrefix[0]);
700  }
701  else
702  {
703  prefix = wszDomPasswdPrefix;
704  len += sizeof(wszDomPasswdPrefix)/sizeof(wszDomPasswdPrefix[0]);
705  }
706 
707  key_name = heap_alloc(len * sizeof(WCHAR));
708  if (!key_name) return NULL;
709 
710  strcpyW(key_name, prefix);
711  strcatW(key_name, target_name);
712 
713  for (p = key_name; *p; p++)
714  if (*p == '\\') *p = '_';
715 
716  return key_name;
717 }
718 
720 {
721  LPWSTR target_name;
722  DWORD ret;
723  DWORD type;
724  DWORD count;
725  LPCWSTR p;
726 
727  if (!filter) return TRUE;
728 
729  ret = RegQueryValueExW(hkeyCred, NULL, 0, &type, NULL, &count);
730  if (ret != ERROR_SUCCESS)
731  return FALSE;
732  else if (type != REG_SZ)
733  return FALSE;
734 
735  target_name = heap_alloc(count);
736  if (!target_name)
737  return FALSE;
738  ret = RegQueryValueExW(hkeyCred, NULL, 0, &type, (LPVOID)target_name, &count);
739  if (ret != ERROR_SUCCESS || type != REG_SZ)
740  {
741  heap_free(target_name);
742  return FALSE;
743  }
744 
745  TRACE("comparing filter %s to target name %s\n", debugstr_w(filter),
746  debugstr_w(target_name));
747 
748  p = strchrW(filter, '*');
750  (p && !p[1] ? p - filter : -1), target_name,
751  (p && !p[1] ? p - filter : -1)) == CSTR_EQUAL;
752 
753  heap_free(target_name);
754  return ret;
755 }
756 
758  LPWSTR target_name,
759  DWORD target_name_len, const BYTE key_data[KEY_SIZE],
760  PCREDENTIALW *credentials, char **buffer,
761  DWORD *len, DWORD *count)
762 {
763  DWORD i;
764  DWORD ret;
765  for (i = 0;; i++)
766  {
767  HKEY hkeyCred;
768  ret = RegEnumKeyW(hkeyMgr, i, target_name, target_name_len+1);
769  if (ret == ERROR_NO_MORE_ITEMS)
770  {
771  ret = ERROR_SUCCESS;
772  break;
773  }
774  else if (ret != ERROR_SUCCESS)
775  continue;
776  TRACE("target_name = %s\n", debugstr_w(target_name));
777  ret = RegOpenKeyExW(hkeyMgr, target_name, 0, KEY_QUERY_VALUE, &hkeyCred);
778  if (ret != ERROR_SUCCESS)
779  continue;
781  {
782  RegCloseKey(hkeyCred);
783  continue;
784  }
785  if (buffer)
786  {
787  *len = sizeof(CREDENTIALW);
788  credentials[*count] = (PCREDENTIALW)*buffer;
789  }
790  else
791  *len += sizeof(CREDENTIALW);
792  ret = registry_read_credential(hkeyCred, buffer ? credentials[*count] : NULL,
793  key_data, buffer ? *buffer + sizeof(CREDENTIALW) : NULL,
794  len);
795  RegCloseKey(hkeyCred);
796  if (ret != ERROR_SUCCESS) break;
797  if (buffer) *buffer += *len;
798  (*count)++;
799  }
800  return ret;
801 }
802 
803 #ifdef __APPLE__
804 static BOOL mac_credential_matches_filter(void *data, UInt32 data_len, const WCHAR *filter)
805 {
806  int len;
807  WCHAR *target_name;
808  const WCHAR *p;
809  BOOL ret;
810 
811  if (!filter) return TRUE;
812 
813  len = MultiByteToWideChar(CP_UTF8, 0, data, data_len, NULL, 0);
814  if (!(target_name = heap_alloc((len + 1) * sizeof(WCHAR)))) return FALSE;
815  MultiByteToWideChar(CP_UTF8, 0, data, data_len, target_name, len);
816  target_name[len] = 0;
817 
818  TRACE("comparing filter %s to target name %s\n", debugstr_w(filter), debugstr_w(target_name));
819 
820  p = strchrW(filter, '*');
822  (p && !p[1] ? p - filter : -1), target_name,
823  (p && !p[1] ? p - filter : -1)) == CSTR_EQUAL;
824  heap_free(target_name);
825  return ret;
826 }
827 
828 static DWORD mac_enumerate_credentials(LPCWSTR filter, PCREDENTIALW *credentials,
829  char *buffer, DWORD *len, DWORD *count)
830 {
831  SecKeychainSearchRef search;
832  SecKeychainItemRef item;
833  int status;
834  Boolean saved_user_interaction_allowed;
835  DWORD ret;
836 
837  SecKeychainGetUserInteractionAllowed(&saved_user_interaction_allowed);
838  SecKeychainSetUserInteractionAllowed(false);
839 
840  status = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, NULL, &search);
841  if (status == noErr)
842  {
843  while (SecKeychainSearchCopyNext(search, &item) == noErr)
844  {
845  SecKeychainAttributeInfo info;
846  SecKeychainAttributeList *attr_list;
847  UInt32 info_tags[] = { kSecServiceItemAttr };
848  BOOL match;
849 
850  info.count = sizeof(info_tags)/sizeof(info_tags[0]);
851  info.tag = info_tags;
852  info.format = NULL;
853  status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
854  if (status != noErr)
855  {
856  WARN("SecKeychainItemCopyAttributesAndData returned status %d\n", status);
857  continue;
858  }
859  if (buffer)
860  {
861  *len = sizeof(CREDENTIALW);
862  credentials[*count] = (PCREDENTIALW)buffer;
863  }
864  else
865  *len += sizeof(CREDENTIALW);
866  if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServiceItemAttr)
867  {
868  SecKeychainItemFreeAttributesAndData(attr_list, NULL);
869  continue;
870  }
871  TRACE("service item: %.*s\n", (int)attr_list->attr[0].length, (char *)attr_list->attr[0].data);
872  match = mac_credential_matches_filter(attr_list->attr[0].data, attr_list->attr[0].length, filter);
873  SecKeychainItemFreeAttributesAndData(attr_list, NULL);
874  if (!match) continue;
875  ret = mac_read_credential_from_item(item, FALSE,
876  buffer ? credentials[*count] : NULL,
877  buffer ? buffer + sizeof(CREDENTIALW) : NULL,
878  len);
879  CFRelease(item);
880  if (ret == ERROR_SUCCESS)
881  {
882  (*count)++;
883  if (buffer) buffer += *len;
884  }
885  }
886  CFRelease(search);
887  }
888  else
889  ERR("SecKeychainSearchCreateFromAttributes returned status %d\n", status);
890  SecKeychainSetUserInteractionAllowed(saved_user_interaction_allowed);
891  return ERROR_SUCCESS;
892 }
893 
894 static DWORD mac_delete_credential(LPCWSTR TargetName)
895 {
896  int status;
897  SecKeychainSearchRef search;
898  status = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, NULL, &search);
899  if (status == noErr)
900  {
901  SecKeychainItemRef item;
902  while (SecKeychainSearchCopyNext(search, &item) == noErr)
903  {
904  SecKeychainAttributeInfo info;
905  SecKeychainAttributeList *attr_list;
906  UInt32 info_tags[] = { kSecServiceItemAttr };
907  LPWSTR target_name;
908  INT str_len;
909  info.count = sizeof(info_tags)/sizeof(info_tags[0]);
910  info.tag = info_tags;
911  info.format = NULL;
912  status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
913  if (status != noErr)
914  {
915  WARN("SecKeychainItemCopyAttributesAndData returned status %d\n", status);
916  continue;
917  }
918  if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServiceItemAttr)
919  {
920  CFRelease(item);
921  continue;
922  }
923  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, NULL, 0);
924  target_name = heap_alloc((str_len + 1) * sizeof(WCHAR));
925  MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, target_name, str_len);
926  /* nul terminate */
927  target_name[str_len] = '\0';
928  if (strcmpiW(TargetName, target_name))
929  {
930  CFRelease(item);
931  heap_free(target_name);
932  continue;
933  }
934  heap_free(target_name);
935  SecKeychainItemFreeAttributesAndData(attr_list, NULL);
936  SecKeychainItemDelete(item);
937  CFRelease(item);
938  CFRelease(search);
939 
940  return ERROR_SUCCESS;
941  }
942  CFRelease(search);
943  }
944  return ERROR_NOT_FOUND;
945 }
946 #endif
947 
948 /******************************************************************************
949  * convert_PCREDENTIALW_to_PCREDENTIALA [internal]
950  *
951  * convert a Credential struct from UNICODE to ANSI and return the needed size in Bytes
952  *
953  */
954 
956 {
957  char *buffer;
958  INT string_len;
959  INT needed = sizeof(CREDENTIALA);
960 
961  if (!CredentialA)
962  {
963  if (CredentialW->TargetName)
964  needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, NULL, 0, NULL, NULL);
965  if (CredentialW->Comment)
966  needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, NULL, 0, NULL, NULL);
967  needed += CredentialW->CredentialBlobSize;
968  if (CredentialW->TargetAlias)
969  needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, NULL, 0, NULL, NULL);
970  if (CredentialW->UserName)
971  needed += WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, NULL, 0, NULL, NULL);
972 
973  return needed;
974  }
975 
976 
977  buffer = (char *)CredentialA + sizeof(CREDENTIALA);
978  len -= sizeof(CREDENTIALA);
979  CredentialA->Flags = CredentialW->Flags;
980  CredentialA->Type = CredentialW->Type;
981 
982  if (CredentialW->TargetName)
983  {
984  CredentialA->TargetName = buffer;
985  string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetName, -1, buffer, len, NULL, NULL);
986  buffer += string_len;
987  needed += string_len;
988  len -= string_len;
989  }
990  else
991  CredentialA->TargetName = NULL;
992  if (CredentialW->Comment)
993  {
994  CredentialA->Comment = buffer;
995  string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->Comment, -1, buffer, len, NULL, NULL);
996  buffer += string_len;
997  needed += string_len;
998  len -= string_len;
999  }
1000  else
1001  CredentialA->Comment = NULL;
1002  CredentialA->LastWritten = CredentialW->LastWritten;
1003  CredentialA->CredentialBlobSize = CredentialW->CredentialBlobSize;
1004  if (CredentialW->CredentialBlobSize && (CredentialW->CredentialBlobSize <= len))
1005  {
1006  CredentialA->CredentialBlob =(LPBYTE)buffer;
1007  memcpy(CredentialA->CredentialBlob, CredentialW->CredentialBlob,
1008  CredentialW->CredentialBlobSize);
1009  buffer += CredentialW->CredentialBlobSize;
1010  needed += CredentialW->CredentialBlobSize;
1011  len -= CredentialW->CredentialBlobSize;
1012  }
1013  else
1014  CredentialA->CredentialBlob = NULL;
1015  CredentialA->Persist = CredentialW->Persist;
1016  CredentialA->AttributeCount = 0;
1017  CredentialA->Attributes = NULL; /* FIXME */
1018  if (CredentialW->TargetAlias)
1019  {
1020  CredentialA->TargetAlias = buffer;
1021  string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->TargetAlias, -1, buffer, len, NULL, NULL);
1022  buffer += string_len;
1023  needed += string_len;
1024  len -= string_len;
1025  }
1026  else
1027  CredentialA->TargetAlias = NULL;
1028  if (CredentialW->UserName)
1029  {
1030  CredentialA->UserName = buffer;
1031  string_len = WideCharToMultiByte(CP_ACP, 0, CredentialW->UserName, -1, buffer, len, NULL, NULL);
1032  needed += string_len;
1033  }
1034  else
1035  CredentialA->UserName = NULL;
1036 
1037  return needed;
1038 }
1039 
1040 /******************************************************************************
1041  * convert_PCREDENTIALA_to_PCREDENTIALW [internal]
1042  *
1043  * convert a Credential struct from ANSI to UNICODE and return the needed size in Bytes
1044  *
1045  */
1047 {
1048  char *buffer;
1049  INT string_len;
1050  INT needed = sizeof(CREDENTIALW);
1051 
1052  if (!CredentialW)
1053  {
1054  if (CredentialA->TargetName)
1055  needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, NULL, 0);
1056  if (CredentialA->Comment)
1057  needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, NULL, 0);
1058  needed += CredentialA->CredentialBlobSize;
1059  if (CredentialA->TargetAlias)
1060  needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, NULL, 0);
1061  if (CredentialA->UserName)
1062  needed += sizeof(WCHAR) * MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, NULL, 0);
1063 
1064  return needed;
1065  }
1066 
1067  buffer = (char *)CredentialW + sizeof(CREDENTIALW);
1068  len -= sizeof(CREDENTIALW);
1069  CredentialW->Flags = CredentialA->Flags;
1070  CredentialW->Type = CredentialA->Type;
1071  if (CredentialA->TargetName)
1072  {
1073  CredentialW->TargetName = (LPWSTR)buffer;
1074  string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetName, -1, CredentialW->TargetName, len / sizeof(WCHAR));
1075  buffer += sizeof(WCHAR) * string_len;
1076  needed += sizeof(WCHAR) * string_len;
1077  len -= sizeof(WCHAR) * string_len;
1078  }
1079  else
1080  CredentialW->TargetName = NULL;
1081  if (CredentialA->Comment)
1082  {
1083  CredentialW->Comment = (LPWSTR)buffer;
1084  string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->Comment, -1, CredentialW->Comment, len / sizeof(WCHAR));
1085  buffer += sizeof(WCHAR) * string_len;
1086  needed += sizeof(WCHAR) * string_len;
1087  len -= sizeof(WCHAR) * string_len;
1088  }
1089  else
1090  CredentialW->Comment = NULL;
1091  CredentialW->LastWritten = CredentialA->LastWritten;
1092  CredentialW->CredentialBlobSize = CredentialA->CredentialBlobSize;
1093  if (CredentialA->CredentialBlobSize)
1094  {
1095  CredentialW->CredentialBlob =(LPBYTE)buffer;
1096  memcpy(CredentialW->CredentialBlob, CredentialA->CredentialBlob,
1097  CredentialA->CredentialBlobSize);
1098  buffer += CredentialA->CredentialBlobSize;
1099  needed += CredentialA->CredentialBlobSize;
1100  len -= CredentialA->CredentialBlobSize;
1101  }
1102  else
1103  CredentialW->CredentialBlob = NULL;
1104  CredentialW->Persist = CredentialA->Persist;
1105  CredentialW->AttributeCount = 0;
1106  CredentialW->Attributes = NULL; /* FIXME */
1107  if (CredentialA->TargetAlias)
1108  {
1109  CredentialW->TargetAlias = (LPWSTR)buffer;
1110  string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->TargetAlias, -1, CredentialW->TargetAlias, len / sizeof(WCHAR));
1111  buffer += sizeof(WCHAR) * string_len;
1112  needed += sizeof(WCHAR) * string_len;
1113  len -= sizeof(WCHAR) * string_len;
1114  }
1115  else
1116  CredentialW->TargetAlias = NULL;
1117  if (CredentialA->UserName)
1118  {
1119  CredentialW->UserName = (LPWSTR)buffer;
1120  string_len = MultiByteToWideChar(CP_ACP, 0, CredentialA->UserName, -1, CredentialW->UserName, len / sizeof(WCHAR));
1121  needed += sizeof(WCHAR) * string_len;
1122  }
1123  else
1124  CredentialW->UserName = NULL;
1125 
1126  return needed;
1127 }
1128 
1129 /******************************************************************************
1130  * CredDeleteA [ADVAPI32.@]
1131  */
1133 {
1134  LPWSTR TargetNameW;
1135  DWORD len;
1136  BOOL ret;
1137 
1138  TRACE("(%s, %d, 0x%x)\n", debugstr_a(TargetName), Type, Flags);
1139 
1140  if (!TargetName)
1141  {
1143  return FALSE;
1144  }
1145 
1146  len = MultiByteToWideChar(CP_ACP, 0, TargetName, -1, NULL, 0);
1147  TargetNameW = heap_alloc(len * sizeof(WCHAR));
1148  if (!TargetNameW)
1149  {
1151  return FALSE;
1152  }
1153  MultiByteToWideChar(CP_ACP, 0, TargetName, -1, TargetNameW, len);
1154 
1155  ret = CredDeleteW(TargetNameW, Type, Flags);
1156 
1157  heap_free(TargetNameW);
1158 
1159  return ret;
1160 }
1161 
1162 /******************************************************************************
1163  * CredDeleteW [ADVAPI32.@]
1164  */
1166 {
1167  HKEY hkeyMgr;
1168  DWORD ret;
1169  LPWSTR key_name;
1170 
1171  TRACE("(%s, %d, 0x%x)\n", debugstr_w(TargetName), Type, Flags);
1172 
1173  if (!TargetName)
1174  {
1176  return FALSE;
1177  }
1178 
1180  {
1181  FIXME("unhandled type %d\n", Type);
1183  return FALSE;
1184  }
1185 
1186  if (Flags)
1187  {
1188  FIXME("unhandled flags 0x%x\n", Flags);
1190  return FALSE;
1191  }
1192 
1193 #ifdef __APPLE__
1195  {
1196  ret = mac_delete_credential(TargetName);
1197  if (ret == ERROR_SUCCESS)
1198  return TRUE;
1199  }
1200 #endif
1201 
1202  ret = open_cred_mgr_key(&hkeyMgr, TRUE);
1203  if (ret != ERROR_SUCCESS)
1204  {
1205  WARN("couldn't open/create manager key, error %d\n", ret);
1207  return FALSE;
1208  }
1209 
1211  ret = RegDeleteKeyW(hkeyMgr, key_name);
1213  RegCloseKey(hkeyMgr);
1214  if (ret != ERROR_SUCCESS)
1215  {
1217  return FALSE;
1218  }
1219 
1220  return TRUE;
1221 }
1222 
1223 /******************************************************************************
1224  * CredEnumerateA [ADVAPI32.@]
1225  */
1227  PCREDENTIALA **Credentials)
1228 {
1229  LPWSTR FilterW;
1230  PCREDENTIALW *CredentialsW;
1231  DWORD i;
1232  INT len;
1233  INT needed;
1234  char *buffer;
1235 
1236  TRACE("(%s, 0x%x, %p, %p)\n", debugstr_a(Filter), Flags, Count, Credentials);
1237 
1238  if (Filter)
1239  {
1240  len = MultiByteToWideChar(CP_ACP, 0, Filter, -1, NULL, 0);
1241  FilterW = heap_alloc(len * sizeof(WCHAR));
1242  if (!FilterW)
1243  {
1245  return FALSE;
1246  }
1247  MultiByteToWideChar(CP_ACP, 0, Filter, -1, FilterW, len);
1248  }
1249  else
1250  FilterW = NULL;
1251 
1252  if (!CredEnumerateW(FilterW, Flags, Count, &CredentialsW))
1253  {
1254  heap_free(FilterW);
1255  return FALSE;
1256  }
1257  heap_free(FilterW);
1258 
1259  len = *Count * sizeof(PCREDENTIALA);
1260  for (i = 0; i < *Count; i++)
1261  len += convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, 0);
1262 
1263  *Credentials = heap_alloc(len);
1264  if (!*Credentials)
1265  {
1266  CredFree(CredentialsW);
1268  return FALSE;
1269  }
1270 
1271  buffer = (char *)&(*Credentials)[*Count];
1272  len -= *Count * sizeof(PCREDENTIALA);
1273  for (i = 0; i < *Count; i++)
1274  {
1275  (*Credentials)[i] = (PCREDENTIALA)buffer;
1276  needed = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], len);
1277  buffer += needed;
1278  len -= needed;
1279  }
1280 
1281  CredFree(CredentialsW);
1282 
1283  return TRUE;
1284 }
1285 
1286 /******************************************************************************
1287  * CredEnumerateW [ADVAPI32.@]
1288  */
1290  PCREDENTIALW **Credentials)
1291 {
1292  HKEY hkeyMgr;
1293  DWORD ret;
1294  LPWSTR target_name;
1295  DWORD target_name_len;
1296  DWORD len;
1297  char *buffer;
1298  BYTE key_data[KEY_SIZE];
1299 
1300  TRACE("(%s, 0x%x, %p, %p)\n", debugstr_w(Filter), Flags, Count, Credentials);
1301 
1302  if (Flags)
1303  {
1305  return FALSE;
1306  }
1307 
1308  ret = open_cred_mgr_key(&hkeyMgr, FALSE);
1309  if (ret != ERROR_SUCCESS)
1310  {
1311  WARN("couldn't open/create manager key, error %d\n", ret);
1313  return FALSE;
1314  }
1315 
1316  ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
1317  if (ret != ERROR_SUCCESS)
1318  {
1319  RegCloseKey(hkeyMgr);
1320  SetLastError(ret);
1321  return FALSE;
1322  }
1323 
1324  ret = RegQueryInfoKeyW(hkeyMgr, NULL, NULL, NULL, NULL, &target_name_len, NULL, NULL, NULL, NULL, NULL, NULL);
1325  if (ret != ERROR_SUCCESS)
1326  {
1327  RegCloseKey(hkeyMgr);
1328  SetLastError(ret);
1329  return FALSE;
1330  }
1331 
1332  target_name = heap_alloc((target_name_len+1)*sizeof(WCHAR));
1333  if (!target_name)
1334  {
1335  RegCloseKey(hkeyMgr);
1337  return FALSE;
1338  }
1339 
1340  *Count = 0;
1341  len = 0;
1342  ret = registry_enumerate_credentials(hkeyMgr, Filter, target_name, target_name_len,
1343  key_data, NULL, NULL, &len, Count);
1344 #ifdef __APPLE__
1345  if (ret == ERROR_SUCCESS)
1346  ret = mac_enumerate_credentials(Filter, NULL, NULL, &len, Count);
1347 #endif
1348  if (ret == ERROR_SUCCESS && *Count == 0)
1349  ret = ERROR_NOT_FOUND;
1350  if (ret != ERROR_SUCCESS)
1351  {
1352  heap_free(target_name);
1353  RegCloseKey(hkeyMgr);
1354  SetLastError(ret);
1355  return FALSE;
1356  }
1357  len += *Count * sizeof(PCREDENTIALW);
1358 
1359  if (ret == ERROR_SUCCESS)
1360  {
1361  buffer = heap_alloc(len);
1362  *Credentials = (PCREDENTIALW *)buffer;
1363  if (buffer)
1364  {
1365  buffer += *Count * sizeof(PCREDENTIALW);
1366  *Count = 0;
1367  ret = registry_enumerate_credentials(hkeyMgr, Filter, target_name,
1368  target_name_len, key_data,
1369  *Credentials, &buffer, &len,
1370  Count);
1371 #ifdef __APPLE__
1372  if (ret == ERROR_SUCCESS)
1373  ret = mac_enumerate_credentials(Filter, *Credentials,
1374  buffer, &len, Count);
1375 #endif
1376  }
1377  else
1379  }
1380 
1381  heap_free(target_name);
1382  RegCloseKey(hkeyMgr);
1383 
1384  if (ret != ERROR_SUCCESS)
1385  {
1386  SetLastError(ret);
1387  return FALSE;
1388  }
1389  return TRUE;
1390 }
1391 
1392 /******************************************************************************
1393  * CredFree [ADVAPI32.@]
1394  */
1396 {
1397  heap_free(Buffer);
1398 }
1399 
1400 /******************************************************************************
1401  * CredReadA [ADVAPI32.@]
1402  */
1404 {
1405  LPWSTR TargetNameW;
1406  PCREDENTIALW CredentialW;
1407  INT len;
1408 
1409  TRACE("(%s, %d, 0x%x, %p)\n", debugstr_a(TargetName), Type, Flags, Credential);
1410 
1411  if (!TargetName)
1412  {
1414  return FALSE;
1415  }
1416 
1417  len = MultiByteToWideChar(CP_ACP, 0, TargetName, -1, NULL, 0);
1418  TargetNameW = heap_alloc(len * sizeof(WCHAR));
1419  if (!TargetNameW)
1420  {
1422  return FALSE;
1423  }
1424  MultiByteToWideChar(CP_ACP, 0, TargetName, -1, TargetNameW, len);
1425 
1426  if (!CredReadW(TargetNameW, Type, Flags, &CredentialW))
1427  {
1428  heap_free(TargetNameW);
1429  return FALSE;
1430  }
1431  heap_free(TargetNameW);
1432 
1433  len = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, NULL, 0);
1434  *Credential = heap_alloc(len);
1435  if (!*Credential)
1436  {
1438  return FALSE;
1439  }
1440  convert_PCREDENTIALW_to_PCREDENTIALA(CredentialW, *Credential, len);
1441 
1442  CredFree(CredentialW);
1443 
1444  return TRUE;
1445 }
1446 
1447 /******************************************************************************
1448  * CredReadW [ADVAPI32.@]
1449  */
1451 {
1452  HKEY hkeyMgr;
1453  HKEY hkeyCred;
1454  DWORD ret;
1455  LPWSTR key_name;
1456  DWORD len;
1457  BYTE key_data[KEY_SIZE];
1458 
1459  TRACE("(%s, %d, 0x%x, %p)\n", debugstr_w(TargetName), Type, Flags, Credential);
1460 
1461  if (!TargetName)
1462  {
1464  return FALSE;
1465  }
1466 
1468  {
1469  FIXME("unhandled type %d\n", Type);
1471  return FALSE;
1472  }
1473 
1474  if (Flags)
1475  {
1476  FIXME("unhandled flags 0x%x\n", Flags);
1478  return FALSE;
1479  }
1480 
1481 #ifdef __APPLE__
1483  {
1484  int status;
1485  SecKeychainSearchRef search;
1486  status = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, NULL, &search);
1487  if (status == noErr)
1488  {
1489  SecKeychainItemRef item;
1490  while (SecKeychainSearchCopyNext(search, &item) == noErr)
1491  {
1492  SecKeychainAttributeInfo info;
1493  SecKeychainAttributeList *attr_list;
1494  UInt32 info_tags[] = { kSecServiceItemAttr };
1495  LPWSTR target_name;
1496  INT str_len;
1497  info.count = sizeof(info_tags)/sizeof(info_tags[0]);
1498  info.tag = info_tags;
1499  info.format = NULL;
1500  status = SecKeychainItemCopyAttributesAndData(item, &info, NULL, &attr_list, NULL, NULL);
1501  len = sizeof(**Credential);
1502  if (status != noErr)
1503  {
1504  WARN("SecKeychainItemCopyAttributesAndData returned status %d\n", status);
1505  continue;
1506  }
1507  if (attr_list->count != 1 || attr_list->attr[0].tag != kSecServiceItemAttr)
1508  {
1509  CFRelease(item);
1510  continue;
1511  }
1512  str_len = MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, NULL, 0);
1513  target_name = heap_alloc((str_len + 1) * sizeof(WCHAR));
1514  MultiByteToWideChar(CP_UTF8, 0, attr_list->attr[0].data, attr_list->attr[0].length, target_name, str_len);
1515  /* nul terminate */
1516  target_name[str_len] = '\0';
1517  if (strcmpiW(TargetName, target_name))
1518  {
1519  CFRelease(item);
1520  heap_free(target_name);
1521  continue;
1522  }
1523  heap_free(target_name);
1524  SecKeychainItemFreeAttributesAndData(attr_list, NULL);
1525  ret = mac_read_credential_from_item(item, TRUE, NULL, NULL, &len);
1526  if (ret == ERROR_SUCCESS)
1527  {
1528  *Credential = heap_alloc(len);
1529  if (*Credential)
1530  {
1531  len = sizeof(**Credential);
1532  ret = mac_read_credential_from_item(item, TRUE, *Credential,
1533  (char *)(*Credential + 1), &len);
1534  }
1535  else
1537  CFRelease(item);
1538  CFRelease(search);
1539  if (ret != ERROR_SUCCESS)
1540  {
1541  SetLastError(ret);
1542  return FALSE;
1543  }
1544  return TRUE;
1545  }
1546  CFRelease(item);
1547  }
1548  CFRelease(search);
1549  }
1550  }
1551 #endif
1552 
1553  ret = open_cred_mgr_key(&hkeyMgr, FALSE);
1554  if (ret != ERROR_SUCCESS)
1555  {
1556  WARN("couldn't open/create manager key, error %d\n", ret);
1558  return FALSE;
1559  }
1560 
1561  ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
1562  if (ret != ERROR_SUCCESS)
1563  {
1564  RegCloseKey(hkeyMgr);
1565  SetLastError(ret);
1566  return FALSE;
1567  }
1568 
1570  ret = RegOpenKeyExW(hkeyMgr, key_name, 0, KEY_QUERY_VALUE, &hkeyCred);
1572  if (ret != ERROR_SUCCESS)
1573  {
1574  TRACE("credentials for target name %s not found\n", debugstr_w(TargetName));
1576  return FALSE;
1577  }
1578 
1579  len = sizeof(**Credential);
1580  ret = registry_read_credential(hkeyCred, NULL, key_data, NULL, &len);
1581  if (ret == ERROR_SUCCESS)
1582  {
1583  *Credential = heap_alloc(len);
1584  if (*Credential)
1585  {
1586  len = sizeof(**Credential);
1587  ret = registry_read_credential(hkeyCred, *Credential, key_data,
1588  (char *)(*Credential + 1), &len);
1589  }
1590  else
1592  }
1593 
1594  RegCloseKey(hkeyCred);
1595  RegCloseKey(hkeyMgr);
1596 
1597  if (ret != ERROR_SUCCESS)
1598  {
1599  SetLastError(ret);
1600  return FALSE;
1601  }
1602  return TRUE;
1603 }
1604 
1605 /******************************************************************************
1606  * CredReadDomainCredentialsA [ADVAPI32.@]
1607  */
1609  DWORD Flags, DWORD *Size, PCREDENTIALA **Credentials)
1610 {
1611  PCREDENTIAL_TARGET_INFORMATIONW TargetInformationW;
1612  INT len;
1613  DWORD i;
1614  WCHAR *buffer, *end;
1615  BOOL ret;
1616  PCREDENTIALW* CredentialsW;
1617 
1618  TRACE("(%p, 0x%x, %p, %p)\n", TargetInformation, Flags, Size, Credentials);
1619 
1620  /* follow Windows behavior - do not test for NULL, initialize early */
1621  *Size = 0;
1622  *Credentials = NULL;
1623 
1624  if (!TargetInformation)
1625  {
1627  return FALSE;
1628  }
1629 
1630  len = sizeof(*TargetInformationW);
1631  if (TargetInformation->TargetName)
1632  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->TargetName, -1, NULL, 0) * sizeof(WCHAR);
1633  if (TargetInformation->NetbiosServerName)
1634  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosServerName, -1, NULL, 0) * sizeof(WCHAR);
1635  if (TargetInformation->DnsServerName)
1636  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsServerName, -1, NULL, 0) * sizeof(WCHAR);
1637  if (TargetInformation->NetbiosDomainName)
1638  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosDomainName, -1, NULL, 0) * sizeof(WCHAR);
1639  if (TargetInformation->DnsDomainName)
1640  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsDomainName, -1, NULL, 0) * sizeof(WCHAR);
1641  if (TargetInformation->DnsTreeName)
1642  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsTreeName, -1, NULL, 0) * sizeof(WCHAR);
1643  if (TargetInformation->PackageName)
1644  len += MultiByteToWideChar(CP_ACP, 0, TargetInformation->PackageName, -1, NULL, 0) * sizeof(WCHAR);
1645 
1646  TargetInformationW = heap_alloc(len);
1647  if (!TargetInformationW)
1648  {
1650  return FALSE;
1651  }
1652  buffer = (WCHAR*)(TargetInformationW + 1);
1653  end = (WCHAR *)((char *)TargetInformationW + len);
1654 
1655  if (TargetInformation->TargetName)
1656  {
1657  TargetInformationW->TargetName = buffer;
1658  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->TargetName, -1,
1659  TargetInformationW->TargetName, end - buffer);
1660  } else
1661  TargetInformationW->TargetName = NULL;
1662 
1663  if (TargetInformation->NetbiosServerName)
1664  {
1665  TargetInformationW->NetbiosServerName = buffer;
1666  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosServerName, -1,
1667  TargetInformationW->NetbiosServerName, end - buffer);
1668  } else
1669  TargetInformationW->NetbiosServerName = NULL;
1670 
1671  if (TargetInformation->DnsServerName)
1672  {
1673  TargetInformationW->DnsServerName = buffer;
1674  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsServerName, -1,
1675  TargetInformationW->DnsServerName, end - buffer);
1676  } else
1677  TargetInformationW->DnsServerName = NULL;
1678 
1679  if (TargetInformation->NetbiosDomainName)
1680  {
1681  TargetInformationW->NetbiosDomainName = buffer;
1682  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->NetbiosDomainName, -1,
1683  TargetInformationW->NetbiosDomainName, end - buffer);
1684  } else
1685  TargetInformationW->NetbiosDomainName = NULL;
1686 
1687  if (TargetInformation->DnsDomainName)
1688  {
1689  TargetInformationW->DnsDomainName = buffer;
1690  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsDomainName, -1,
1691  TargetInformationW->DnsDomainName, end - buffer);
1692  } else
1693  TargetInformationW->DnsDomainName = NULL;
1694 
1695  if (TargetInformation->DnsTreeName)
1696  {
1697  TargetInformationW->DnsTreeName = buffer;
1698  buffer += MultiByteToWideChar(CP_ACP, 0, TargetInformation->DnsTreeName, -1,
1699  TargetInformationW->DnsTreeName, end - buffer);
1700  } else
1701  TargetInformationW->DnsTreeName = NULL;
1702 
1703  if (TargetInformation->PackageName)
1704  {
1705  TargetInformationW->PackageName = buffer;
1706  MultiByteToWideChar(CP_ACP, 0, TargetInformation->PackageName, -1,
1707  TargetInformationW->PackageName, end - buffer);
1708  } else
1709  TargetInformationW->PackageName = NULL;
1710 
1711  TargetInformationW->Flags = TargetInformation->Flags;
1712  TargetInformationW->CredTypeCount = TargetInformation->CredTypeCount;
1713  TargetInformationW->CredTypes = TargetInformation->CredTypes;
1714 
1715  ret = CredReadDomainCredentialsW(TargetInformationW, Flags, Size, &CredentialsW);
1716 
1717  heap_free(TargetInformationW);
1718 
1719  if (ret)
1720  {
1721  char *buf;
1722  INT needed;
1723 
1724  len = *Size * sizeof(PCREDENTIALA);
1725  for (i = 0; i < *Size; i++)
1726  len += convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], NULL, 0);
1727 
1728  *Credentials = heap_alloc(len);
1729  if (!*Credentials)
1730  {
1731  CredFree(CredentialsW);
1733  return FALSE;
1734  }
1735 
1736  buf = (char *)&(*Credentials)[*Size];
1737  len -= *Size * sizeof(PCREDENTIALA);
1738  for (i = 0; i < *Size; i++)
1739  {
1740  (*Credentials)[i] = (PCREDENTIALA)buf;
1741  needed = convert_PCREDENTIALW_to_PCREDENTIALA(CredentialsW[i], (*Credentials)[i], len);
1742  buf += needed;
1743  len -= needed;
1744  }
1745 
1746  CredFree(CredentialsW);
1747  }
1748  return ret;
1749 }
1750 
1751 /******************************************************************************
1752  * CredReadDomainCredentialsW [ADVAPI32.@]
1753  */
1755  DWORD *Size, PCREDENTIALW **Credentials)
1756 {
1757  FIXME("(%p, 0x%x, %p, %p) stub\n", TargetInformation, Flags, Size, Credentials);
1758 
1759  /* follow Windows behavior - do not test for NULL, initialize early */
1760  *Size = 0;
1761  *Credentials = NULL;
1762  if (!TargetInformation)
1763  {
1765  return FALSE;
1766  }
1767 
1769  return FALSE;
1770 }
1771 
1772 /******************************************************************************
1773  * CredWriteA [ADVAPI32.@]
1774  */
1776 {
1777  BOOL ret;
1778  INT len;
1779  PCREDENTIALW CredentialW;
1780 
1781  TRACE("(%p, 0x%x)\n", Credential, Flags);
1782 
1783  if (!Credential || !Credential->TargetName)
1784  {
1786  return FALSE;
1787  }
1788 
1789  len = convert_PCREDENTIALA_to_PCREDENTIALW(Credential, NULL, 0);
1790  CredentialW = heap_alloc(len);
1791  if (!CredentialW)
1792  {
1794  return FALSE;
1795  }
1796 
1797  convert_PCREDENTIALA_to_PCREDENTIALW(Credential, CredentialW, len);
1798 
1799  ret = CredWriteW(CredentialW, Flags);
1800 
1801  heap_free(CredentialW);
1802 
1803  return ret;
1804 }
1805 
1806 /******************************************************************************
1807  * CredWriteW [ADVAPI32.@]
1808  */
1810 {
1811  HKEY hkeyMgr;
1812  HKEY hkeyCred;
1813  DWORD ret;
1814  LPWSTR key_name;
1815  BYTE key_data[KEY_SIZE];
1816 
1817  TRACE("(%p, 0x%x)\n", Credential, Flags);
1818 
1819  if (!Credential || !Credential->TargetName)
1820  {
1822  return FALSE;
1823  }
1824 
1826  {
1827  FIXME("unhandled flags 0x%x\n", Flags);
1829  return FALSE;
1830  }
1831 
1832  if (Credential->Type != CRED_TYPE_GENERIC && Credential->Type != CRED_TYPE_DOMAIN_PASSWORD)
1833  {
1834  FIXME("unhandled type %d\n", Credential->Type);
1836  return FALSE;
1837  }
1838 
1839  TRACE("Credential->Flags = 0x%08x\n", Credential->Flags);
1840  TRACE("Credential->Type = %u\n", Credential->Type);
1841  TRACE("Credential->TargetName = %s\n", debugstr_w(Credential->TargetName));
1842  TRACE("Credential->Comment = %s\n", debugstr_w(Credential->Comment));
1843  TRACE("Credential->Persist = %u\n", Credential->Persist);
1844  TRACE("Credential->TargetAlias = %s\n", debugstr_w(Credential->TargetAlias));
1845  TRACE("Credential->UserName = %s\n", debugstr_w(Credential->UserName));
1846 
1847  if (Credential->Type == CRED_TYPE_DOMAIN_PASSWORD)
1848  {
1849  if (!Credential->UserName ||
1850  (Credential->Persist == CRED_PERSIST_ENTERPRISE &&
1851  (!strchrW(Credential->UserName, '\\') && !strchrW(Credential->UserName, '@'))))
1852  {
1853  ERR("bad username %s\n", debugstr_w(Credential->UserName));
1855  return FALSE;
1856  }
1857  }
1858 
1859 #ifdef __APPLE__
1860  if (!Credential->AttributeCount &&
1861  Credential->Type == CRED_TYPE_DOMAIN_PASSWORD &&
1862  (Credential->Persist == CRED_PERSIST_LOCAL_MACHINE || Credential->Persist == CRED_PERSIST_ENTERPRISE))
1863  {
1864  ret = mac_write_credential(Credential, Flags & CRED_PRESERVE_CREDENTIAL_BLOB);
1865  if (ret != ERROR_SUCCESS)
1866  {
1867  SetLastError(ret);
1868  return FALSE;
1869  }
1870  return TRUE;
1871  }
1872 #endif
1873 
1874  ret = open_cred_mgr_key(&hkeyMgr, FALSE);
1875  if (ret != ERROR_SUCCESS)
1876  {
1877  WARN("couldn't open/create manager key, error %d\n", ret);
1879  return FALSE;
1880  }
1881 
1882  ret = get_cred_mgr_encryption_key(hkeyMgr, key_data);
1883  if (ret != ERROR_SUCCESS)
1884  {
1885  RegCloseKey(hkeyMgr);
1886  SetLastError(ret);
1887  return FALSE;
1888  }
1889 
1890  key_name = get_key_name_for_target(Credential->TargetName, Credential->Type);
1891  ret = RegCreateKeyExW(hkeyMgr, key_name, 0, NULL,
1893  KEY_READ|KEY_WRITE, NULL, &hkeyCred, NULL);
1895  if (ret != ERROR_SUCCESS)
1896  {
1897  TRACE("credentials for target name %s not found\n",
1898  debugstr_w(Credential->TargetName));
1900  return FALSE;
1901  }
1902 
1903  ret = registry_write_credential(hkeyCred, Credential, key_data,
1905 
1906  RegCloseKey(hkeyCred);
1907  RegCloseKey(hkeyMgr);
1908 
1909  if (ret != ERROR_SUCCESS)
1910  {
1911  SetLastError(ret);
1912  return FALSE;
1913  }
1914  return TRUE;
1915 }
1916 
1917 /******************************************************************************
1918  * CredGetSessionTypes [ADVAPI32.@]
1919  */
1921 {
1922  TRACE("(%u, %p)\n", persistCount, persists);
1923 
1924  memset(persists, CRED_PERSIST_NONE, persistCount*sizeof(*persists));
1925  if (CRED_TYPE_GENERIC < persistCount)
1926  {
1928 
1929  if (CRED_TYPE_DOMAIN_PASSWORD < persistCount)
1930  {
1932  }
1933  }
1934  return TRUE;
1935 }
1936 
1937 /******************************************************************************
1938  * CredMarshalCredentialA [ADVAPI32.@]
1939  */
1941 {
1942  BOOL ret;
1943  WCHAR *outW;
1944 
1945  TRACE("%u, %p, %p\n", type, cred, out);
1946 
1947  if ((ret = CredMarshalCredentialW( type, cred, &outW )))
1948  {
1949  int len = WideCharToMultiByte( CP_ACP, 0, outW, -1, NULL, 0, NULL, NULL );
1950  if (!(*out = heap_alloc( len )))
1951  {
1952  heap_free( outW );
1953  return FALSE;
1954  }
1955  WideCharToMultiByte( CP_ACP, 0, outW, -1, *out, len, NULL, NULL );
1956  heap_free( outW );
1957  }
1958  return ret;
1959 }
1960 
1961 static UINT cred_encode( const char *bin, unsigned int len, WCHAR *cred )
1962 {
1963  static const char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#-";
1964  UINT n = 0, x;
1965 
1966  while (len > 0)
1967  {
1968  cred[n++] = enc[bin[0] & 0x3f];
1969  x = (bin[0] & 0xc0) >> 6;
1970  if (len == 1)
1971  {
1972  cred[n++] = enc[x];
1973  break;
1974  }
1975  cred[n++] = enc[((bin[1] & 0xf) << 2) | x];
1976  x = (bin[1] & 0xf0) >> 4;
1977  if (len == 2)
1978  {
1979  cred[n++] = enc[x];
1980  break;
1981  }
1982  cred[n++] = enc[((bin[2] & 0x3) << 4) | x];
1983  cred[n++] = enc[(bin[2] & 0xfc) >> 2];
1984  bin += 3;
1985  len -= 3;
1986  }
1987  return n;
1988 }
1989 
1990 /******************************************************************************
1991  * CredMarshalCredentialW [ADVAPI32.@]
1992  */
1994 {
1995  CERT_CREDENTIAL_INFO *cert = cred;
1997  DWORD len, size;
1998  WCHAR *p;
1999 
2000  TRACE("%u, %p, %p\n", type, cred, out);
2001 
2002  if (!cred || (type == CertCredential && cert->cbSize < sizeof(*cert)) ||
2004  (type == UsernameTargetCredential && (!target->UserName || !target->UserName[0])))
2005  {
2007  return FALSE;
2008  }
2009  switch (type)
2010  {
2011  case CertCredential:
2012  {
2013  size = (sizeof(cert->rgbHashOfCert) + 2) * 4 / 3;
2014  if (!(p = heap_alloc( (size + 4) * sizeof(WCHAR) ))) return FALSE;
2015  p[0] = '@';
2016  p[1] = '@';
2017  p[2] = 'A' + type;
2018  len = cred_encode( (const char *)cert->rgbHashOfCert, sizeof(cert->rgbHashOfCert), p + 3 );
2019  p[len + 3] = 0;
2020  break;
2021  }
2023  {
2024  len = strlenW( target->UserName );
2025  size = (sizeof(DWORD) + len * sizeof(WCHAR) + 2) * 4 / 3;
2026  if (!(p = heap_alloc( (size + 4) * sizeof(WCHAR) ))) return FALSE;
2027  p[0] = '@';
2028  p[1] = '@';
2029  p[2] = 'A' + type;
2030  size = len * sizeof(WCHAR);
2031  len = cred_encode( (const char *)&size, sizeof(DWORD), p + 3 );
2032  len += cred_encode( (const char *)target->UserName, size, p + 3 + len );
2033  p[len + 3] = 0;
2034  break;
2035  }
2036  case BinaryBlobCredential:
2037  FIXME("BinaryBlobCredential not implemented\n");
2038  return FALSE;
2039  default:
2040  return FALSE;
2041  }
2042  *out = p;
2043  return TRUE;
2044 }
2045 
2046 /******************************************************************************
2047  * CredUnmarshalCredentialA [ADVAPI32.@]
2048  */
2050 {
2051  BOOL ret;
2052  WCHAR *credW = NULL;
2053 
2054  TRACE("%s, %p, %p\n", debugstr_a(cred), type, out);
2055 
2056  if (cred)
2057  {
2058  int len = MultiByteToWideChar( CP_ACP, 0, cred, -1, NULL, 0 );
2059  if (!(credW = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
2060  MultiByteToWideChar( CP_ACP, 0, cred, -1, credW, len );
2061  }
2062  ret = CredUnmarshalCredentialW( credW, type, out );
2063  heap_free( credW );
2064  return ret;
2065 }
2066 
2067 static inline char char_decode( WCHAR c )
2068 {
2069  if (c >= 'A' && c <= 'Z') return c - 'A';
2070  if (c >= 'a' && c <= 'z') return c - 'a' + 26;
2071  if (c >= '0' && c <= '9') return c - '0' + 52;
2072  if (c == '#') return 62;
2073  if (c == '-') return 63;
2074  return 64;
2075 }
2076 
2077 static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
2078 {
2079  unsigned int i = 0;
2080  char c0, c1, c2, c3;
2081  const WCHAR *p = cred;
2082 
2083  while (len >= 4)
2084  {
2085  if ((c0 = char_decode( p[0] )) > 63) return FALSE;
2086  if ((c1 = char_decode( p[1] )) > 63) return FALSE;
2087  if ((c2 = char_decode( p[2] )) > 63) return FALSE;
2088  if ((c3 = char_decode( p[3] )) > 63) return FALSE;
2089 
2090  buf[i + 0] = (c1 << 6) | c0;
2091  buf[i + 1] = (c2 << 4) | (c1 >> 2);
2092  buf[i + 2] = (c3 << 2) | (c2 >> 4);
2093  len -= 4;
2094  i += 3;
2095  p += 4;
2096  }
2097  if (len == 3)
2098  {
2099  if ((c0 = char_decode( p[0] )) > 63) return FALSE;
2100  if ((c1 = char_decode( p[1] )) > 63) return FALSE;
2101  if ((c2 = char_decode( p[2] )) > 63) return FALSE;
2102 
2103  buf[i + 0] = (c1 << 6) | c0;
2104  buf[i + 1] = (c2 << 4) | (c1 >> 2);
2105  }
2106  else if (len == 2)
2107  {
2108  if ((c0 = char_decode( p[0] )) > 63) return FALSE;
2109  if ((c1 = char_decode( p[1] )) > 63) return FALSE;
2110 
2111  buf[i + 0] = (c1 << 6) | c0;
2112  }
2113  else if (len == 1)
2114  {
2115  return FALSE;
2116  }
2117  return TRUE;
2118 }
2119 
2120 /******************************************************************************
2121  * CredUnmarshalCredentialW [ADVAPI32.@]
2122  */
2124 {
2125  unsigned int len, buflen;
2126 
2127  TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
2128 
2129  if (!cred || cred[0] != '@' || cred[1] != '@' ||
2130  char_decode( cred[2] ) > 63)
2131  {
2133  return FALSE;
2134  }
2135  len = strlenW( cred + 3 );
2136  *type = char_decode( cred[2] );
2137  switch (*type)
2138  {
2139  case CertCredential:
2140  {
2141  char hash[CERT_HASH_LENGTH];
2143 
2144  if (len != 27 || !cred_decode( cred + 3, len, hash ))
2145  {
2147  return FALSE;
2148  }
2149  if (!(cert = heap_alloc( sizeof(*cert) ))) return FALSE;
2150  memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
2151  cert->cbSize = sizeof(*cert);
2152  *out = cert;
2153  break;
2154  }
2156  {
2158  DWORD size;
2159 
2160  if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
2161  size % sizeof(WCHAR) || len - 6 != (size * 4 + 2) / 3)
2162  {
2164  return FALSE;
2165  }
2166  buflen = sizeof(*target) + size + sizeof(WCHAR);
2167  if (!(target = heap_alloc( buflen ))) return FALSE;
2168  if (!cred_decode( cred + 9, len - 6, (char *)(target + 1) ))
2169  {
2170  heap_free( target );
2171  return FALSE;
2172  }
2173  target->UserName = (WCHAR *)(target + 1);
2174  target->UserName[size / sizeof(WCHAR)] = 0;
2175  *out = target;
2176  break;
2177  }
2178  case BinaryBlobCredential:
2179  FIXME("BinaryBlobCredential not implemented\n");
2180  return FALSE;
2181  default:
2182  WARN("unhandled type %u\n", *type);
2184  return FALSE;
2185  }
2186  return TRUE;
2187 }
2188 
2189 /******************************************************************************
2190  * CredIsMarshaledCredentialW [ADVAPI32.@]
2191  *
2192  * Check, if the name parameter is a marshaled credential, hash or binary blob
2193  *
2194  * PARAMS
2195  * name the name to check
2196  *
2197  * RETURNS
2198  * TRUE: the name parameter is a marshaled credential, hash or binary blob
2199  * FALSE: the name is a plain username
2200  */
2202 {
2203  TRACE("(%s)\n", debugstr_w(name));
2204 
2205  if (name && name[0] == '@' && name[1] == '@' && name[2] > 'A' && name[3])
2206  {
2207  char hash[CERT_HASH_LENGTH];
2208  int len = strlenW(name + 3 );
2209  DWORD size;
2210 
2211  if ((name[2] - 'A') == CertCredential && (len == 27) && cred_decode(name + 3, len, hash))
2212  return TRUE;
2213 
2214  if (((name[2] - 'A') == UsernameTargetCredential) &&
2215  (len >= 9) && cred_decode(name + 3, 6, (char *)&size) && size)
2216  return TRUE;
2217 
2218  if ((name[2] - 'A') == BinaryBlobCredential)
2219  FIXME("BinaryBlobCredential not checked\n");
2220 
2221  if ((name[2] - 'A') > BinaryBlobCredential)
2222  TRACE("unknown type: %d\n", (name[2] - 'A'));
2223  }
2224 
2226  return FALSE;
2227 }
2228 
2229 /******************************************************************************
2230  * CredIsMarshaledCredentialA [ADVAPI32.@]
2231  *
2232  * See CredIsMarshaledCredentialW
2233  *
2234  */
2236 {
2237  LPWSTR nameW = NULL;
2238  BOOL res;
2239  int len;
2240 
2241  TRACE("(%s)\n", debugstr_a(name));
2242 
2243  if (name)
2244  {
2245  len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
2246  nameW = heap_alloc(len * sizeof(WCHAR));
2248  }
2249 
2251  heap_free(nameW);
2252  return res;
2253 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
static const WCHAR wszPersistValue[]
Definition: cred.c:63
#define KEY_SIZE
Definition: cred.c:53
DWORD CredentialBlobSize
Definition: wincred.h:89
static short search(int val, const short *table, int size)
Definition: msg711.c:255
LPBYTE CredentialBlob
Definition: wincred.h:90
static const WCHAR wszTypeValue[]
Definition: cred.c:60
static const WCHAR wszPasswordValue[]
Definition: cred.c:66
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define TRUE
Definition: types.h:120
#define ERROR_NO_SUCH_LOGON_SESSION
Definition: winerror.h:794
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:101
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL WINAPI CredWriteA(PCREDENTIALA Credential, DWORD Flags)
Definition: cred.c:1775
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:95
static const WCHAR wszCommentValue[]
Definition: cred.c:61
#define WINADVAPI
Definition: wincred.h:29
static const WCHAR wszTargetAliasValue[]
Definition: cred.c:64
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_READ
Definition: nt_native.h:1023
Definition: match.c:28
DWORD AttributeCount
Definition: wincred.h:76
NTSYSAPI VOID NTAPI RtlSecondsSince1970ToTime(_In_ ULONG SecondsSince1970, _Out_ PLARGE_INTEGER Time)
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
DWORD UInt32
Definition: chm_lib.c:106
WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD persistCount, LPDWORD persists)
Definition: cred.c:1920
static const WCHAR wszFlagsValue[]
Definition: cred.c:59
#define CP_ACP
Definition: compat.h:99
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
NTSTATUS WINAPI SystemFunction032(struct ustring *data, const struct ustring *key)
Definition: sysfunc.c:533
#define WARN(fmt,...)
Definition: debug.h:111
static BOOL cred_decode(const WCHAR *cred, unsigned int len, char *buf)
Definition: cred.c:2077
#define str_len
Definition: treelist.c:89
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1237
static BOOL registry_credential_matches_filter(HKEY hkeyCred, LPCWSTR filter)
Definition: cred.c:719
GLdouble n
Definition: glext.h:7729
static INT convert_PCREDENTIALW_to_PCREDENTIALA(const CREDENTIALW *CredentialW, PCREDENTIALA CredentialA, DWORD len)
Definition: cred.c:955
static UINT cred_encode(const char *bin, unsigned int len, WCHAR *cred)
Definition: cred.c:1961
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
GLuint buffer
Definition: glext.h:5915
BOOL WINAPI CredEnumerateW(LPCWSTR Filter, DWORD Flags, DWORD *Count, PCREDENTIALW **Credentials)
Definition: cred.c:1289
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
#define NORM_IGNORECASE
Definition: winnls.h:173
#define CRED_PERSIST_NONE
Definition: wincred.h:213
__u16 time
Definition: mkdosfs.c:366
static const WCHAR wszEncryptionKeyValue[]
Definition: cred.c:57
DWORD AttributeCount
Definition: wincred.h:92
#define CRED_PERSIST_LOCAL_MACHINE
Definition: wincred.h:215
char * LPSTR
Definition: xmlstorage.h:182
BOOL WINAPI CredEnumerateA(LPCSTR Filter, DWORD Flags, DWORD *Count, PCREDENTIALA **Credentials)
Definition: cred.c:1226
FILETIME LastWritten
Definition: wincred.h:72
static DWORD write_credential_blob(HKEY hkey, LPCWSTR target_name, DWORD type, const BYTE key_data[KEY_SIZE], const BYTE *credential_blob, DWORD credential_blob_size)
Definition: cred.c:475
int32_t INT
Definition: typedefs.h:56
LPWSTR UserName
Definition: wincred.h:95
unsigned int count
Definition: notification.c:64
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1091
BOOL WINAPI CredWriteW(PCREDENTIALW Credential, DWORD Flags)
Definition: cred.c:1809
struct _test_info info[]
Definition: SetCursorPos.c:19
struct _CREDENTIALW CREDENTIALW
static const WCHAR wszLastWrittenValue[]
Definition: cred.c:62
DWORD Persist
Definition: wincred.h:75
static DWORD get_cred_mgr_encryption_key(HKEY hkeyMgr, BYTE key_data[KEY_SIZE])
Definition: cred.c:639
LPSTR UserName
Definition: wincred.h:79
static const WCHAR wszUserNameValue[]
Definition: cred.c:65
DWORD dwHighDateTime
Definition: mapidefs.h:66
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
enum _CRED_MARSHAL_TYPE CRED_MARSHAL_TYPE
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPSTR TargetAlias
Definition: wincred.h:78
LPSTR TargetName
Definition: wincred.h:70
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
static INT convert_PCREDENTIALA_to_PCREDENTIALW(const CREDENTIALA *CredentialA, PCREDENTIALW CredentialW, INT len)
Definition: cred.c:1046
#define CP_UTF8
Definition: nls.h:20
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI CredReadA(LPCSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALA *Credential)
Definition: cred.c:1403
static DWORD read_credential_blob(HKEY hkey, const BYTE key_data[KEY_SIZE], LPBYTE credential_blob, DWORD *credential_blob_size)
Definition: cred.c:68
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
struct _LARGE_INTEGER::@2201 u
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
NTSYSAPI ULONG NTAPI RtlUniform(_In_ PULONG Seed)
static DWORD
Definition: cred.c:30
smooth NULL
Definition: ftsmooth.c:416
PCREDENTIAL_ATTRIBUTEA Attributes
Definition: wincred.h:77
static BYTE cert[]
Definition: msg.c:1437
Definition: bufpool.h:45
struct match match
Definition: match.c:33
const char * LPCSTR
Definition: xmlstorage.h:183
DWORD CredentialBlobSize
Definition: wincred.h:73
BOOL WINAPI CredUnmarshalCredentialA(LPCSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out)
Definition: cred.c:2049
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define CRED_TYPE_DOMAIN_PASSWORD
Definition: wincred.h:205
static char char_decode(WCHAR c)
Definition: cred.c:2067
static const WCHAR nameW[]
Definition: main.c:46
static WCHAR username[]
Definition: url.c:32
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
BOOL WINAPI CredIsMarshaledCredentialA(LPCSTR name)
Definition: cred.c:2235
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: lang.c:2275
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4895
#define CRED_PERSIST_ENTERPRISE
Definition: wincred.h:216
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
VOID WINAPI CredFree(PVOID Buffer)
Definition: cred.c:1395
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
DWORD Flags
Definition: wincred.h:84
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define debugstr_a
Definition: kernel32.h:31
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static DWORD open_cred_mgr_key(HKEY *hkey, BOOL open_for_write)
Definition: cred.c:632
#define ERROR_BAD_USERNAME
Definition: winerror.h:1200
LPWSTR TargetAlias
Definition: wincred.h:94
LPWSTR TargetName
Definition: wincred.h:86
#define WINAPI
Definition: msvc.h:8
const GLubyte * c
Definition: glext.h:8905
enum _CRED_MARSHAL_TYPE * PCRED_MARSHAL_TYPE
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
BOOL WINAPI CredIsMarshaledCredentialW(LPCWSTR name)
Definition: cred.c:2201
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL WINAPI CredMarshalCredentialW(CRED_MARSHAL_TYPE type, PVOID cred, LPWSTR *out)
Definition: cred.c:1993
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3686
PCREDENTIAL_ATTRIBUTEW Attributes
Definition: wincred.h:93
int ret
WINE_DEFAULT_DEBUG_CHANNEL(cred)
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
BOOL WINAPI CredReadDomainCredentialsA(PCREDENTIAL_TARGET_INFORMATIONA TargetInformation, DWORD Flags, DWORD *Size, PCREDENTIALA **Credentials)
Definition: cred.c:1608
#define CRED_TYPE_GENERIC
Definition: wincred.h:204
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
#define CSTR_EQUAL
Definition: winnls.h:453
WCHAR TargetName[256]
Definition: arping.c:27
Definition: time.h:76
DWORD Type
Definition: wincred.h:85
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
GLsizei const GLfloat * value
Definition: glext.h:6069
DWORD Persist
Definition: wincred.h:91
LONG WINAPI RegEnumKeyW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, DWORD cbName)
Definition: reg.c:2416
#define strcmpiW(s1, s2)
Definition: unicode.h:39
static const WCHAR wszCredentialManagerKey[]
Definition: cred.c:55
#define ERR(fmt,...)
Definition: debug.h:109
BOOL WINAPI CredMarshalCredentialA(CRED_MARSHAL_TYPE type, PVOID cred, LPSTR *out)
Definition: cred.c:1940
struct _CREDENTIALW * PCREDENTIALW
BOOL WINAPI CredUnmarshalCredentialW(LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out)
Definition: cred.c:2123
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
static ATOM item
Definition: dde.c:856
static DWORD registry_read_credential(HKEY hkey, PCREDENTIALW credential, const BYTE key_data[KEY_SIZE], char *buffer, DWORD *len)
Definition: cred.c:103
BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential)
Definition: cred.c:1450
__kernel_time_t time_t
Definition: linux.h:252
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
BOOL WINAPI CredDeleteW(LPCWSTR TargetName, DWORD Type, DWORD Flags)
Definition: cred.c:1165
WINE_UNICODE_INLINE WCHAR * strcatW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:242
DWORD Flags
Definition: wincred.h:68
_CRTIMP time_t __cdecl mktime(struct tm *_Tm)
Definition: time.h:426
struct _CREDENTIALA CREDENTIALA
static LPWSTR get_key_name_for_target(LPCWSTR target_name, DWORD type)
Definition: cred.c:687
Definition: config.c:18
unsigned int UINT
Definition: ndis.h:50
#define CERT_HASH_LENGTH
Definition: wincred.h:160
#define ERROR_NOT_FOUND
Definition: winerror.h:690
LPSTR Comment
Definition: wincred.h:71
#define MultiByteToWideChar
Definition: compat.h:100
static struct _PeImage bin
Definition: name.c:36
GLuint res
Definition: glext.h:9613
FILETIME LastWritten
Definition: wincred.h:88
static DWORD registry_write_credential(HKEY hkey, const CREDENTIALW *credential, const BYTE key_data[KEY_SIZE], BOOL preserve_blob)
Definition: cred.c:501
uint32_t * LPDWORD
Definition: typedefs.h:57
DWORD Type
Definition: wincred.h:69
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
static DWORD registry_enumerate_credentials(HKEY hkeyMgr, LPCWSTR filter, LPWSTR target_name, DWORD target_name_len, const BYTE key_data[KEY_SIZE], PCREDENTIALW *credentials, char **buffer, DWORD *len, DWORD *count)
Definition: cred.c:757
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
struct _CREDENTIALA * PCREDENTIALA
GLuint GLenum GLenum GLenum GLenum outW
Definition: glext.h:9616
BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATIONW TargetInformation, DWORD Flags, DWORD *Size, PCREDENTIALW **Credentials)
Definition: cred.c:1754
Definition: _hash_fun.h:40
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
DWORD dwLowDateTime
Definition: mapidefs.h:65
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1449
LPWSTR Comment
Definition: wincred.h:87
#define CRED_PERSIST_SESSION
Definition: wincred.h:214
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define CRED_PRESERVE_CREDENTIAL_BLOB
Definition: wincred.h:242
Definition: path.c:42
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define ERROR_REGISTRY_CORRUPT
Definition: winerror.h:594
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97
BOOL WINAPI CredDeleteA(LPCSTR TargetName, DWORD Type, DWORD Flags)
Definition: cred.c:1132