27
27
from The Open Group.
30
/* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
32
* Permission is hereby granted, free of charge, to any person obtaining a
33
* copy of this software and associated documentation files (the
34
* "Software"), to deal in the Software without restriction, including
35
* without limitation the rights to use, copy, modify, merge, publish,
36
* distribute, and/or sell copies of the Software, and to permit persons
37
* to whom the Software is furnished to do so, provided that the above
38
* copyright notice(s) and this permission notice appear in all copies of
39
* the Software and that both the above copyright notice(s) and this
40
* permission notice appear in supporting documentation.
42
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
43
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
45
* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
46
* HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
47
* INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
48
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
49
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
50
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52
* Except as contained in this notice, the name of a copyright holder
53
* shall not be used in advertising or otherwise to promote the sale, use
54
* or other dealings in this Software without prior written authorization
55
* of the copyright holder.
30
58
/* $XFree86: xc/programs/xdm/greeter/greet.c,v 3.16tsi Exp $ */
118
148
extern Display *dpy;
120
150
static int done, code;
121
static char name[128], password[128];
152
static char name[NAME_LEN], password[PASSWORD_LEN];
122
154
static Widget toplevel;
123
155
static Widget login;
124
156
static XtAppContext context;
125
157
static XtIntervalId pingTimeout;
160
static int pamconv(int num_msg,
164
struct pam_message **msg,
165
struct pam_response **response, void *appdata_ptr);
167
# define PAM_ERROR_PRINT(pamfunc, pamh) \
168
LogError("%s failure: %s\n", pamfunc, pam_strerror(pamh, pam_error))
173
struct greet_info *greet;
174
char *username_display;
129
181
GreetPingServer (
423
488
#ifdef __OpenBSD__
424
489
openlog("xdm", LOG_ODELAY, LOG_AUTH);
495
/* Run PAM conversation */
496
pam_handle_t **pamhp = thepamhp();
498
unsigned int pam_flags = 0;
499
struct myconv_data pcd = { d, greet, NULL };
500
struct pam_conv pc = { pamconv, &pcd };
501
const char * pam_fname;
503
const char * login_prompt;
506
SetPrompt(login, 0, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
507
login_prompt = GetPrompt(login, LOGIN_PROMPT_USERNAME);
508
SetPrompt(login, 1, NULL, LOGIN_PROMPT_NOT_SHOWN, False);
510
#define RUN_AND_CHECK_PAM_ERROR(function, args) \
512
pam_error = function args; \
513
if (pam_error != PAM_SUCCESS) { \
514
PAM_ERROR_PRINT(#function, *pamhp); \
520
RUN_AND_CHECK_PAM_ERROR(pam_start,
521
("xdm", NULL, &pc, pamhp));
523
/* Set default login prompt to xdm's default from Xresources */
524
if (login_prompt != NULL) {
525
RUN_AND_CHECK_PAM_ERROR(pam_set_item,
526
(*pamhp, PAM_USER_PROMPT, login_prompt));
529
if (d->name[0] != ':') { /* Displaying to remote host */
530
char *hostname = strdup(d->name);
532
if (hostname == NULL) {
533
LogOutOfMem("GreetUser");
535
char *colon = strrchr(hostname, ':');
540
RUN_AND_CHECK_PAM_ERROR(pam_set_item,
541
(*pamhp, PAM_RHOST, hostname));
545
RUN_AND_CHECK_PAM_ERROR(pam_set_item, (*pamhp, PAM_TTY, d->name));
547
if (!greet->allow_null_passwd) {
548
pam_flags |= PAM_DISALLOW_NULL_AUTHTOK;
550
RUN_AND_CHECK_PAM_ERROR(pam_authenticate,
551
(*pamhp, pam_flags));
553
/* handle expired passwords */
554
pam_error = pam_acct_mgmt(*pamhp, pam_flags);
555
pam_fname = "pam_acct_mgmt";
556
if (pam_error == PAM_NEW_AUTHTOK_REQD) {
557
ShowChangePasswdMessage(login);
559
pam_error = pam_chauthtok(*pamhp, PAM_CHANGE_EXPIRED_AUTHTOK);
560
} while ((pam_error == PAM_AUTHTOK_ERR) ||
561
(pam_error == PAM_TRY_AGAIN));
562
pam_fname = "pam_chauthtok";
564
if (pam_error != PAM_SUCCESS) {
565
PAM_ERROR_PRINT(pam_fname, *pamhp);
569
RUN_AND_CHECK_PAM_ERROR(pam_setcred,
571
RUN_AND_CHECK_PAM_ERROR(pam_get_item,
572
(*pamhp, PAM_USER, (void *) &username));
573
if (username != NULL) {
574
Debug("PAM_USER: %s\n", username);
575
greet->name = username;
576
greet->password = NULL;
583
SessionExit (d, code, FALSE);
585
if ((pam_error == PAM_SUCCESS) && (Verify (d, greet, verify))) {
586
SetPrompt (login, 1, "Login Successful", LOGIN_TEXT_INFO, False);
587
SetValue (login, 1, NULL);
590
RUN_AND_CHECK_PAM_ERROR(pam_end,
591
(*pamhp, pam_error));
592
FailedLogin (d, greet);
428
596
* Greet user, requesting name/password
497
666
return Greet_Success;
671
static int pamconv(int num_msg,
675
struct pam_message **msg,
676
struct pam_response **response, void *appdata_ptr)
680
int status = PAM_SUCCESS;
681
const char *pam_msg_styles[5]
682
= { "<invalid pam msg style>",
683
"PAM_PROMPT_ECHO_OFF", "PAM_PROMPT_ECHO_ON",
684
"PAM_ERROR_MSG", "PAM_TEXT_INFO" } ;
686
struct pam_message *m;
687
struct pam_response *r;
689
struct myconv_data *d = (struct myconv_data *) appdata_ptr;
691
pam_handle_t **pamhp = thepamhp();
693
*response = calloc(num_msg, sizeof (struct pam_response));
694
if (*response == NULL)
695
return (PAM_BUF_ERR);
700
for (i = 0; i < num_msg; i++ , m++ , r++) {
703
loginPromptState pStyle = LOGIN_PROMPT_ECHO_OFF;
705
if ((pam_get_item(*pamhp, PAM_USER, (void *) &username) == PAM_SUCCESS)
706
&& (username != NULL) && (*username != '\0')) {
707
SetPrompt(login, LOGIN_PROMPT_USERNAME,
708
NULL, LOGIN_TEXT_INFO, False);
709
SetValue(login, LOGIN_PROMPT_USERNAME, username);
713
Debug("pam_msg: %s (%d): '%s'\n",
714
((m->msg_style > 0) && (m->msg_style <= 4)) ?
715
pam_msg_styles[m->msg_style] : pam_msg_styles[0],
716
m->msg_style, m->msg);
718
switch (m->msg_style) {
720
ErrorMessage(login, m->msg, True);
724
SetPrompt (login, promptId, m->msg, LOGIN_TEXT_INFO, True);
725
SetValue (login, promptId, NULL);
728
case PAM_PROMPT_ECHO_ON:
729
pStyle = LOGIN_PROMPT_ECHO_ON;
731
case PAM_PROMPT_ECHO_OFF:
732
SetPrompt (login, promptId, m->msg, pStyle, False);
733
SetValue (login, promptId, NULL);
734
greetCode = Greet (d->d, d->greet);
735
if (greetCode != 0) {
736
status = PAM_CONV_ERR;
739
r->resp = strdup(GetValue(login, promptId));
740
SetValue(login, promptId, NULL);
741
if (r->resp == NULL) {
742
status = PAM_BUF_ERR;
745
/* Debug("pam_resp: '%s'\n", r->resp); */
750
LogError("Unknown PAM msg_style: %d\n", m->msg_style);
754
if (status != PAM_SUCCESS) {
757
for (i = 0; i < num_msg; i++, r++) {
759
bzero(r->resp, strlen(r->resp));