📄 passwd.c
字号:
#if !defined( lint ) && !defined( SABER )static const char sccsid[] = "@(#)passwd.c 4.02 97/04/01 xlockmore";#endif/*- * passwd.cpp, part of the KDE kscreensaver * * changes: 06-Jun-98: updated for PAM support. * Code is taken essentially verbatim from xlockmore 4.09. * PAM support in xlockmore is attributed as: * 24-Jan-98: Updated PAM support and made it configure-able. * Marc Ewing <marc@redhat.com> Original PAM support from * 25-Jul-96 Michael K. Johnson <johnsonm@redhat.com> *--------------------------------------------------------- * passwd.c - passwd stuff. * * Copyright (c) 1988-91 by Patrick J. Naughton. * * Revision History: * * Changes of David Bagley <bagleyd@bigfoot.com> * 25-May-96: When xlock is compiled with shadow passwords it will still * work on non shadowed systems. Marek Michalkiewicz * <marekm@i17linuxb.ists.pwr.wroc.pl> * 25-Feb-96: Lewis Muhlenkamp * Added in ability for any of the root accounts to unlock * screen. Message now gets sent to syslog if root does the * unlocking. * 23-Dec-95: Ron Hitchens <ron@idiom.com> reorganized. * 10-Dec-95: More context handling stuff for DCE thanks to * Terje Marthinussen <terjem@cc.uit.no>. * 01-Sep-95: DCE code added thanks to Heath A. Kehoe * <hakehoe@icaen.uiowa.edu>. * 24-Jun-95: Extracted from xlock.c, encrypted passwords are now fetched * on start-up to ensure correct operation (except Ultrix). */#include <kmsgbox.h>#include "main.h" // for MODE_PREVIEW#include "xlockmore.h"#ifdef HAVE_PAM#define USE_PAM 1extern "C" {#include <security/pam_appl.h>}#ifdef KDE_PAM_SERVICE#define KDE_PAM KDE_PAM_SERVICE#else #define KDE_PAM "xdm" /* default PAM service called by kscreensaver */#endif #else /* !USE_PAM */#ifdef HAVE_SHADOW#define USE_SHADOW 1#endif#endif#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_CRYPT_H#include <crypt.h>#endif#ifdef HAVE_PATHS_H#include <paths.h>#endif#ifndef _PATH_TMP#define _PATH_TMP "/tmp/"#endifextern char *ProgramName;extern Bool allowroot;extern Bool inroot;extern Bool inwindow;extern Bool grabmouse;#define ROOT "root"#if !defined( SUNOS_ADJUNCT_PASSWD )#include <pwd.h>#endif#ifdef __bsdi__#include <sys/param.h>#if _BSDI_VERSION >= 199608#define BSD_AUTH#endif#endif#ifdef BSD_AUTH#include <login_cap.h>static login_cap_t *lc = NULL;static login_cap_t *rlc = NULL;#endifextern int mode;#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT ))#include <fcntl.h>#include <errno.h>#if ( HAVE_SYSLOG_H && defined( USE_SYSLOG ))#include <syslog.h>#endifextern int errno;void get_multiple(struct passwd *);void set_multiple();#define BUFMAX 1024 /* Maximum size of pipe buffer *//* Linked list to keep track of everyone that's authorized * to unlock the screen. */struct pwln { char *pw_name;#ifdef BSD_AUTH login_cap_t *pw_lc;#else char *pw_passwd;#endif struct pwln *next;};typedef struct pwln pwlnode;typedef struct pwln *pwlptr;pwlptr pwll, pwllh = (pwlptr) NULL;extern pwlptr pwllh;/* Function that creates and initializes a new node that * will be added to the linked list. */pwlptrnew_pwlnode(void){ pwlptr pwl; if ((pwl = (pwlptr) malloc(sizeof (pwlnode))) == 0) return ((pwlptr) ENOMEM); pwl->pw_name = (char *) NULL;#ifdef BSD_AUTH pwl->pw_lc = NULL;#else pwl->pw_passwd = (char *) NULL;#endif pwl->next = (pwlptr) NULL; return (pwl);}#endif#ifdef ultrix#include <auth.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include<stdarg.h>#ifdef OSF1_ENH_SEC#include <sys/security.h>#include <prot.h>#endif#if defined( __linux__ ) && defined( USE_SHADOW ) && defined( HAVE_PW_ENCRYPT )/* Deprecated - long passwords have known weaknesses. Also, pw_encrypt is non-standard (requires libshadow.a) while everything else you need to support shadow passwords is in the standard (ELF) libc. */#define crypt pw_encrypt#endif#ifdef USE_SHADOW#ifndef __hpux#include <shadow.h>#endif#endif#ifdef SUNOS_ADJUNCT_PASSWD#include <sys/label.h>#include <sys/audit.h>#include <pwdadj.h>#define passwd passwd_adjunct#define pw_passwd pwa_passwd#define getpwnam(_s) getpwanam(_s)#define pw_name pwa_name#define getpwuid(_s) (((_s)==0)?getpwanam(ROOT):getpwanam(cuserid(NULL)))#endif /* SUNOS_ADJUNCT_PASSWD *//* System V Release 4 redefinitions of BSD functions and structures */#if !defined( SHADOW ) && (defined( SYSV ) || defined( SVR4 ))#ifdef LESS_THAN_AIX3_2struct passwd { char *pw_name; char *pw_passwd; uid_t pw_uid; gid_t pw_gid; char *pw_gecos; char *pw_dir; char *pw_shell;};#endif /* LESS_THAN_AIX3_2 */#ifdef HPUX_SECURE_PASSWD#define passwd s_passwd#define getpwnam(_s) getspwnam(_s)#define getpwuid(_u) getspwuid(_u)#endif /* HPUX_SECURE_PASSWD */#endif /* defined( SYSV ) || defined( SVR4 ) */#ifdef HP_PASSWDETC /* HAVE_SYS_WAIT_H */#include <sys/wait.h>#endif /* HP_PASSWDETC */#ifdef AFS#include <afs/kauth.h>#include <afs/kautils.h>#endif /* AFS */char user[PASSLENGTH];#ifdef USE_PAM/* used to pass the password to the conversation function */static char *PAM_password;/*- * PAM conversation function * Here we assume (for now, at least) that echo on means login name, and * echo off means password. */#ifdef PAM_MESSAGE_NONCONSTtypedef struct pam_message pam_message_type;#elsetypedef const struct pam_message pam_message_type;#endifinline static char *COPY_STRING(const char *s) { return (s ? strdup(s) : NULL);}static intPAM_conv(int num_msg, pam_message_type **msg, struct pam_response **resp, void *appdata_ptr){ int replies = 0; struct pam_response *reply = NULL;//#define COPY_STRING(s) (s) ? strdup(s) : NULL reply = (struct pam_response *) malloc(sizeof (struct pam_response) * num_msg); if (!reply) return PAM_CONV_ERR; for (replies = 0; replies < num_msg; replies++) { switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = COPY_STRING(user); /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = COPY_STRING(PAM_password); /* PAM frees resp */ break; case PAM_TEXT_INFO: /* ignore it... */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = NULL; break; case PAM_ERROR_MSG: /* ignore it... */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = NULL; break; default: /* Must be an error of some sort... */ (void) free((void *) reply); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS;}static struct pam_conv PAM_conversation ={ &PAM_conv, NULL};#endif /* USE_PAM */#if !defined( ultrix ) && !defined( USE_PAM )static char userpass[PASSLENGTH];static char rootpass[PASSLENGTH];#endif /* !ultrix && !USE_PAM */#ifdef DCE_PASSWDstatic int usernet, rootnet;static int check_dce_net_passwd(char *, char *);#endif#if defined( HAVE_KRB4 ) || defined( HAVE_KRB5 )#ifdef HAVE_KRB4#include <krb.h>#else /* HAVE_KRB5 */#include <krb5.h>#endif#include <sys/param.h>static int krb_check_password(struct passwd *, char *);#endif#if ((!defined( OSF1_ENH_SEC ) && !defined( HP_PASSWDETC )))static struct passwd *my_passwd_entry(void){ uid_t uid; struct passwd *pw;#ifdef USE_SHADOW struct spwd *spw;#endif uid = getuid();#ifndef SUNOS_ADJUNCT_PASSWD { char *user = NULL; pw = 0; user = getenv("LOGNAME"); if (!user) user = getenv("USER"); if (user) {/* PURIFY 3.2 on Solaris2 reports an uninitialized memory read and PURIFY 4.0 on SunOS4 reports a file descriptor allocated on the next line */ pw = getpwnam(user);/* 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 && (pw->pw_uid != uid)) pw = 0; } } if (!pw)#endif pw = getpwuid(uid);#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 return (pw);}#endifvoiderror(char *s1,...){ char *s2; va_list vl; va_start(vl, s1); s2 = va_arg(vl, char *); va_end(vl); (void) fprintf(stderr, s1, ProgramName, s2); exit(1);}static voidgetUserName(void){#ifdef HP_PASSWDETC/* * The PasswdEtc libraries have replacement passwd functions that make * queries to DomainOS registries. Unfortunately, these functions do * wierd things to the process (at minimum, signal handlers get changed, * there are probably other things as well) that cause xlock to become * unstable. * * As a (really, really sick) workaround, we'll fork() and do the getpw*() * calls in the child, and pass the information back through a pipe. */ 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_name, strlen(pw->pw_name)); 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], &(user[total]), 50)) > 0) total += n; wait(&stat_loc); if (n < 0) error("%s: could not get user name (read failed)\n"); user[total] = 0; if (total < 1) error("%s: could not get user name (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 user name.\n"); (void) strcpy(user, pw->ufld.fd_name);#else /* !OSF1_ENH_SEC */ struct passwd *pw; if (!(pw = my_passwd_entry())) /*if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) */ error("%s: could not get user name.\n");/* 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(user, pw->pw_name);#if ( HAVE_FCNTL_H && defined( USE_MULTIPLE_ROOT )) get_multiple(pw);#endif#endif /* !OSF1_ENH_SEC */#endif /* !HP_PASSWDETC */}#if !defined( USE_PAM )#if defined( USE_SHADOW )static intpasswd_invalid(char *passwd){ int i = strlen(passwd); return (i == 1 || i == 2);}#endif#if !defined( ultrix ) && !defined( DCE_PASSWD ) && !defined( BSD_AUTH )/* This routine is not needed if HAVE_FCNTL_H and USE_MULTIPLE_ROOT */static voidgetCryptedUserPasswd(void){#ifdef HP_PASSWDETC/* * still very sick, see above */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -