View | Details | Raw Unified | Return to bug 1867
Collapse All | Expand All

(-)openssh-5.8p1.orig/gss-serv-krb5.c (-5 / +157 lines)
Lines 32-38 Link Here
32
#include <sys/types.h>
32
#include <sys/types.h>
33
33
34
#include <stdarg.h>
34
#include <stdarg.h>
35
#include <stdio.h>
35
#include <string.h>
36
#include <string.h>
37
#include <unistd.h>
36
38
37
#include "xmalloc.h"
39
#include "xmalloc.h"
38
#include "key.h"
40
#include "key.h"
Lines 40-51 Link Here
40
#include "auth.h"
42
#include "auth.h"
41
#include "log.h"
43
#include "log.h"
42
#include "servconf.h"
44
#include "servconf.h"
45
#include "misc.h"
43
46
44
#include "buffer.h"
47
#include "buffer.h"
45
#include "ssh-gss.h"
48
#include "ssh-gss.h"
46
49
47
extern ServerOptions options;
48
49
#ifdef HEIMDAL
50
#ifdef HEIMDAL
50
# include <krb5.h>
51
# include <krb5.h>
51
#else
52
#else
Lines 56-61 extern ServerOptions options; Link Here
56
# endif
57
# endif
57
#endif
58
#endif
58
59
60
extern Authctxt *the_authctxt;
61
extern ServerOptions options;
62
63
/* all commands are allowed by default */
64
char **k5users_allowed_cmds = NULL;
65
66
static int ssh_gssapi_k5login_exists();
67
static int ssh_gssapi_krb5_cmdok(krb5_principal, const char *, const char *,
68
    int);
69
59
static krb5_context krb_context = NULL;
70
static krb5_context krb_context = NULL;
60
71
61
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
72
/* Initialise the krb5 library, for the stuff that GSSAPI won't do */
Lines 83-92 ssh_gssapi_krb5_init(void) Link Here
83
 */
94
 */
84
95
85
static int
96
static int
86
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name)
97
ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *luser)
87
{
98
{
88
	krb5_principal princ;
99
	krb5_principal princ;
89
	int retval;
100
	int retval;
101
	int k5login_exists;
90
102
91
	if (ssh_gssapi_krb5_init() == 0)
103
	if (ssh_gssapi_krb5_init() == 0)
92
		return 0;
104
		return 0;
Lines 97-106 ssh_gssapi_krb5_userok(ssh_gssapi_client Link Here
97
		    krb5_get_err_text(krb_context, retval));
109
		    krb5_get_err_text(krb_context, retval));
98
		return 0;
110
		return 0;
99
	}
111
	}
100
	if (krb5_kuserok(krb_context, princ, name)) {
112
	/* krb5_kuserok() returns 1 if .k5login DNE and this is self-login.
113
	 * We have to make sure to check .k5users in that case. */
114
	k5login_exists = ssh_gssapi_k5login_exists();
115
	/* NOTE: .k5login and .k5users must opened as root, not the user,
116
	 * because if they are on a krb5-protected filesystem, user credentials
117
	 * to access these files aren't available yet. */
118
	if (krb5_kuserok(krb_context, princ, luser) && k5login_exists) {
101
		retval = 1;
119
		retval = 1;
102
		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
120
		logit("Authorized to %s, krb5 principal %s (krb5_kuserok)",
103
		    name, (char *)client->displayname.value);
121
		    luser, (char *)client->displayname.value);
122
	} else if (ssh_gssapi_krb5_cmdok(princ, client->exportedname.value,
123
	    luser, k5login_exists)) {
124
		retval = 1;
125
		logit("Authorized to %s, krb5 principal %s "
126
		    "(ssh_gssapi_krb5_cmdok)",
127
		    luser, (char *)client->displayname.value);
104
	} else
128
	} else
105
		retval = 0;
129
		retval = 0;
106
130
Lines 108-113 ssh_gssapi_krb5_userok(ssh_gssapi_client Link Here
108
	return retval;
132
	return retval;
109
}
133
}
110
134
135
/* Test for existence of .k5login.
136
 * We need this as part of our .k5users check, because krb5_kuserok()
137
 * returns success if .k5login DNE and user is logging in as himself.
138
 * With .k5login absent and .k5users present, we don't want absence
139
 * of .k5login to authorize self-login.  (absence of both is required)
140
 * Returns 1 if .k5login is available, 0 otherwise.
141
 */
