📄 passwd.c
字号:
struct passwd *pw; int pipefd[2], n, total = 0, stat_loc; pid_t pid; pipe(pipefd); if ((pid = fork()) == 0) { close(pipefd[0]); pw = getpwuid(getuid()); write(pipefd[1], pw->pw_passwd, strlen(pw->pw_passwd)); close(pipefd[1]); _exit(0); } if (pid < 0) error("%s: could not get user password (fork failed)\n"); close(pipefd[1]); while ((n = read(pipefd[0], &(userpass[total]), 50)) > 0) total += n; wait(&stat_loc); if (n < 0) error("%s: could not get user password (read failed)\n"); user[total] = 0; if (total < 1) error("%s: could not get user password (lookups failed)\n");#else /* !HP_PASSWDETC */#ifdef OSF1_ENH_SEC struct pr_passwd *pw; /*if ((pw = getprpwuid(getuid())) == NULL) */ if ((pw = getprpwuid(starting_ruid())) == NULL) error("%s: could not get encrypted user password.\n"); (void) strcpy(userpass, pw->ufld.fd_encrypt);#else /* !OSF1_ENH_SEC */ struct passwd *pw; if (!(pw = my_passwd_entry())) error("%s: could not get encrypted user password.\n"); // checking of "canGetPasswd" was here once. But it is now // done in main.cpp (only for Shadow passwords). (void) strcpy(userpass, pw->pw_passwd);#endif /* !OSF1_ENH_SEC */#endif /* !HP_PASSWDETC */}static voidgetCryptedRootPasswd(void){#ifdef HP_PASSWDETC/* * Still really, really sick. See above. */ struct passwd *pw; int pipefd[2], n, total = 0, stat_loc; pid_t pid; pipe(pipefd); if ((pid = fork()) == 0) { close(pipefd[0]); pw = getpwnam(ROOT); write(pipefd[1], pw->pw_passwd, strlen(pw->pw_passwd)); close(pipefd[1]); _exit(0); } if (pid < 0) error("%s: could not get root password (fork failed)\n"); close(pipefd[1]); while ((n = read(pipefd[0], &(rootpass[total]), 50)) > 0) total += n; wait(&stat_loc); if (n < 0) error("%s: could not get root password (read failed)\n"); rootpass[total] = 0; if (total < 1) error("%s: could not get root password (lookups failed)\n");#else /* !HP_PASSWDETC */#ifdef OSF1_ENH_SEC struct pr_passwd *pw; if ((pw = getprpwnam(ROOT)) == NULL) error("%s: could not get encrypted root password.\n"); (void) strcpy(rootpass, pw->ufld.fd_encrypt);#else /* !OSF1_ENH_SEC */ struct passwd *pw;#ifdef USE_SHADOW struct spwd *spw;#endif/* PURIFY 3.2 on Solaris2 reports an uninitialized memory read on the next line. PURIFY 4.0 on SunOS4 does not report this error */ if (!(pw = getpwnam(ROOT))) if (!(pw = getpwuid(0))) /*if ((pw = (struct passwd *) getpwuid(0)) == NULL) */ error("%s: could not get encrypted root password.\n");#ifdef USE_SHADOW if ((spw = getspnam(pw->pw_name)) != NULL) { char *tmp; /* swap */ tmp = pw->pw_passwd; pw->pw_passwd = spw->sp_pwdp; spw->sp_pwdp = tmp; } endspent();#endif/* PURIFY 3.2 on Solaris2 reports an uninitialized memory read on the next line. PURIFY 4.0 on SunOS4 does not report this error */ (void) strcpy(rootpass, pw->pw_passwd);#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT )) set_multiple();#endif /* HAVE_FCNTL_H && MULTIPLE_ROOT */#endif /* !OSF1_ENH_SEC */#endif /* !HP_PASSWDETC */}#endif /* !ultrix && !DCE_PASSWD && !BSD_AUTH */#endif /* !USE_PAM *//* * we don't allow for root to have no password, but we handle the case * where the user has no password correctly; they have to hit return * only */intcheckPasswd(char *buffer){ int done;#ifdef DCE_PASSWD if (usernet) done = check_dce_net_passwd(user, buffer); else done = !strcmp(userpass, crypt(buffer, userpass)); if (done) return 1; if (!allowroot) return 0; if (rootnet) done = check_dce_net_passwd(ROOT, buffer); else done = !strcmp(rootpass, crypt(buffer, rootpass));#else /* !DCE_PASSWD */#ifdef USE_PAM/*- * Use PAM to do authentication. No session logging, only authentication. * Bail out if there are any errors. * For now, don't try to display strings explaining errors. * Later, we could integrate PAM more by posting errors to the * user. * Query: should we be using PAM_SILENT to shut PAM up? */ pam_handle_t *pamh; int pam_error;#define PAM_BAIL if (pam_error != PAM_SUCCESS) { \ pam_end(pamh, 0); return 0; \} PAM_password = buffer; pam_error = pam_start(KDE_PAM, user, &PAM_conversation, &pamh); PAM_BAIL; pam_error = pam_authenticate(pamh, 0); if (pam_error != PAM_SUCCESS) { /* Try as root; bail if no success there either */ pam_error = pam_set_item(pamh, PAM_USER, ROOT); PAM_BAIL; pam_error = pam_authenticate(pamh, 0); PAM_BAIL; } /* Don't do account management or credentials; credentials * aren't needed and account management would just lock up * a computer and require root to come and unlock it. Blech. */ pam_end(pamh, PAM_SUCCESS); /* If this point is reached, the user has been authenticated. */ done = True;#else /* !USE_PAM */#ifdef ultrix done = ((authenticate_user((struct passwd *) getpwnam(user), buffer, NULL) >= 0) || (allowroot && (authenticate_user((struct passwd *) getpwnam(ROOT), buffer, NULL) >= 0)));#else /* !ultrix */#ifdef BSD_AUTH char *pass; char *style; char *name; done = 0;#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT )) /* Scan through the linked list until you match a password. Print * message to log if password match doesn't equal the user. * * This should be changed to allow the user name to be typed in also * to make this more secure. */ for (pwll = pwllh; done == 0 && pwll->next; pwll = pwll->next) { name = pwll->pw_name; lc = pwll->pw_lc;#else name = user;#endif if ((pass = strchr(buffer, ':')) != NULL) { *pass++ = '\0'; style = login_getstyle(lc, buffer, "auth-xlock"); if (auth_response(name, lc->lc_class, style, "response", NULL, "", pass) > 0) done = 1; else if (rlc != NULL) { style = login_getstyle(rlc, buffer, "auth-xlock"); if (auth_response(ROOT, rlc->lc_class, style, "response", NULL, "", pass) > 0) done = 1; } pass[-1] = ':'; } if (done == 0) { style = login_getstyle(lc, NULL, "auth-xlock"); if (auth_response(name, lc->lc_class, style, "response", NULL, "", buffer) > 0) done = 1; else if (rlc != NULL) { style = login_getstyle(rlc, NULL, "auth-xlock"); if (auth_response(ROOT, rlc->lc_class, style, "response", NULL, "", buffer) > 0) done = 1; } }#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT ))}#endif#else /* !BSD_AUTH */#ifdef AFS char *reason; /* check afs passwd first, then local, then root */ done = !ka_UserAuthenticate(user, "", 0, buffer, 0, &reason); if (!done)#endif /* !AFS */#if defined(HAVE_KRB4) || defined(HAVE_KRB5) if (!strcmp(userpass, "*")) done = (krb_check_password((struct passwd *) getpwuid(getuid()), buffer) || (allowroot && !strcmp((char *) crypt(buffer, rootpass), rootpass))); else#endif /* !HAVE_KRB4 && !HAVE_KRB5 */#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT )) /* Scan through the linked list until you match a password. Print * message to log if password match doesn't equal the user. * * This should be changed to allow the user name to be typed in also * to make this more secure. */ done = 0; for (pwll = pwllh; pwll->next; pwll = pwll->next) if (!strcmp((char *) crypt(buffer, pwll->pw_passwd), pwll->pw_passwd)) {#if ( HAVE_SYSLOG_H && defined( USE_SYSLOG )) if (strcmp(user, pwll->pw_name) != 0) syslog(LOG_NOTICE, "xlock: %s unlocked screen", pwll->pw_name);#endif done = 1; break; }#else done = ((!strcmp((char *) crypt(buffer, userpass), userpass)) || (allowroot && !strcmp((char *) crypt(buffer, rootpass), rootpass)));#endif /* userpass is used */ if (!*userpass && *buffer) /* * the user has no password, but something was typed anyway. * sounds fishy: don't let him in... */ done = False;#endif /* !BSD_AUTH */#endif /* !ultrix */#endif /* !USE_PAM */#endif /* !DCE_PASSWD */ return done;}/*- * Functions for DCE authentication * * Revision History: * 21-Aug-95: Added fallback to static password file [HAK] * 06-Jul-95: Mods by Heath A. Kehoe <hakehoe@icaen.uiowa.edu> for * inclusion into xlockmore * May-95: Created by Phil O'Connell <philo@icaen.uiowa.edu> */#ifdef DCE_PASSWD#include <pthread.h>#include <dce/sec_login.h>static voidinitDCE(void){ sec_login_handle_t login_context; error_status_t error_status; boolean32 valid; struct passwd *pwd; /* test to see if this user exists on the network registry */ valid = sec_login_setup_identity((unsigned_char_p_t) user, sec_login_no_flags, &login_context, &error_status); if (!valid) { switch (error_status) { case sec_rgy_object_not_found: break; case sec_rgy_server_unavailable: (void) fprintf(stderr, "%s: the network registry is not available.\n", ProgramName); break; case sec_login_s_no_memory: error("%s: out of memory\n"); /*NOTREACHED */ default: (void) fprintf(stderr, "%s: sec_login_setup_identity() returned status %d\n", ProgramName, (int) error_status); break; } pwd = getpwnam(user); if (!pwd || strlen(pwd->pw_passwd) < 10) { error("%s: could not get user password\n"); /*NOTREACHED */ } usernet = 0; (void) strcpy(userpass, pwd->pw_passwd); } else usernet = 1; if (allowroot) { valid = sec_login_setup_identity((unsigned_char_p_t) ROOT, sec_login_no_flags, &login_context, &error_status); if (!valid) { switch (error_status) { case sec_rgy_object_not_found: break; case sec_rgy_server_unavailable: (void) fprintf(stderr, "%s: the network registry is not available.\n", ProgramName); break; case sec_login_s_no_memory: error("%s: out of memory\n"); /*NOTREACHED */ default: (void) fprintf(stderr, "%s: sec_login_setup_identity() returned status %d\n", ProgramName, (int) error_status); break; } pwd = getpwuid(0); if (!pwd || strlen(pwd->pw_passwd) < 10) { (void) fprintf(stderr, "%s: could not get root password\n", ProgramName); allowroot = 0; } rootnet = 0; (void) strcpy(rootpass, pwd->pw_passwd); } else rootnet = 1; } pthread_lock_global_np();}static char *error_string(error_status_t error_status){ static char buf[60]; switch (error_status) { case error_status_ok: return "no error"; case sec_rgy_object_not_found: return "The principal does not exist"; case sec_rgy_server_unavailable: return "The network registry is not available"; case sec_login_s_no_memory: return "Not enough memory is available to complete the operation"; case sec_login_s_already_valid: return "The login context has already been validated"; case sec_login_s_default_use: return "Can't validate the default context"; case sec_login_s_acct_invalid: return "The account is invalid or has expired"; case sec_login_s_unsupp_passwd_type: return "The password type is not supported"; case sec_login_s_context_invalid: return "The login context itself is not valid"; default: (void) sprintf(buf, "error status #%d", (int) error_status); return buf; }}/* *---------------------------------------------------------------------- * Function Created 5/95 to be used with xlock to validate DCE * passwords. Routine simply returns a (1) if the the variable * PASS is the USER's PASSWORD, else it returns a (0). * Functions used: * * sec_login_setup_identity * sec_login_validate_identity * sec_login_certify_identity * * where setup_identity obtains the login context for the USER. * This identity is then validated with validate_identity. Finally, * cerfify_identity is called to make sure that the Security * Server used to set up and validate a login context is legitimate. * * Created by Phil O'Connell * philo@icaen.uiowa.edu * Student Programmer * *----------------------------------------------------------------------- */static intcheck_dce_net_passwd(char *usr, char *pass){ sec_login_handle_t login_context; error_status_t error_status; sec_passwd_rec_t password; boolean32 reset_password; sec_login_auth_src_t auth_src; unsigned_char_p_t principal_name; boolean32 valid = 0; char *passcpy; boolean32 current_context; pthread_unlock_global_np(); /* -------------------- SETUP IDENTITY--------------------------------- */ principal_name = (unsigned_char_p_t) usr; /* * We would rather like to refresh and existing login context instead of * making a new one. */ sec_login_get_current_context(&login_context, &error_status); if (error_status != error_status_ok) { current_context = 0; (void) fprintf(stderr, "get_current_context failed! Setting up a new one\n"); valid = sec_login_setup_identity(principal_name, sec_login_no_flags, &login_context, &error_status); if (!valid) { (void) fprintf(stderr, "sec_login_setup_identity() failed: %s\n", error_string(error_status)); pthread_lock_global_np(); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -