/xdm-1.1.11/greeter/greet.c
# · C · 832 lines · 641 code · 90 blank · 101 comment · 102 complexity · 83609a800d10a0596848e66585d87189 MD5 · raw file
- /*
- Copyright 1988, 1998 The Open Group
- Permission to use, copy, modify, distribute, and sell this software and its
- documentation for any purpose is hereby granted without fee, provided that
- the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation.
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- Except as contained in this notice, the name of The Open Group shall
- not be used in advertising or otherwise to promote the sale, use or
- other dealings in this Software without prior written authorization
- from The Open Group.
- */
- /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- /*
- * xdm - display manager daemon
- * Author: Keith Packard, X Consortium
- *
- * widget to get username/password
- *
- */
- #ifdef HAVE_CONFIG_H
- # include "config.h"
- #endif
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/XKBlib.h>
- #ifdef USE_XINERAMA
- # include <X11/extensions/Xinerama.h>
- #endif
- #include "dm.h"
- #include "dm_error.h"
- #include "greet.h"
- #include "LoginP.h"
- #if defined(HAVE_OPENLOG) && defined(HAVE_SYSLOG_H)
- # define USE_SYSLOG
- # include <syslog.h>
- # ifndef LOG_AUTHPRIV
- # define LOG_AUTHPRIV LOG_AUTH
- # endif
- # ifndef LOG_PID
- # define LOG_PID 0
- # endif
- #endif
- #ifdef HAVE_LIBAUDIT
- #include <libaudit.h>
- #include <pwd.h>
- #else
- #define log_to_audit_system(l,h,s) do { ; } while (0)
- #endif
- #include <string.h>
- #if defined(SECURE_RPC) && defined(sun)
- /* Go figure, there's no getdomainname() prototype available */
- extern int getdomainname(char *name, size_t len);
- #endif
- /*
- * Function pointers filled in by the initial call ito the library
- */
- int (*__xdm_PingServer)(struct display *d, Display *alternateDpy) = NULL;
- void (*__xdm_SessionPingFailed)(struct display *d) = NULL;
- void (*__xdm_Debug)(const char * fmt, ...) = NULL;
- void (*__xdm_RegisterCloseOnFork)(int fd) = NULL;
- void (*__xdm_SecureDisplay)(struct display *d, Display *dpy) = NULL;
- void (*__xdm_UnsecureDisplay)(struct display *d, Display *dpy) = NULL;
- void (*__xdm_ClearCloseOnFork)(int fd) = NULL;
- void (*__xdm_SetupDisplay)(struct display *d) = NULL;
- void (*__xdm_LogError)(const char * fmt, ...) = NULL;
- void (*__xdm_SessionExit)(struct display *d, int status, int removeAuth) = NULL;
- void (*__xdm_DeleteXloginResources)(struct display *d, Display *dpy) = NULL;
- int (*__xdm_source)(char **environ, char *file) = NULL;
- char **(*__xdm_defaultEnv)(void) = NULL;
- char **(*__xdm_setEnv)(char **e, char *name, char *value) = NULL;
- char **(*__xdm_putEnv)(const char *string, char **env) = NULL;
- char **(*__xdm_parseArgs)(char **argv, char *string) = NULL;
- void (*__xdm_printEnv)(char **e) = NULL;
- char **(*__xdm_systemEnv)(struct display *d, char *user, char *home) = NULL;
- void (*__xdm_LogOutOfMem)(const char * fmt, ...) = NULL;
- void (*__xdm_setgrent)(void) = NULL;
- struct group *(*__xdm_getgrent)(void) = NULL;
- void (*__xdm_endgrent)(void) = NULL;
- # ifdef HAVE_GETSPNAM
- struct spwd *(*__xdm_getspnam)(GETSPNAM_ARGS) = NULL;
- # ifndef QNX4
- void (*__xdm_endspent)(void) = NULL;
- # endif /* QNX4 doesn't use endspent */
- # endif
- struct passwd *(*__xdm_getpwnam)(GETPWNAM_ARGS) = NULL;
- # if defined(linux) || defined(__GLIBC__)
- void (*__xdm_endpwent)(void) = NULL;
- # endif
- char *(*__xdm_crypt)(CRYPT_ARGS) = NULL;
- # ifdef USE_PAM
- pam_handle_t **(*__xdm_thepamhp)(void) = NULL;
- # endif
- #ifdef SECURE_RPC
- # include <rpc/rpc.h>
- # include <rpc/key_prot.h>
- #endif
- #ifdef K5AUTH
- # include <krb5/krb5.h>
- #endif
- static int done, code;
- #ifndef USE_PAM
- static char name[NAME_LEN], password[PASSWORD_LEN];
- #endif
- static Widget toplevel;
- static Widget login;
- static XtAppContext context;
- static XtIntervalId pingTimeout;
- #ifdef USE_PAM
- static int pamconv(int num_msg,
- # ifndef sun
- const
- # endif
- struct pam_message **msg,
- struct pam_response **response, void *appdata_ptr);
- # define PAM_ERROR_PRINT(pamfunc, pamh) \
- LogError("%s failure: %s\n", pamfunc, pam_strerror(pamh, pam_error))
- struct myconv_data {
- struct display *d;
- struct greet_info *greet;
- char *username_display;
- };
- #endif
- /*ARGSUSED*/
- static void
- GreetPingServer (
- XtPointer closure,
- XtIntervalId *intervalId)
- {
- struct display *d;
- d = (struct display *) closure;
- if (!PingServer (d, XtDisplay (toplevel)))
- SessionPingFailed (d);
- pingTimeout = XtAppAddTimeOut (context, d->pingInterval * 60 * 1000,
- GreetPingServer, (closure));
- }
- /*ARGSUSED*/
- static void
- GreetDone (
- Widget w,
- LoginData *data,
- int status)
- {
- Debug ("GreetDone: %s, (password is %d long)\n",
- data->name, strlen (data->passwd));
- switch (status) {
- case NOTIFY_OK:
- #ifndef USE_PAM
- strncpy (name, data->name, sizeof(name));
- name[sizeof(name)-1] = '\0';
- strncpy (password, data->passwd, sizeof(password));
- password[sizeof(password)-1] = '\0';
- #endif
- code = 0;
- done = 1;
- break;
- case NOTIFY_ABORT:
- Debug ("RESERVER_DISPLAY\n");
- code = RESERVER_DISPLAY;
- done = 1;
- break;
- case NOTIFY_RESTART:
- Debug ("REMANAGE_DISPLAY\n");
- code = REMANAGE_DISPLAY;
- done = 1;
- break;
- case NOTIFY_ABORT_DISPLAY:
- Debug ("UNMANAGE_DISPLAY\n");
- code = UNMANAGE_DISPLAY;
- done = 1;
- break;
- }
- #ifndef USE_PAM
- if (done) {
- bzero (data->name, NAME_LEN);
- bzero (data->passwd, PASSWORD_LEN);
- }
- #endif
- }
- static Display *
- InitGreet (struct display *d)
- {
- Arg arglist[10];
- int i;
- static int argc;
- Screen *scrn;
- static char *argv[] = { "xlogin", NULL };
- Display *dpy;
- #ifdef USE_XINERAMA
- XineramaScreenInfo *screens;
- int s_num;
- #endif
- Debug ("greet %s\n", d->name);
- argc = 1;
- XtToolkitInitialize ();
- context = XtCreateApplicationContext();
- dpy = XtOpenDisplay (context, d->name, "xlogin", "Xlogin", NULL, 0,
- &argc, argv);
- if (!dpy)
- return NULL;
- #ifdef XKB
- {
- int opcode, evbase, errbase, majret, minret;
- unsigned int value = XkbPCF_GrabsUseXKBStateMask;
- if (XkbQueryExtension (dpy, &opcode, &evbase, &errbase, &majret, &minret)) {
- if (!XkbSetPerClientControls (dpy, XkbPCF_GrabsUseXKBStateMask, &value))
- LogError ("%s\n", "SetPerClientControls failed");
- }
- }
- #endif
- RegisterCloseOnFork (ConnectionNumber (dpy));
- SecureDisplay (d, dpy);
- i = 0;
- scrn = XDefaultScreenOfDisplay(dpy);
- XtSetArg(arglist[i], XtNscreen, scrn); i++;
- XtSetArg(arglist[i], XtNargc, argc); i++;
- XtSetArg(arglist[i], XtNargv, argv); i++;
- toplevel = XtAppCreateShell ((String) NULL, "Xlogin",
- applicationShellWidgetClass, dpy, arglist, i);
- i = 0;
- XtSetArg (arglist[i], XtNnotifyDone, (XtPointer)GreetDone); i++;
- if (!d->authorize || d->authorizations || !d->authComplain)
- {
- XtSetArg (arglist[i], XtNsecureSession, True); i++;
- }
- login = XtCreateManagedWidget ("login", loginWidgetClass, toplevel,
- arglist, i);
- XtRealizeWidget (toplevel);
- #ifdef USE_XINERAMA
- if (
- XineramaIsActive(dpy) &&
- (screens = XineramaQueryScreens(dpy, &s_num)) != NULL
- )
- {
- XWarpPointer(dpy, None, XRootWindowOfScreen (scrn),
- 0, 0, 0, 0,
- screens[0].x_org + screens[0].width / 2,
- screens[0].y_org + screens[0].height / 2);
- XFree(screens);
- }
- else
- #endif
- XWarpPointer(dpy, None, XRootWindowOfScreen (scrn),
- 0, 0, 0, 0,
- XWidthOfScreen(scrn) / 2,
- XHeightOfScreen(scrn) / 2);
- if (d->pingInterval)
- {
- pingTimeout = XtAppAddTimeOut (context, d->pingInterval * 60 * 1000,
- GreetPingServer, (XtPointer) d);
- }
- return dpy;
- }
- static void
- CloseGreet (struct display *d)
- {
- Boolean allow;
- Arg arglist[1];
- Display *dpy = XtDisplay(toplevel);
- if (pingTimeout)
- {
- XtRemoveTimeOut (pingTimeout);
- pingTimeout = 0;
- }
- UnsecureDisplay (d, dpy);
- XtSetArg (arglist[0], XtNallowAccess, (char *) &allow);
- XtGetValues (login, arglist, 1);
- if (allow)
- {
- Debug ("Disabling access control\n");
- XSetAccessControl (dpy, DisableAccess);
- }
- XtDestroyWidget (toplevel);
- toplevel = NULL;
- login = NULL; /* child of toplevel, which we just destroyed */
- ClearCloseOnFork (XConnectionNumber (dpy));
- XCloseDisplay (dpy);
- Debug ("Greet connection closed\n");
- }
- #define WHITESPACE 0
- #define ARGUMENT 1
- static int
- Greet (struct display *d, struct greet_info *greet)
- {
- XEvent event;
- Arg arglist[1];
- XtSetArg (arglist[0], XtNallowAccess, False);
- XtSetValues (login, arglist, 1);
- Debug ("dispatching %s\n", d->name);
- done = 0;
- while (!done) {
- XtAppNextEvent (context, &event);
- switch (event.type) {
- case MappingNotify:
- XRefreshKeyboardMapping(&event.xmapping);
- break;
- default:
- XtDispatchEvent (&event);
- break;
- }
- }
- XFlush (XtDisplay (toplevel));
- Debug ("Done dispatch %s\n", d->name);
- if (code == 0)
- {
- #ifndef USE_PAM
- char *ptr;
- unsigned int c,state = WHITESPACE;
- /*
- * Process the name string to get rid of white spaces.
- */
- for (ptr = name; state == WHITESPACE; ptr++)
- {
- c = (unsigned int)(*ptr);
- if (c == ' ')
- continue;
- state = ARGUMENT;
- break;
- }
- greet->name = ptr;
- greet->password = password;
- #endif /* USE_PAM */
- XtSetArg (arglist[0], XtNsessionArgument, (char *) &(greet->string));
- XtGetValues (login, arglist, 1);
- Debug ("sessionArgument: %s\n", greet->string ? greet->string : "<NULL>");
- }
- return code;
- }
- static void
- FailedLogin (struct display *d, const char *username)
- {
- #ifdef USE_SYSLOG
- if (username == NULL)
- username = "username unavailable";
- syslog(LOG_AUTHPRIV|LOG_NOTICE,
- "LOGIN FAILURE ON %s, %s",
- d->name, username);
- #endif
- DrawFail (login);
- }
- #ifdef USE_PAM
- #ifdef HAVE_LIBAUDIT
- static void
- log_to_audit_system(const pam_handle_t *pamhp, int success)
- {
- struct passwd *pw = NULL;
- char *hostname = NULL, *tty = NULL, *login=NULL;
- int audit_fd;
- audit_fd = audit_open();
- pam_get_item(pamhp, PAM_RHOST, &hostname);
- pam_get_item(pamhp, PAM_TTY, &tty);
- pam_get_item(pamhp, PAM_USER, &login);
- if (login)
- pw = getpwnam(login);
- audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN,
- NULL, "login", login ? login : "(unknown)",
- pw ? pw->pw_uid : -1, hostname, NULL, tty, success);
- close(audit_fd);
- }
- #endif
- #endif
- _X_EXPORT
- greet_user_rtn GreetUser(
- struct display *d,
- Display ** dpy,
- struct verify_info *verify,
- struct greet_info *greet,
- struct dlfuncs *dlfuncs)
- {
- int i;
- Arg arglist[2];
- /*
- * These must be set before they are used.
- */
- __xdm_PingServer = dlfuncs->_PingServer;
- __xdm_SessionPingFailed = dlfuncs->_SessionPingFailed;
- __xdm_Debug = dlfuncs->_Debug;
- __xdm_RegisterCloseOnFork = dlfuncs->_RegisterCloseOnFork;
- __xdm_SecureDisplay = dlfuncs->_SecureDisplay;
- __xdm_UnsecureDisplay = dlfuncs->_UnsecureDisplay;
- __xdm_ClearCloseOnFork = dlfuncs->_ClearCloseOnFork;
- __xdm_SetupDisplay = dlfuncs->_SetupDisplay;
- __xdm_LogError = dlfuncs->_LogError;
- __xdm_SessionExit = dlfuncs->_SessionExit;
- __xdm_DeleteXloginResources = dlfuncs->_DeleteXloginResources;
- __xdm_source = dlfuncs->_source;
- __xdm_defaultEnv = dlfuncs->_defaultEnv;
- __xdm_setEnv = dlfuncs->_setEnv;
- __xdm_putEnv = dlfuncs->_putEnv;
- __xdm_parseArgs = dlfuncs->_parseArgs;
- __xdm_printEnv = dlfuncs->_printEnv;
- __xdm_systemEnv = dlfuncs->_systemEnv;
- __xdm_LogOutOfMem = dlfuncs->_LogOutOfMem;
- __xdm_setgrent = dlfuncs->_setgrent;
- __xdm_getgrent = dlfuncs->_getgrent;
- __xdm_endgrent = dlfuncs->_endgrent;
- # ifdef HAVE_GETSPNAM
- __xdm_getspnam = dlfuncs->_getspnam;
- # ifndef QNX4
- __xdm_endspent = dlfuncs->_endspent;
- # endif /* QNX4 doesn't use endspent */
- # endif
- __xdm_getpwnam = dlfuncs->_getpwnam;
- # if defined(linux) || defined(__GLIBC__)
- __xdm_endpwent = dlfuncs->_endpwent;
- # endif
- __xdm_crypt = dlfuncs->_crypt;
- # ifdef USE_PAM
- __xdm_thepamhp = dlfuncs->_thepamhp;
- # endif
- *dpy = InitGreet (d);
- /*
- * Run the setup script - note this usually will not work when
- * the server is grabbed, so we don't even bother trying.
- */
- if (!d->grabServer)
- SetupDisplay (d);
- if (!*dpy) {
- LogError ("Cannot reopen display %s for greet window\n", d->name);
- exit (RESERVER_DISPLAY);
- }
- XtSetArg (arglist[0], XtNallowNullPasswd,
- (char *) &(greet->allow_null_passwd));
- XtSetArg (arglist[1], XtNallowRootLogin,
- (char *) &(greet->allow_root_login));
- XtGetValues (login, arglist, 2);
- for (;;) {
- #ifdef USE_PAM
- /* Run PAM conversation */
- pam_handle_t **pamhp = thepamhp();
- int pam_error;
- unsigned int pam_flags = 0;
- struct myconv_data pcd = { d, greet, NULL };
- struct pam_conv pc = { pamconv, &pcd };
- const char * pam_fname;
- const char * login_prompt;
- SetPrompt(login, LOGIN_PROMPT_USERNAME, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
- login_prompt = GetPrompt(login, LOGIN_PROMPT_USERNAME);
- SetPrompt(login, LOGIN_PROMPT_PASSWORD, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
- # define RUN_AND_CHECK_PAM_ERROR(function, args) \
- do { \
- pam_error = function args; \
- if (pam_error != PAM_SUCCESS) { \
- PAM_ERROR_PRINT(#function, *pamhp); \
- goto pam_done; \
- } \
- } while (0)
- RUN_AND_CHECK_PAM_ERROR(pam_start,
- ("xdm", NULL, &pc, pamhp));
- /* Set default login prompt to xdm's default from Xresources */
- if (login_prompt != NULL) {
- RUN_AND_CHECK_PAM_ERROR(pam_set_item,
- (*pamhp, PAM_USER_PROMPT, login_prompt));
- }
- if (d->name[0] != ':') { /* Displaying to remote host */
- char *hostname = strdup(d->name);
- if (hostname == NULL) {
- LogOutOfMem("GreetUser");
- } else {
- char *colon = strrchr(hostname, ':');
- if (colon != NULL)
- *colon = '\0';
- RUN_AND_CHECK_PAM_ERROR(pam_set_item,
- (*pamhp, PAM_RHOST, hostname));
- free(hostname);
- }
- } else { /* Displaying on local host */
- const char *ttyname = NULL;
- #ifdef __sun
- /* Solaris PAM & auditing insist this is a device file that can
- be found under /dev, so we can't use the display name */
- char vtpath[16];
- if ((d->windowPath) && !(strchr(d->windowPath, ':'))) {
- /* if path is simply a VT, with no intermediaries, use it */
- snprintf(vtpath, sizeof(vtpath), "/dev/vt/%s", d->windowPath);
- ttyname = vtpath;
- }
- #else
- /* On all other OS'es we just pass the display name for PAM_TTY */
- ttyname = d->name;
- #endif
- RUN_AND_CHECK_PAM_ERROR(pam_set_item, (*pamhp, PAM_TTY, ttyname));
- }
- if (!greet->allow_null_passwd) {
- pam_flags |= PAM_DISALLOW_NULL_AUTHTOK;
- }
- RUN_AND_CHECK_PAM_ERROR(pam_authenticate,
- (*pamhp, pam_flags));
- /* handle expired passwords */
- pam_error = pam_acct_mgmt(*pamhp, pam_flags);
- pam_fname = "pam_acct_mgmt";
- if (pam_error == PAM_NEW_AUTHTOK_REQD) {
- ShowChangePasswdMessage(login);
- do {
- pam_error = pam_chauthtok(*pamhp, PAM_CHANGE_EXPIRED_AUTHTOK);
- } while ((pam_error == PAM_AUTHTOK_ERR) ||
- (pam_error == PAM_TRY_AGAIN));
- pam_fname = "pam_chauthtok";
- }
- if (pam_error != PAM_SUCCESS) {
- PAM_ERROR_PRINT(pam_fname, *pamhp);
- goto pam_done;
- }
- RUN_AND_CHECK_PAM_ERROR(pam_setcred,
- (*pamhp, 0));
- {
- char *username = NULL;
- RUN_AND_CHECK_PAM_ERROR(pam_get_item,
- (*pamhp, PAM_USER, (void *) &username));
- if (username != NULL) {
- Debug("PAM_USER: %s\n", username);
- greet->name = username;
- greet->password = NULL;
- }
- }
- pam_done:
- if (code != 0)
- {
- CloseGreet (d);
- SessionExit (d, code, FALSE);
- }
- if ((pam_error == PAM_SUCCESS) && (Verify (d, greet, verify))) {
- SetPrompt (login, 1, "Login Successful", LOGIN_TEXT_INFO, False);
- SetValue (login, 1, NULL);
- log_to_audit_system(*pamhp, 1);
- break;
- } else {
- /* Try to fill in username for failed login error log */
- char *username = greet->name;
- if (username == NULL) {
- RUN_AND_CHECK_PAM_ERROR(pam_get_item,
- (*pamhp, PAM_USER,
- (void *) &username));
- }
- FailedLogin (d, username);
- log_to_audit_system(*pamhp, 0);
- RUN_AND_CHECK_PAM_ERROR(pam_end,
- (*pamhp, pam_error));
- }
- #else /* not PAM */
- /*
- * Greet user, requesting name/password
- */
- code = Greet (d, greet);
- if (code != 0)
- {
- CloseGreet (d);
- SessionExit (d, code, FALSE);
- }
- /*
- * Verify user
- */
- if (Verify (d, greet, verify))
- break;
- else
- {
- FailedLogin (d, greet->name);
- bzero (greet->name, strlen(greet->name));
- bzero (greet->password, strlen(greet->password));
- }
- #endif
- }
- DeleteXloginResources (d, *dpy);
- CloseGreet (d);
- Debug ("Greet loop finished\n");
- /*
- * Run system-wide initialization file
- */
- if (source (verify->systemEnviron, d->startup) != 0)
- {
- Debug ("Startup program %s exited with non-zero status\n",
- d->startup);
- SessionExit (d, OBEYSESS_DISPLAY, FALSE);
- }
- /*
- * for user-based authorization schemes,
- * add the user to the server's allowed "hosts" list.
- */
- for (i = 0; i < d->authNum; i++)
- {
- #ifdef SECURE_RPC
- if (d->authorizations[i]->name_length == 9 &&
- memcmp(d->authorizations[i]->name, "SUN-DES-1", 9) == 0)
- {
- XHostAddress addr;
- char netname[MAXNETNAMELEN+1];
- char domainname[MAXNETNAMELEN+1];
- getdomainname(domainname, sizeof domainname);
- user2netname (netname, verify->uid, domainname);
- addr.family = FamilyNetname;
- addr.length = strlen (netname);
- addr.address = netname;
- XAddHost (*dpy, &addr);
- }
- #endif
- #ifdef K5AUTH
- if (d->authorizations[i]->name_length == 14 &&
- memcmp(d->authorizations[i]->name, "MIT-KERBEROS-5", 14) == 0)
- {
- /* Update server's auth file with user-specific info.
- * Don't need to AddHost because X server will do that
- * automatically when it reads the cache we are about
- * to point it at.
- */
- extern Xauth *Krb5GetAuthFor();
- XauDisposeAuth (d->authorizations[i]);
- d->authorizations[i] =
- Krb5GetAuthFor(14, "MIT-KERBEROS-5", d->name);
- SaveServerAuthorizations (d, d->authorizations, d->authNum);
- }
- #endif
- }
- return Greet_Success;
- }
- #ifdef USE_PAM
- static int pamconv(int num_msg,
- # ifndef sun
- const
- # endif
- struct pam_message **msg,
- struct pam_response **response, void *appdata_ptr)
- {
- int i;
- int greetCode;
- int status = PAM_SUCCESS;
- const char *pam_msg_styles[5]
- = { "<invalid pam msg style>",
- "PAM_PROMPT_ECHO_OFF", "PAM_PROMPT_ECHO_ON",
- "PAM_ERROR_MSG", "PAM_TEXT_INFO" } ;
- struct pam_message *m;
- struct pam_response *r;
- struct myconv_data *d = (struct myconv_data *) appdata_ptr;
- pam_handle_t **pamhp = thepamhp();
- *response = calloc(num_msg, sizeof (struct pam_response));
- if (*response == NULL)
- return (PAM_BUF_ERR);
- m = (struct pam_message *)*msg;
- r = *response;
- if (login == NULL) {
- status = PAM_CONV_ERR;
- goto pam_error;
- }
- for (i = 0; i < num_msg; i++ , m++ , r++) {
- char *username;
- int promptId = 0;
- loginPromptState pStyle = LOGIN_PROMPT_ECHO_OFF;
- if ((pam_get_item(*pamhp, PAM_USER, (void *) &username) == PAM_SUCCESS)
- && (username != NULL) && (*username != '\0')) {
- SetPrompt(login, LOGIN_PROMPT_USERNAME,
- NULL, LOGIN_TEXT_INFO, False);
- SetValue(login, LOGIN_PROMPT_USERNAME, username);
- promptId = 1;
- }
- Debug("pam_msg: %s (%d): '%s'\n",
- ((m->msg_style > 0) && (m->msg_style <= 4)) ?
- pam_msg_styles[m->msg_style] : pam_msg_styles[0],
- m->msg_style, m->msg);
- switch (m->msg_style) {
- case PAM_ERROR_MSG:
- ErrorMessage(login, m->msg, True);
- break;
- case PAM_TEXT_INFO:
- SetPrompt (login, promptId, m->msg, LOGIN_TEXT_INFO, True);
- SetValue (login, promptId, NULL);
- break;
- case PAM_PROMPT_ECHO_ON:
- pStyle = LOGIN_PROMPT_ECHO_ON;
- /* FALLTHROUGH */
- case PAM_PROMPT_ECHO_OFF:
- SetPrompt (login, promptId, m->msg, pStyle, False);
- SetValue (login, promptId, NULL);
- greetCode = Greet (d->d, d->greet);
- if (greetCode != 0) {
- status = PAM_CONV_ERR;
- goto pam_error;
- } else {
- r->resp = strdup(GetValue(login, promptId));
- SetValue(login, promptId, NULL);
- if (r->resp == NULL) {
- status = PAM_BUF_ERR;
- goto pam_error;
- }
- /* Debug("pam_resp: '%s'\n", r->resp); */
- }
- break;
- default:
- LogError("Unknown PAM msg_style: %d\n", m->msg_style);
- }
- }
- pam_error:
- if (status != PAM_SUCCESS) {
- /* free responses */
- r = *response;
- for (i = 0; i < num_msg; i++, r++) {
- if (r->resp) {
- bzero(r->resp, strlen(r->resp));
- free(r->resp);
- }
- }
- free(*response);
- *response = NULL;
- }
- return status;
- }
- #endif