142
static int
143
ssh_gssapi_k5login_exists()
144
{
145
	char file[MAXPATHLEN];
146
	struct passwd *pw = the_authctxt->pw;
147
148
	snprintf(file, sizeof(file), "%s/.k5login", pw->pw_dir);
149
	return access(file, F_OK) == 0;
150
}
151
152
/* check .k5users for login or command authorization
153
 * Returns 1 if principal is authorized, 0 otherwise.
154
 * If principal is authorized, (global) k5users_allowed_cmds may be populated.
155
 */
156
static int
157
ssh_gssapi_krb5_cmdok(krb5_principal principal, const char *name,
158
    const char *luser, int k5login_exists)
159
{
160
	FILE *fp;
161
	char file[MAXPATHLEN];
162
	char line[BUFSIZ];
163
	char kuser[65]; /* match krb5_kuserok() */
164
	struct stat st;
165
	struct passwd *pw = the_authctxt->pw;
166
	int found_principal = 0;
167
	int ncommands = 0, allcommands = 0;
168
	u_long linenum;
169
170
	snprintf(file, sizeof(file), "%s/.k5users", pw->pw_dir);
171
	/* If both .k5login and .k5users DNE, self-login is ok. */
172
	if (!k5login_exists && (access(file, F_OK) == -1)) {
173
		return (krb5_aname_to_localname(krb_context, principal,
174
		    sizeof(kuser), kuser) == 0) &&
175
		    (strcmp(kuser, luser) == 0);
176
	}
177
	if ((fp = fopen(file, "r")) == NULL) {
178
		int saved_errno = errno;
179
		/* 2nd access check to ease debugging if file perms are wrong.
180
		 * But we don't want to report this if .k5users simply DNE. */
181
		if (access(file, F_OK) == 0) {
182
			logit("User %s fopen %s failed: %s",
183
			    pw->pw_name, file, strerror(saved_errno));
184
		}
185
		return 0;
186
	}
187
	/* .k5users must be owned either by the user or by root */
188
	if (fstat(fileno(fp), &st) == -1) {
189
		/* can happen, but very wierd error so report it */
190
		logit("User %s fstat %s failed: %s",
191
		    pw->pw_name, file, strerror(errno));
192
		fclose(fp);
193
		return 0;
194
	}
195
	if (!(st.st_uid == pw->pw_uid || st.st_uid == 0)) {
196
		logit("User %s %s is not owned by root or user",
197
		    pw->pw_name, file);
198
		fclose(fp);
199
		return 0;
200
	}
201
	/* .k5users must be a regular file.  krb5_kuserok() doesn't do this
202
         * check, but we don't want to be deficient if they add a check. */
203
	if (!S_ISREG(st.st_mode)) {
204
		logit("User %s %s is not a regular file", pw->pw_name, file);
205
		fclose(fp);
206
		return 0;
207
	}
208
	/* file exists; initialize k5users_allowed_cmds (to none!) */
209
	k5users_allowed_cmds = xcalloc(++ncommands,
210
	    sizeof(*k5users_allowed_cmds));
211
212
	/* Check each line.  ksu allows unlimited length lines.  We don't. */
213
	while (!allcommands && read_keyfile_line(fp, file, line, sizeof(line),
214
	    &linenum) != -1) {
215
		char *token;
216
217
		/* we parse just like ksu, even though we could do better */
218
		token = strtok(line, " \t\n");
219
		if (strcmp(name, token) == 0) {
220
			/* we matched on client principal */
221
			found_principal = 1;
222
			if ((token = strtok(NULL, " \t\n")) == NULL) {
223
				/* only shell is allowed */
224
				k5users_allowed_cmds[ncommands-1] =
225
				    xstrdup(pw->pw_shell);
226
				k5users_allowed_cmds =
227
				    xrealloc(k5users_allowed_cmds, ++ncommands,
228
					sizeof(*k5users_allowed_cmds));
229
				break;
230
			}
231
			/* process the allowed commands */
232
			while (token) {
233
				if (strcmp(token, "*") == 0) {
234
					allcommands = 1;
235
					break;
236
				}
237
				k5users_allowed_cmds[ncommands-1] =
238
				    xstrdup(token);
239
				k5users_allowed_cmds =
240
				    xrealloc(k5users_allowed_cmds, ++ncommands,
241
					sizeof(*k5users_allowed_cmds));
242
				token = strtok(NULL, " \t\n");
243
			}
244
		}
245
	}
246
	if (k5users_allowed_cmds) {
247
		/* terminate vector */
248
		k5users_allowed_cmds[ncommands-1] = NULL;
249
		/* if all commands are allowed, free vector */
250
		if (allcommands) {
251
			int i;
252
			for (i = 0; i < ncommands; i++) {
253
				free(k5users_allowed_cmds[i]);
254
			}
255
			free(k5users_allowed_cmds);
256
			k5users_allowed_cmds = NULL;
257
		}
258
	}
259
	fclose(fp);
260
	return found_principal;
261
}
262
111
263
112
/* This writes out any forwarded credentials from the structure populated
264
/* This writes out any forwarded credentials from the structure populated
113
 * during userauth. Called after we have setuid to the user */
