00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 #undef DBGC_CLASS
00027 #define DBGC_CLASS DBGC_AUTH
00028
00029
00030 static fstring this_user;
00031 #if !defined(WITH_PAM)
00032 static fstring this_salt;
00033 static fstring this_crypted;
00034 #endif
00035
00036 #ifdef WITH_AFS
00037
00038 #include <afs/stds.h>
00039 #include <afs/kautils.h>
00040
00041
00042
00043
00044 static BOOL afs_auth(char *user, char *password)
00045 {
00046 long password_expires = 0;
00047 char *reason;
00048
00049
00050
00051 setpag();
00052 if (ka_UserAuthenticateGeneral
00053 (KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG, user, (char *)0,
00054 (char *)0,
00055 password, 0,
00056 &password_expires,
00057 0,
00058 &reason) == 0)
00059 {
00060 return (True);
00061 }
00062 DEBUG(1,
00063 ("AFS authentication for \"%s\" failed (%s)\n", user, reason));
00064 return (False);
00065 }
00066 #endif
00067
00068
00069 #ifdef WITH_DFS
00070
00071 #include <dce/dce_error.h>
00072 #include <dce/sec_login.h>
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 sec_login_handle_t my_dce_sec_context;
00088 int dcelogin_atmost_once = 0;
00089
00090
00091
00092
00093 static BOOL dfs_auth(char *user, char *password)
00094 {
00095 struct tm *t;
00096 error_status_t err;
00097 int err2;
00098 int prterr;
00099 signed32 expire_time, current_time;
00100 boolean32 password_reset;
00101 struct passwd *pw;
00102 sec_passwd_rec_t passwd_rec;
00103 sec_login_auth_src_t auth_src = sec_login_auth_src_network;
00104 unsigned char dce_errstr[dce_c_error_string_len];
00105 gid_t egid;
00106
00107 if (dcelogin_atmost_once)
00108 return (False);
00109
00110 #ifdef HAVE_CRYPT
00111
00112
00113
00114
00115
00116
00117 if (strcmp((char *)crypt(password, this_salt), this_crypted))
00118 {
00119 return (False);
00120 }
00121 #endif
00122
00123 sec_login_get_current_context(&my_dce_sec_context, &err);
00124 if (err != error_status_ok)
00125 {
00126 dce_error_inq_text(err, dce_errstr, &err2);
00127 DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));
00128
00129 return (False);
00130 }
00131
00132 sec_login_certify_identity(my_dce_sec_context, &err);
00133 if (err != error_status_ok)
00134 {
00135 dce_error_inq_text(err, dce_errstr, &err2);
00136 DEBUG(0, ("DCE can't get current context. %s\n", dce_errstr));
00137
00138 return (False);
00139 }
00140
00141 sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
00142 if (err != error_status_ok)
00143 {
00144 dce_error_inq_text(err, dce_errstr, &err2);
00145 DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));
00146
00147 return (False);
00148 }
00149
00150 time(¤t_time);
00151
00152 if (expire_time < (current_time + 60))
00153 {
00154 struct passwd *pw;
00155 sec_passwd_rec_t *key;
00156
00157 sec_login_get_pwent(my_dce_sec_context,
00158 (sec_login_passwd_t *) & pw, &err);
00159 if (err != error_status_ok)
00160 {
00161 dce_error_inq_text(err, dce_errstr, &err2);
00162 DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
00163
00164 return (False);
00165 }
00166
00167 sec_login_refresh_identity(my_dce_sec_context, &err);
00168 if (err != error_status_ok)
00169 {
00170 dce_error_inq_text(err, dce_errstr, &err2);
00171 DEBUG(0, ("DCE can't refresh identity. %s\n",
00172 dce_errstr));
00173
00174 return (False);
00175 }
00176
00177 sec_key_mgmt_get_key(rpc_c_authn_dce_secret, NULL,
00178 (unsigned char *)pw->pw_name,
00179 sec_c_key_version_none,
00180 (void **)&key, &err);
00181 if (err != error_status_ok)
00182 {
00183 dce_error_inq_text(err, dce_errstr, &err2);
00184 DEBUG(0, ("DCE can't get key for %s. %s\n",
00185 pw->pw_name, dce_errstr));
00186
00187 return (False);
00188 }
00189
00190 sec_login_valid_and_cert_ident(my_dce_sec_context, key,
00191 &password_reset, &auth_src,
00192 &err);
00193 if (err != error_status_ok)
00194 {
00195 dce_error_inq_text(err, dce_errstr, &err2);
00196 DEBUG(0,
00197 ("DCE can't validate and certify identity for %s. %s\n",
00198 pw->pw_name, dce_errstr));
00199 }
00200
00201 sec_key_mgmt_free_key(key, &err);
00202 if (err != error_status_ok)
00203 {
00204 dce_error_inq_text(err, dce_errstr, &err2);
00205 DEBUG(0, ("DCE can't free key.\n", dce_errstr));
00206 }
00207 }
00208
00209 if (sec_login_setup_identity((unsigned char *)user,
00210 sec_login_no_flags,
00211 &my_dce_sec_context, &err) == 0)
00212 {
00213 dce_error_inq_text(err, dce_errstr, &err2);
00214 DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",
00215 user, dce_errstr));
00216 return (False);
00217 }
00218
00219 sec_login_get_pwent(my_dce_sec_context,
00220 (sec_login_passwd_t *) & pw, &err);
00221 if (err != error_status_ok)
00222 {
00223 dce_error_inq_text(err, dce_errstr, &err2);
00224 DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
00225
00226 return (False);
00227 }
00228
00229 sec_login_purge_context(&my_dce_sec_context, &err);
00230 if (err != error_status_ok)
00231 {
00232 dce_error_inq_text(err, dce_errstr, &err2);
00233 DEBUG(0, ("DCE can't purge context. %s\n", dce_errstr));
00234
00235 return (False);
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 egid = getegid();
00248
00249 set_effective_gid(pw->pw_gid);
00250 set_effective_uid(pw->pw_uid);
00251
00252 if (sec_login_setup_identity((unsigned char *)user,
00253 sec_login_no_flags,
00254 &my_dce_sec_context, &err) == 0)
00255 {
00256 dce_error_inq_text(err, dce_errstr, &err2);
00257 DEBUG(0, ("DCE Setup Identity for %s failed: %s\n",
00258 user, dce_errstr));
00259 goto err;
00260 }
00261
00262 sec_login_get_pwent(my_dce_sec_context,
00263 (sec_login_passwd_t *) & pw, &err);
00264 if (err != error_status_ok)
00265 {
00266 dce_error_inq_text(err, dce_errstr, &err2);
00267 DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
00268 goto err;
00269 }
00270
00271 passwd_rec.version_number = sec_passwd_c_version_none;
00272 passwd_rec.pepper = NULL;
00273 passwd_rec.key.key_type = sec_passwd_plain;
00274 passwd_rec.key.tagged_union.plain = (idl_char *) password;
00275
00276 sec_login_validate_identity(my_dce_sec_context,
00277 &passwd_rec, &password_reset,
00278 &auth_src, &err);
00279 if (err != error_status_ok)
00280 {
00281 dce_error_inq_text(err, dce_errstr, &err2);
00282 DEBUG(0,
00283 ("DCE Identity Validation failed for principal %s: %s\n",
00284 user, dce_errstr));
00285 goto err;
00286 }
00287
00288 sec_login_certify_identity(my_dce_sec_context, &err);
00289 if (err != error_status_ok)
00290 {
00291 dce_error_inq_text(err, dce_errstr, &err2);
00292 DEBUG(0, ("DCE certify identity failed: %s\n", dce_errstr));
00293 goto err;
00294 }
00295
00296 if (auth_src != sec_login_auth_src_network)
00297 {
00298 DEBUG(0, ("DCE context has no network credentials.\n"));
00299 }
00300
00301 sec_login_set_context(my_dce_sec_context, &err);
00302 if (err != error_status_ok)
00303 {
00304 dce_error_inq_text(err, dce_errstr, &err2);
00305 DEBUG(0,
00306 ("DCE login failed for principal %s, cant set context: %s\n",
00307 user, dce_errstr));
00308
00309 sec_login_purge_context(&my_dce_sec_context, &err);
00310 goto err;
00311 }
00312
00313 sec_login_get_pwent(my_dce_sec_context,
00314 (sec_login_passwd_t *) & pw, &err);
00315 if (err != error_status_ok)
00316 {
00317 dce_error_inq_text(err, dce_errstr, &err2);
00318 DEBUG(0, ("DCE can't get pwent. %s\n", dce_errstr));
00319 goto err;
00320 }
00321
00322 DEBUG(0, ("DCE login succeeded for principal %s on pid %d\n",
00323 user, sys_getpid()));
00324
00325 DEBUG(3, ("DCE principal: %s\n"
00326 " uid: %d\n"
00327 " gid: %d\n",
00328 pw->pw_name, pw->pw_uid, pw->pw_gid));
00329 DEBUG(3, (" info: %s\n"
00330 " dir: %s\n"
00331 " shell: %s\n",
00332 pw->pw_gecos, pw->pw_dir, pw->pw_shell));
00333
00334 sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
00335 if (err != error_status_ok)
00336 {
00337 dce_error_inq_text(err, dce_errstr, &err2);
00338 DEBUG(0, ("DCE can't get expiration. %s\n", dce_errstr));
00339 goto err;
00340 }
00341
00342 set_effective_uid(0);
00343 set_effective_gid(0);
00344
00345 t = localtime(&expire_time);
00346 if (t) {
00347 const char *asct = asctime(t);
00348 if (asct) {
00349 DEBUG(0,("DCE context expires: %s", asct));
00350 }
00351 }
00352
00353 dcelogin_atmost_once = 1;
00354 return (True);
00355
00356 err:
00357
00358
00359 set_effective_uid(0);
00360 set_effective_gid(egid);
00361 return (False);
00362 }
00363
00364 void dfs_unlogin(void)
00365 {
00366 error_status_t err;
00367 int err2;
00368 unsigned char dce_errstr[dce_c_error_string_len];
00369
00370 sec_login_purge_context(&my_dce_sec_context, &err);
00371 if (err != error_status_ok)
00372 {
00373 dce_error_inq_text(err, dce_errstr, &err2);
00374 DEBUG(0,
00375 ("DCE purge login context failed for server instance %d: %s\n",
00376 sys_getpid(), dce_errstr));
00377 }
00378 }
00379 #endif
00380
00381 #ifdef LINUX_BIGCRYPT
00382
00383
00384
00385 static int linux_bigcrypt(char *password, char *salt1, char *crypted)
00386 {
00387 #define LINUX_PASSWORD_SEG_CHARS 8
00388 char salt[3];
00389 int i;
00390
00391 StrnCpy(salt, salt1, 2);
00392 crypted += 2;
00393
00394 for (i = strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) {
00395 char *p = crypt(password, salt) + 2;
00396 if (strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0)
00397 return (0);
00398 password += LINUX_PASSWORD_SEG_CHARS;
00399 crypted += strlen(p);
00400 }
00401
00402 return (1);
00403 }
00404 #endif
00405
00406 #ifdef OSF1_ENH_SEC
00407
00408
00409
00410 static char *osf1_bigcrypt(char *password, char *salt1)
00411 {
00412 static char result[AUTH_MAX_PASSWD_LENGTH] = "";
00413 char *p1;
00414 char *p2 = password;
00415 char salt[3];
00416 int i;
00417 int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS;
00418 if (strlen(password) % AUTH_CLEARTEXT_SEG_CHARS)
00419 parts++;
00420
00421 StrnCpy(salt, salt1, 2);
00422 StrnCpy(result, salt1, 2);
00423 result[2] = '\0';
00424
00425 for (i = 0; i < parts; i++) {
00426 p1 = crypt(p2, salt);
00427 strncat(result, p1 + 2,
00428 AUTH_MAX_PASSWD_LENGTH - strlen(p1 + 2) - 1);
00429 StrnCpy(salt, &result[2 + i * AUTH_CIPHERTEXT_SEG_CHARS], 2);
00430 p2 += AUTH_CLEARTEXT_SEG_CHARS;
00431 }
00432
00433 return (result);
00434 }
00435 #endif
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *),
00446 int N)
00447 {
00448 int len = strlen(s);
00449 int i;
00450 NTSTATUS nt_status;
00451
00452 #ifdef PASSWORD_LENGTH
00453 len = MIN(len, PASSWORD_LENGTH);
00454 #endif
00455
00456 if (N <= 0 || offset >= len)
00457 return (fn(s));
00458
00459 for (i = offset; i < (len - (N - 1)); i++) {
00460 char c = s[i];
00461 if (!islower_ascii(c))
00462 continue;
00463 s[i] = toupper_ascii(c);
00464 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) {
00465 return (nt_status);
00466 }
00467 s[i] = c;
00468 }
00469 return (NT_STATUS_WRONG_PASSWORD);
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479 static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N)
00480 {
00481 int n;
00482 NTSTATUS nt_status;
00483 for (n = 1; n <= N; n++)
00484 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, 0, fn, n), NT_STATUS_WRONG_PASSWORD))
00485 return nt_status;
00486 return NT_STATUS_WRONG_PASSWORD;
00487 }
00488
00489
00490
00491
00492
00493 static NTSTATUS password_check(const char *password)
00494 {
00495 #ifdef WITH_PAM
00496 return smb_pam_passcheck(this_user, password);
00497 #else
00498
00499 BOOL ret;
00500
00501 #ifdef WITH_AFS
00502 if (afs_auth(this_user, password))
00503 return NT_STATUS_OK;
00504 #endif
00505
00506 #ifdef WITH_DFS
00507 if (dfs_auth(this_user, password))
00508 return NT_STATUS_OK;
00509 #endif
00510
00511 #ifdef OSF1_ENH_SEC
00512
00513 ret = (strcmp(osf1_bigcrypt(password, this_salt),
00514 this_crypted) == 0);
00515 if (!ret) {
00516 DEBUG(2,
00517 ("OSF1_ENH_SEC failed. Trying normal crypt.\n"));
00518 ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
00519 }
00520 if (ret) {
00521 return NT_STATUS_OK;
00522 } else {
00523 return NT_STATUS_WRONG_PASSWORD;
00524 }
00525
00526 #endif
00527
00528 #ifdef ULTRIX_AUTH
00529 ret = (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
00530 if (ret) {
00531 return NT_STATUS_OK;
00532 } else {
00533 return NT_STATUS_WRONG_PASSWORD;
00534 }
00535
00536 #endif
00537
00538 #ifdef LINUX_BIGCRYPT
00539 ret = (linux_bigcrypt(password, this_salt, this_crypted));
00540 if (ret) {
00541 return NT_STATUS_OK;
00542 } else {
00543 return NT_STATUS_WRONG_PASSWORD;
00544 }
00545 #endif
00546
00547 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
00548
00549
00550
00551
00552
00553
00554
00555
00556 if (strcmp(bigcrypt(password, this_salt), this_crypted) == 0)
00557 return NT_STATUS_OK;
00558 else
00559 ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
00560 if (ret) {
00561 return NT_STATUS_OK;
00562 } else {
00563 return NT_STATUS_WRONG_PASSWORD;
00564 }
00565 #else
00566
00567 #ifdef HAVE_BIGCRYPT
00568 ret = (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
00569 if (ret) {
00570 return NT_STATUS_OK;
00571 } else {
00572 return NT_STATUS_WRONG_PASSWORD;
00573 }
00574 #endif
00575
00576 #ifndef HAVE_CRYPT
00577 DEBUG(1, ("Warning - no crypt available\n"));
00578 return NT_STATUS_LOGON_FAILURE;
00579 #else
00580 ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
00581 if (ret) {
00582 return NT_STATUS_OK;
00583 } else {
00584 return NT_STATUS_WRONG_PASSWORD;
00585 }
00586 #endif
00587 #endif
00588 #endif
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password,
00601 int pwlen, BOOL (*fn) (const char *, const char *), BOOL run_cracker)
00602 {
00603 pstring pass2;
00604 int level = lp_passwordlevel();
00605
00606 NTSTATUS nt_status;
00607
00608 #ifdef DEBUG_PASSWORD
00609 DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password));
00610 #endif
00611
00612 if (!password)
00613 return NT_STATUS_LOGON_FAILURE;
00614
00615 if (((!*password) || (!pwlen)) && !lp_null_passwords())
00616 return NT_STATUS_LOGON_FAILURE;
00617
00618 #if defined(WITH_PAM)
00619
00620
00621
00622
00623
00624
00625 fstrcpy(this_user, user);
00626
00627 DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen));
00628
00629 #else
00630
00631 DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen));
00632
00633 if (!pass) {
00634 DEBUG(3, ("Couldn't find user %s\n", user));
00635 return NT_STATUS_NO_SUCH_USER;
00636 }
00637
00638
00639
00640
00641
00642 fstrcpy(this_crypted, pass->pw_passwd);
00643 fstrcpy(this_salt, pass->pw_passwd);
00644
00645 #ifdef HAVE_GETSPNAM
00646 {
00647 struct spwd *spass;
00648
00649
00650
00651
00652
00653
00654 spass = getspnam(pass->pw_name);
00655 if (spass && spass->sp_pwdp) {
00656 fstrcpy(this_crypted, spass->sp_pwdp);
00657 fstrcpy(this_salt, spass->sp_pwdp);
00658 }
00659 }
00660 #elif defined(IA_UINFO)
00661 {
00662
00663
00664
00665
00666 uinfo_t uinfo;
00667 if (ia_openinfo(pass->pw_name, &uinfo) != -1)
00668 ia_get_logpwd(uinfo, &(pass->pw_passwd));
00669 }
00670 #endif
00671
00672 #ifdef HAVE_GETPRPWNAM
00673 {
00674 struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
00675 if (pr_pw && pr_pw->ufld.fd_encrypt)
00676 fstrcpy(this_crypted, pr_pw->ufld.fd_encrypt);
00677 }
00678 #endif
00679
00680 #ifdef HAVE_GETPWANAM
00681 {
00682 struct passwd_adjunct *pwret;
00683 pwret = getpwanam(s);
00684 if (pwret && pwret->pwa_passwd)
00685 fstrcpy(this_crypted, pwret->pwa_passwd);
00686 }
00687 #endif
00688
00689 #ifdef OSF1_ENH_SEC
00690 {
00691 struct pr_passwd *mypasswd;
00692 DEBUG(5, ("Checking password for user %s in OSF1_ENH_SEC\n",
00693 user));
00694 mypasswd = getprpwnam(user);
00695 if (mypasswd) {
00696 fstrcpy(this_user, mypasswd->ufld.fd_name);
00697 fstrcpy(this_crypted, mypasswd->ufld.fd_encrypt);
00698 } else {
00699 DEBUG(5,
00700 ("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
00701 user));
00702 }
00703 }
00704 #endif
00705
00706 #ifdef ULTRIX_AUTH
00707 {
00708 AUTHORIZATION *ap = getauthuid(pass->pw_uid);
00709 if (ap) {
00710 fstrcpy(this_crypted, ap->a_password);
00711 endauthent();
00712 }
00713 }
00714 #endif
00715
00716 #if defined(HAVE_TRUNCATED_SALT)
00717
00718
00719 this_salt[2] = 0;
00720 #endif
00721
00722 if (!*this_crypted) {
00723 if (!lp_null_passwords()) {
00724 DEBUG(2, ("Disallowing %s with null password\n",
00725 this_user));
00726 return NT_STATUS_LOGON_FAILURE;
00727 }
00728 if (!*password) {
00729 DEBUG(3,
00730 ("Allowing access to %s with null password\n",
00731 this_user));
00732 return NT_STATUS_OK;
00733 }
00734 }
00735
00736 #endif
00737
00738
00739 nt_status = password_check(password);
00740 if NT_STATUS_IS_OK(nt_status) {
00741 if (fn) {
00742 fn(user, password);
00743 }
00744 return (nt_status);
00745 } else if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
00746
00747 return (nt_status);
00748 }
00749
00750 if (!run_cracker) {
00751 return (nt_status);
00752 }
00753
00754
00755
00756
00757 if (strhasupper(password) && strhaslower(password)) {
00758 return nt_status;
00759 }
00760
00761
00762 pstrcpy(pass2, password);
00763
00764
00765 if (strhasupper(pass2)) {
00766 strlower_m(pass2);
00767 if NT_STATUS_IS_OK(nt_status = password_check(pass2)) {
00768 if (fn)
00769 fn(user, pass2);
00770 return (nt_status);
00771 }
00772 }
00773
00774
00775 if (level < 1) {
00776 return NT_STATUS_WRONG_PASSWORD;
00777 }
00778
00779
00780 strlower_m(pass2);
00781
00782 if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) {
00783 if (fn)
00784 fn(user, pass2);
00785 return nt_status;
00786 }
00787
00788 return NT_STATUS_WRONG_PASSWORD;
00789 }