1 /* 2 * ReactOS kernel 3 * Copyright (C) 2004 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* $Id$ 20 * 21 * COPYRIGHT: See COPYING in the top level directory 22 * PROJECT: ReactOS system libraries 23 * PURPOSE: SAM interface library 24 * FILE: lib/samlib/samlib.c 25 * PROGRAMER: Eric Kohl 26 */ 27 28 /* INCLUDES *****************************************************************/ 29 #define WIN32_NO_STATUS 30 #include <windows.h> 31 #include <winerror.h> 32 #define NTOS_MODE_USER 33 #include <ndk/ntndk.h> 34 35 #define NDEBUG 36 #include "debug.h" 37 38 39 /* GLOBALS *******************************************************************/ 40 41 42 /* FUNCTIONS *****************************************************************/ 43 44 45 static BOOL 46 CreateBuiltinAliases (HKEY hAliasesKey) 47 { 48 return TRUE; 49 } 50 51 52 static BOOL 53 CreateBuiltinGroups (HKEY hGroupsKey) 54 { 55 return TRUE; 56 } 57 58 59 static BOOL 60 CreateBuiltinUsers (HKEY hUsersKey) 61 { 62 return TRUE; 63 } 64 65 66 BOOL WINAPI 67 SamInitializeSAM (VOID) 68 { 69 DWORD dwDisposition; 70 HKEY hSamKey; 71 HKEY hDomainsKey; 72 HKEY hAccountKey; 73 HKEY hBuiltinKey; 74 HKEY hAliasesKey; 75 HKEY hGroupsKey; 76 HKEY hUsersKey; 77 78 DPRINT("SamInitializeSAM() called\n"); 79 80 if (RegCreateKeyExW (HKEY_LOCAL_MACHINE, 81 L"SAM\\SAM", 82 0, 83 NULL, 84 REG_OPTION_NON_VOLATILE, 85 KEY_ALL_ACCESS, 86 NULL, 87 &hSamKey, 88 &dwDisposition)) 89 { 90 DPRINT1 ("Failed to create 'Sam' key! (Error %lu)\n", GetLastError()); 91 return FALSE; 92 } 93 94 if (RegCreateKeyExW (hSamKey, 95 L"Domains", 96 0, 97 NULL, 98 REG_OPTION_NON_VOLATILE, 99 KEY_ALL_ACCESS, 100 NULL, 101 &hDomainsKey, 102 &dwDisposition)) 103 { 104 DPRINT1 ("Failed to create 'Domains' key! (Error %lu)\n", GetLastError()); 105 RegCloseKey (hSamKey); 106 return FALSE; 107 } 108 109 RegCloseKey (hSamKey); 110 111 /* Create the 'Domains\\Account' key */ 112 if (RegCreateKeyExW (hDomainsKey, 113 L"Account", 114 0, 115 NULL, 116 REG_OPTION_NON_VOLATILE, 117 KEY_ALL_ACCESS, 118 NULL, 119 &hAccountKey, 120 &dwDisposition)) 121 { 122 DPRINT1 ("Failed to create 'Domains\\Account' key! (Error %lu)\n", GetLastError()); 123 RegCloseKey (hDomainsKey); 124 return FALSE; 125 } 126 127 128 /* Create the 'Account\Aliases' key */ 129 if (RegCreateKeyExW (hAccountKey, 130 L"Aliases", 131 0, 132 NULL, 133 REG_OPTION_NON_VOLATILE, 134 KEY_ALL_ACCESS, 135 NULL, 136 &hAliasesKey, 137 &dwDisposition)) 138 { 139 DPRINT1 ("Failed to create 'Account\\Aliases' key! (Error %lu)\n", GetLastError()); 140 RegCloseKey (hAccountKey); 141 RegCloseKey (hDomainsKey); 142 return FALSE; 143 } 144 145 RegCloseKey (hAliasesKey); 146 147 148 /* Create the 'Account\Groups' key */ 149 if (RegCreateKeyExW (hAccountKey, 150 L"Groups", 151 0, 152 NULL, 153 REG_OPTION_NON_VOLATILE, 154 KEY_ALL_ACCESS, 155 NULL, 156 &hGroupsKey, 157 &dwDisposition)) 158 { 159 DPRINT1 ("Failed to create 'Account\\Groups' key! (Error %lu)\n", GetLastError()); 160 RegCloseKey (hAccountKey); 161 RegCloseKey (hDomainsKey); 162 return FALSE; 163 } 164 165 RegCloseKey (hGroupsKey); 166 167 168 /* Create the 'Account\Users' key */ 169 if (RegCreateKeyExW (hAccountKey, 170 L"Users", 171 0, 172 NULL, 173 REG_OPTION_NON_VOLATILE, 174 KEY_ALL_ACCESS, 175 NULL, 176 &hUsersKey, 177 &dwDisposition)) 178 { 179 DPRINT1 ("Failed to create 'Account\\Users' key! (Error %lu)\n", GetLastError()); 180 RegCloseKey (hAccountKey); 181 RegCloseKey (hDomainsKey); 182 return FALSE; 183 } 184 185 RegCloseKey (hUsersKey); 186 187 RegCloseKey (hAccountKey); 188 189 190 /* Create the 'Domains\\Builtin' */ 191 if (RegCreateKeyExW (hDomainsKey, 192 L"Builtin", 193 0, 194 NULL, 195 REG_OPTION_NON_VOLATILE, 196 KEY_ALL_ACCESS, 197 NULL, 198 &hBuiltinKey, 199 &dwDisposition)) 200 { 201 DPRINT1 ("Failed to create Builtin key! (Error %lu)\n", GetLastError()); 202 RegCloseKey (hDomainsKey); 203 return FALSE; 204 } 205 206 207 /* Create the 'Builtin\Aliases' key */ 208 if (RegCreateKeyExW (hBuiltinKey, 209 L"Aliases", 210 0, 211 NULL, 212 REG_OPTION_NON_VOLATILE, 213 KEY_ALL_ACCESS, 214 NULL, 215 &hAliasesKey, 216 &dwDisposition)) 217 { 218 DPRINT1 ("Failed to create 'Builtin\\Aliases' key! (Error %lu)\n", GetLastError()); 219 RegCloseKey (hBuiltinKey); 220 RegCloseKey (hDomainsKey); 221 return FALSE; 222 } 223 224 /* Create builtin aliases */ 225 if (!CreateBuiltinAliases (hAliasesKey)) 226 { 227 DPRINT1 ("Failed to create builtin aliases!\n"); 228 RegCloseKey (hAliasesKey); 229 RegCloseKey (hBuiltinKey); 230 RegCloseKey (hDomainsKey); 231 return FALSE; 232 } 233 234 RegCloseKey (hAliasesKey); 235 236 237 /* Create the 'Builtin\Groups' key */ 238 if (RegCreateKeyExW (hBuiltinKey, 239 L"Groups", 240 0, 241 NULL, 242 REG_OPTION_NON_VOLATILE, 243 KEY_ALL_ACCESS, 244 NULL, 245 &hGroupsKey, 246 &dwDisposition)) 247 { 248 DPRINT1 ("Failed to create 'Builtin\\Groups' key! (Error %lu)\n", GetLastError()); 249 RegCloseKey (hBuiltinKey); 250 RegCloseKey (hDomainsKey); 251 return FALSE; 252 } 253 254 /* Create builtin groups */ 255 if (!CreateBuiltinGroups (hGroupsKey)) 256 { 257 DPRINT1 ("Failed to create builtin groups!\n"); 258 RegCloseKey (hGroupsKey); 259 RegCloseKey (hBuiltinKey); 260 RegCloseKey (hDomainsKey); 261 return FALSE; 262 } 263 264 RegCloseKey (hGroupsKey); 265 266 267 /* Create the 'Builtin\Users' key */ 268 if (RegCreateKeyExW (hBuiltinKey, 269 L"Users", 270 0, 271 NULL, 272 REG_OPTION_NON_VOLATILE, 273 KEY_ALL_ACCESS, 274 NULL, 275 &hUsersKey, 276 &dwDisposition)) 277 { 278 DPRINT1 ("Failed to create 'Builtin\\Users' key! (Error %lu)\n", GetLastError()); 279 RegCloseKey (hBuiltinKey); 280 RegCloseKey (hDomainsKey); 281 return FALSE; 282 } 283 284 /* Create builtin users */ 285 if (!CreateBuiltinUsers (hUsersKey)) 286 { 287 DPRINT1 ("Failed to create builtin users!\n"); 288 RegCloseKey (hUsersKey); 289 RegCloseKey (hBuiltinKey); 290 RegCloseKey (hDomainsKey); 291 return FALSE; 292 } 293 294 RegCloseKey (hUsersKey); 295 296 RegCloseKey (hBuiltinKey); 297 298 RegCloseKey (hDomainsKey); 299 300 DPRINT ("SamInitializeSAM() done\n"); 301 302 return TRUE; 303 } 304 305 306 BOOL WINAPI 307 SamGetDomainSid (PSID *Sid) 308 { 309 DPRINT ("SamGetDomainSid() called\n"); 310 311 return FALSE; 312 } 313 314 315 BOOL WINAPI 316 SamSetDomainSid (PSID Sid) 317 { 318 HKEY hAccountKey; 319 320 DPRINT ("SamSetDomainSid() called\n"); 321 322 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, 323 L"SAM\\SAM\\Domains\\Account", 324 0, 325 KEY_ALL_ACCESS, 326 &hAccountKey)) 327 { 328 DPRINT1 ("Failed to open the Account key! (Error %lu)\n", GetLastError()); 329 return FALSE; 330 } 331 332 if (RegSetValueExW (hAccountKey, 333 L"Sid", 334 0, 335 REG_BINARY, 336 (LPBYTE)Sid, 337 RtlLengthSid (Sid))) 338 { 339 DPRINT1 ("Failed to set Domain-SID value! (Error %lu)\n", GetLastError()); 340 RegCloseKey (hAccountKey); 341 return FALSE; 342 } 343 344 RegCloseKey (hAccountKey); 345 346 DPRINT ("SamSetDomainSid() called\n"); 347 348 return TRUE; 349 } 350 351 352 /* 353 * ERROR_USER_EXISTS 354 */ 355 BOOL WINAPI 356 SamCreateUser (PWSTR UserName, 357 PWSTR UserPassword, 358 PSID UserSid) 359 { 360 DWORD dwDisposition; 361 HKEY hUsersKey; 362 HKEY hUserKey; 363 364 DPRINT ("SamCreateUser() called\n"); 365 366 /* FIXME: Check whether the SID is a real user sid */ 367 368 /* Open the Users key */ 369 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, 370 L"SAM\\SAM\\Domains\\Account\\Users", 371 0, 372 KEY_ALL_ACCESS, 373 &hUsersKey)) 374 { 375 DPRINT1 ("Failed to open Account key! (Error %lu)\n", GetLastError()); 376 return FALSE; 377 } 378 379 /* Create user name key */ 380 if (RegCreateKeyExW (hUsersKey, 381 UserName, 382 0, 383 NULL, 384 REG_OPTION_NON_VOLATILE, 385 KEY_ALL_ACCESS, 386 NULL, 387 &hUserKey, 388 &dwDisposition)) 389 { 390 DPRINT1 ("Failed to create/open the user key! (Error %lu)\n", GetLastError()); 391 RegCloseKey (hUsersKey); 392 return FALSE; 393 } 394 395 RegCloseKey (hUsersKey); 396 397 if (dwDisposition == REG_OPENED_EXISTING_KEY) 398 { 399 DPRINT1 ("User already exists!\n"); 400 RegCloseKey (hUserKey); 401 SetLastError (ERROR_USER_EXISTS); 402 return FALSE; 403 } 404 405 406 /* Set 'Name' value */ 407 if (RegSetValueExW (hUserKey, 408 L"Name", 409 0, 410 REG_SZ, 411 (LPBYTE)UserName, 412 (wcslen (UserName) + 1) * sizeof (WCHAR))) 413 { 414 DPRINT1 ("Failed to set the user name value! (Error %lu)\n", GetLastError()); 415 RegCloseKey (hUserKey); 416 return FALSE; 417 } 418 419 /* Set 'Password' value */ 420 if (RegSetValueExW (hUserKey, 421 L"Password", 422 0, 423 REG_SZ, 424 (LPBYTE)UserPassword, 425 (wcslen (UserPassword) + 1) * sizeof (WCHAR))) 426 { 427 DPRINT1 ("Failed to set the user name value! (Error %lu)\n", GetLastError()); 428 RegCloseKey (hUserKey); 429 return FALSE; 430 } 431 432 /* Set 'Sid' value */ 433 if (RegSetValueExW (hUserKey, 434 L"Sid", 435 0, 436 REG_BINARY, 437 (LPBYTE)UserSid, 438 RtlLengthSid (UserSid))) 439 { 440 DPRINT1 ("Failed to set the user SID value! (Error %lu)\n", GetLastError()); 441 RegCloseKey (hUserKey); 442 return FALSE; 443 } 444 445 RegCloseKey (hUserKey); 446 447 DPRINT ("SamCreateUser() done\n"); 448 449 return TRUE; 450 } 451 452 453 /* 454 * ERROR_WRONG_PASSWORD 455 * ERROR_NO_SUCH_USER 456 */ 457 BOOL WINAPI 458 SamCheckUserPassword (PWSTR UserName, 459 PWSTR UserPassword) 460 { 461 WCHAR szPassword[256]; 462 DWORD dwLength; 463 HKEY hUsersKey; 464 HKEY hUserKey; 465 466 DPRINT ("SamCheckUserPassword() called\n"); 467 468 /* Open the Users key */ 469 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, 470 L"SAM\\SAM\\Domains\\Account\\Users", 471 0, 472 KEY_READ, 473 &hUsersKey)) 474 { 475 DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError()); 476 return FALSE; 477 } 478 479 /* Open the user key */ 480 if (RegOpenKeyExW (hUsersKey, 481 UserName, 482 0, 483 KEY_READ, 484 &hUserKey)) 485 { 486 if (GetLastError () == ERROR_FILE_NOT_FOUND) 487 { 488 DPRINT1 ("Invalid user name!\n"); 489 SetLastError (ERROR_NO_SUCH_USER); 490 } 491 else 492 { 493 DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError()); 494 } 495 496 RegCloseKey (hUsersKey); 497 return FALSE; 498 } 499 500 RegCloseKey (hUsersKey); 501 502 /* Get the password */ 503 dwLength = 256 * sizeof(WCHAR); 504 if (RegQueryValueExW (hUserKey, 505 L"Password", 506 NULL, 507 NULL, 508 (LPBYTE)szPassword, 509 &dwLength)) 510 { 511 DPRINT1 ("Failed to read the password! (Error %lu)\n", GetLastError()); 512 RegCloseKey (hUserKey); 513 return FALSE; 514 } 515 516 RegCloseKey (hUserKey); 517 518 /* Compare passwords */ 519 if ((wcslen (szPassword) != wcslen (UserPassword)) || 520 (wcscmp (szPassword, UserPassword) != 0)) 521 { 522 DPRINT1 ("Wrong password!\n"); 523 SetLastError (ERROR_WRONG_PASSWORD); 524 return FALSE; 525 } 526 527 DPRINT ("SamCheckUserPassword() done\n"); 528 529 return TRUE; 530 } 531 532 533 BOOL WINAPI 534 SamGetUserSid (PWSTR UserName, 535 PSID *Sid) 536 { 537 PSID lpSid; 538 DWORD dwLength; 539 HKEY hUsersKey; 540 HKEY hUserKey; 541 542 DPRINT ("SamGetUserSid() called\n"); 543 544 if (Sid != NULL) 545 *Sid = NULL; 546 547 /* Open the Users key */ 548 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, 549 L"SAM\\SAM\\Domains\\Account\\Users", 550 0, 551 KEY_READ, 552 &hUsersKey)) 553 { 554 DPRINT1 ("Failed to open Users key! (Error %lu)\n", GetLastError()); 555 return FALSE; 556 } 557 558 /* Open the user key */ 559 if (RegOpenKeyExW (hUsersKey, 560 UserName, 561 0, 562 KEY_READ, 563 &hUserKey)) 564 { 565 if (GetLastError () == ERROR_FILE_NOT_FOUND) 566 { 567 DPRINT1 ("Invalid user name!\n"); 568 SetLastError (ERROR_NO_SUCH_USER); 569 } 570 else 571 { 572 DPRINT1 ("Failed to open user key! (Error %lu)\n", GetLastError()); 573 } 574 575 RegCloseKey (hUsersKey); 576 return FALSE; 577 } 578 579 RegCloseKey (hUsersKey); 580 581 /* Get SID size */ 582 dwLength = 0; 583 if (RegQueryValueExW (hUserKey, 584 L"Sid", 585 NULL, 586 NULL, 587 NULL, 588 &dwLength)) 589 { 590 DPRINT1 ("Failed to read the SID size! (Error %lu)\n", GetLastError()); 591 RegCloseKey (hUserKey); 592 return FALSE; 593 } 594 595 /* Allocate sid buffer */ 596 DPRINT ("Required SID buffer size: %lu\n", dwLength); 597 lpSid = (PSID)RtlAllocateHeap (RtlGetProcessHeap (), 598 0, 599 dwLength); 600 if (lpSid == NULL) 601 { 602 DPRINT1 ("Failed to allocate SID buffer!\n"); 603 RegCloseKey (hUserKey); 604 return FALSE; 605 } 606 607 /* Read sid */ 608 if (RegQueryValueExW (hUserKey, 609 L"Sid", 610 NULL, 611 NULL, 612 (LPBYTE)lpSid, 613 &dwLength)) 614 { 615 DPRINT1 ("Failed to read the SID! (Error %lu)\n", GetLastError()); 616 RtlFreeHeap (RtlGetProcessHeap (), 617 0, 618 lpSid); 619 RegCloseKey (hUserKey); 620 return FALSE; 621 } 622 623 RegCloseKey (hUserKey); 624 625 *Sid = lpSid; 626 627 DPRINT ("SamGetUserSid() done\n"); 628 629 return TRUE; 630 } 631 632 /* EOF */ 633