265
 * during userauth. Called after we have setuid to the user */
(-)openssh-5.8p1.orig/session.c (+22 lines)
Lines 807-812 do_exec(Session *s, const char *command) Link Here
807
			s->is_subsystem = SUBSYSTEM_EXT;
807
			s->is_subsystem = SUBSYSTEM_EXT;
808
		debug("Forced command (key option) '%.900s'", command);
808
		debug("Forced command (key option) '%.900s'", command);
809
	}
809
	}
810
#ifdef GSSAPI
811
#ifdef KRB5 /* k5users_allowed_cmds only available w/ GSSAPI+KRB5 */
812
	else if (k5users_allowed_cmds) {
813
		const char *match = command;
814
		int allowed = 0, i = 0;
815
816
		if (!match)
817
			match = s->pw->pw_shell;
818
		while (k5users_allowed_cmds[i]) {
819
			if (strcmp(match, k5users_allowed_cmds[i++]) == 0) {
820
				debug("Allowed command '%.900s'", match);
821
				allowed = 1;
822
				break;
823
			}
824
		}
825
		if (!allowed) {
826
			debug("command '%.900s' not allowed", match);
827
			return 1;
828
		}
829
	}
830
#endif
831
#endif
810
832
811
#ifdef SSH_AUDIT_EVENTS
833
#ifdef SSH_AUDIT_EVENTS
812
	if (command != NULL)
834
	if (command != NULL)
(-)openssh-5.8p1.orig/ssh-gss.h (+4 lines)
Lines 48-53 Link Here
48
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
48
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
49
#endif /* GSS_C_NT_... */
49
#endif /* GSS_C_NT_... */
50
#endif /* !HEIMDAL */
50
#endif /* !HEIMDAL */
51
52
/* .k5users support */
53
extern char **k5users_allowed_cmds;
54
51
#endif /* KRB5 */
55
#endif /* KRB5 */
52
56
53
/* draft-ietf-secsh-gsskeyex-06 */
57
/* draft-ietf-secsh-gsskeyex-06 */
(-)openssh-5.8p1.orig/sshd.8 (+7 lines)
Lines 320-325 Finally, the server and the client enter Link Here
320
The client tries to authenticate itself using
320
The client tries to authenticate itself using
321
host-based authentication,
321
host-based authentication,
322
public key authentication,
322
public key authentication,
323
GSSAPI authentication,
323
challenge-response authentication,
324
challenge-response authentication,
324
or password authentication.
325
or password authentication.
325
.Pp
326
.Pp
Lines 788-793 This file is used in exactly the same wa Link Here
788
but allows host-based authentication without permitting login with
789
but allows host-based authentication without permitting login with
789
rlogin/rsh.
790
rlogin/rsh.
790
.Pp
791
.Pp
792
.It Pa ~/.k5login
793
.It Pa ~/.k5users
794
These files enforce GSSAPI/Kerberos authentication access control.
795
Further details are described in
796
.Xr ksu 1 .
797
.Pp
791
.It Pa ~/.ssh/
798
.It Pa ~/.ssh/
792
This directory is the default location for all user-specific configuration
799
This directory is the default location for all user-specific configuration
793
and authentication information.
800
and authentication information.

Return to bug 1867