summaryrefslogtreecommitdiff
path: root/check_sia.c
blob: 67ff6ab72d06127435df085d2bad037dce852ecf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 *  CU sudo version 1.5.7
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Please send bugs, changes, problems to sudo-bugs@courtesan.com
 *
 *******************************************************************
 *
 *  check_sia.c -- check a user's password using Digital UNIX's
 *		   Security Integration Architecture
 *
 *  Spider Boardman Sep 26, 1998
 */

#include "config.h"

#ifdef HAVE_SIA

#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif /* STDC_HEADERS */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <sys/param.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <pwd.h>
#include <siad.h>

#include "sudo.h"

#ifndef lint
static const char rcsid[] = "$Id$";
#endif /* lint */

/*
 * Prototypes for local functions
 */
static int tcollect	__P((int, int, uchar_t *, int, prompt_t *));

/********************************************************************
 *  tcollect()
 *
 *  Collection routine (callback) for limiting the timeouts in SIA
 *  prompts.
 */
static int tcollect(timeout, rendition, title, nprompts, prompts)
    int timeout;
    int rendition;
    uchar_t *title;
    int nprompts;
    prompt_t *prompts;
{
    switch (rendition) {
	case SIAFORM:
	case SIAONELINER:
	    if (timeout <= 0 || timeout > PASSWORD_TIMEOUT * 60)
		timeout = PASSWORD_TIMEOUT * 60;
	    /*
	     * Substitute custom prompt if a) the sudo prompt is not "Password:"
	     * and b) the SIA prompt is "Password:" (so we know it is safe).
	     * This keeps us from overwriting things like s/key challenges.
	     */
	    if (strcmp((char *)prompts[0].prompt, "Password:") == 0 &&
		strcmp(prompt, "Password:") != 0)
		prompts[0].prompt = (unsigned char *)prompt;
	    break;
	default:
	    break;
    }

    return sia_collect_trm(timeout, rendition, title, nprompts, prompts);
}

/********************************************************************
 *  sia_attempt_auth()
 *
 *  Try to authenticate the user using Security Integration Architecture
 *  (SIA). Added 9/26/98 by Spider Boardman
 */
void sia_attempt_auth()
{
    SIAENTITY *siah = NULL;
    int retval;
    int counter = TRIES_FOR_PASSWORD;

    set_perms(PERM_ROOT, 0);
    while (counter > 0) {
	retval = sia_ses_init(&siah, Argc, Argv, NULL, user_name, ttyname(0),
			      1, NULL);
	if (retval != SIASUCCESS) {
	    set_perms(PERM_USER, 0);
	    log_error(BAD_ALLOCATION);
	    inform_user(BAD_ALLOCATION);
	    exit(1);
	}
	/* XXX - need a way to detect user hitting return or EOF at prompt */
	retval = sia_ses_reauthent(tcollect, siah);
	(void) sia_ses_release(&siah);
	if (retval == SIASUCCESS) {
	    set_perms(PERM_USER, 0);
	    return;
	}

	--counter;
	pass_warn(stderr);
    }
    set_perms(PERM_USER, 0);

    if (counter > 0) {
	log_error(PASSWORD_NOT_CORRECT);
	inform_user(PASSWORD_NOT_CORRECT);
    } else {
	log_error(PASSWORDS_NOT_CORRECT);
	inform_user(PASSWORDS_NOT_CORRECT);
    }
    exit(1);
}

#endif /* HAVE_SIA */