xref: /freebsd/crypto/openssh/platform.c (revision 4a421b6336e5e0c2ff27024c30fe32c6f71dcf3d)
1*4a421b63SDag-Erling Smørgrav /* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */
2761efaa7SDag-Erling Smørgrav 
3761efaa7SDag-Erling Smørgrav /*
4761efaa7SDag-Erling Smørgrav  * Copyright (c) 2006 Darren Tucker.  All rights reserved.
5761efaa7SDag-Erling Smørgrav  *
6761efaa7SDag-Erling Smørgrav  * Permission to use, copy, modify, and distribute this software for any
7761efaa7SDag-Erling Smørgrav  * purpose with or without fee is hereby granted, provided that the above
8761efaa7SDag-Erling Smørgrav  * copyright notice and this permission notice appear in all copies.
9761efaa7SDag-Erling Smørgrav  *
10761efaa7SDag-Erling Smørgrav  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11761efaa7SDag-Erling Smørgrav  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12761efaa7SDag-Erling Smørgrav  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13761efaa7SDag-Erling Smørgrav  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14761efaa7SDag-Erling Smørgrav  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15761efaa7SDag-Erling Smørgrav  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16761efaa7SDag-Erling Smørgrav  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17761efaa7SDag-Erling Smørgrav  */
18761efaa7SDag-Erling Smørgrav 
19*4a421b63SDag-Erling Smørgrav #include "includes.h"
20*4a421b63SDag-Erling Smørgrav 
21*4a421b63SDag-Erling Smørgrav #include <sys/types.h>
22*4a421b63SDag-Erling Smørgrav 
23*4a421b63SDag-Erling Smørgrav #include <stdarg.h>
24*4a421b63SDag-Erling Smørgrav #include <unistd.h>
25*4a421b63SDag-Erling Smørgrav 
26*4a421b63SDag-Erling Smørgrav #include "log.h"
27*4a421b63SDag-Erling Smørgrav #include "buffer.h"
28*4a421b63SDag-Erling Smørgrav #include "servconf.h"
29*4a421b63SDag-Erling Smørgrav #include "key.h"
30*4a421b63SDag-Erling Smørgrav #include "hostfile.h"
31*4a421b63SDag-Erling Smørgrav #include "auth.h"
32*4a421b63SDag-Erling Smørgrav #include "auth-pam.h"
33761efaa7SDag-Erling Smørgrav #include "platform.h"
34761efaa7SDag-Erling Smørgrav 
35761efaa7SDag-Erling Smørgrav #include "openbsd-compat/openbsd-compat.h"
36761efaa7SDag-Erling Smørgrav 
37*4a421b63SDag-Erling Smørgrav extern int use_privsep;
38*4a421b63SDag-Erling Smørgrav extern ServerOptions options;
39*4a421b63SDag-Erling Smørgrav 
40761efaa7SDag-Erling Smørgrav void
41b15c8340SDag-Erling Smørgrav platform_pre_listen(void)
42b15c8340SDag-Erling Smørgrav {
43b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST
44b15c8340SDag-Erling Smørgrav 	/* Adjust out-of-memory killer so listening process is not killed */
45b15c8340SDag-Erling Smørgrav 	oom_adjust_setup();
46b15c8340SDag-Erling Smørgrav #endif
47b15c8340SDag-Erling Smørgrav }
48b15c8340SDag-Erling Smørgrav 
49b15c8340SDag-Erling Smørgrav void
50761efaa7SDag-Erling Smørgrav platform_pre_fork(void)
51761efaa7SDag-Erling Smørgrav {
52761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS
53761efaa7SDag-Erling Smørgrav 	solaris_contract_pre_fork();
54761efaa7SDag-Erling Smørgrav #endif
55761efaa7SDag-Erling Smørgrav }
56761efaa7SDag-Erling Smørgrav 
57761efaa7SDag-Erling Smørgrav void
58761efaa7SDag-Erling Smørgrav platform_post_fork_parent(pid_t child_pid)
59761efaa7SDag-Erling Smørgrav {
60761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS
61761efaa7SDag-Erling Smørgrav 	solaris_contract_post_fork_parent(child_pid);
62761efaa7SDag-Erling Smørgrav #endif
63761efaa7SDag-Erling Smørgrav }
64761efaa7SDag-Erling Smørgrav 
65761efaa7SDag-Erling Smørgrav void
66761efaa7SDag-Erling Smørgrav platform_post_fork_child(void)
67761efaa7SDag-Erling Smørgrav {
68761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS
69761efaa7SDag-Erling Smørgrav 	solaris_contract_post_fork_child();
70761efaa7SDag-Erling Smørgrav #endif
71b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST
72b15c8340SDag-Erling Smørgrav 	oom_adjust_restore();
73b15c8340SDag-Erling Smørgrav #endif
74b15c8340SDag-Erling Smørgrav }
75b15c8340SDag-Erling Smørgrav 
76*4a421b63SDag-Erling Smørgrav /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
77*4a421b63SDag-Erling Smørgrav int
78*4a421b63SDag-Erling Smørgrav platform_privileged_uidswap(void)
79*4a421b63SDag-Erling Smørgrav {
80*4a421b63SDag-Erling Smørgrav #ifdef HAVE_CYGWIN
81*4a421b63SDag-Erling Smørgrav 	/* uid 0 is not special on Cygwin so always try */
82*4a421b63SDag-Erling Smørgrav 	return 1;
83*4a421b63SDag-Erling Smørgrav #else
84*4a421b63SDag-Erling Smørgrav 	return (getuid() == 0 || geteuid() == 0);
85*4a421b63SDag-Erling Smørgrav #endif
86*4a421b63SDag-Erling Smørgrav }
87*4a421b63SDag-Erling Smørgrav 
88*4a421b63SDag-Erling Smørgrav /*
89*4a421b63SDag-Erling Smørgrav  * This gets called before switching UIDs, and is called even when sshd is
90*4a421b63SDag-Erling Smørgrav  * not running as root.
91*4a421b63SDag-Erling Smørgrav  */
92*4a421b63SDag-Erling Smørgrav void
93*4a421b63SDag-Erling Smørgrav platform_setusercontext(struct passwd *pw)
94*4a421b63SDag-Erling Smørgrav {
95*4a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX
96*4a421b63SDag-Erling Smørgrav 	/* Cache selinux status for later use */
97*4a421b63SDag-Erling Smørgrav 	(void)ssh_selinux_enabled();
98*4a421b63SDag-Erling Smørgrav #endif
99*4a421b63SDag-Erling Smørgrav 
100*4a421b63SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROJECTS
101*4a421b63SDag-Erling Smørgrav 	/* if solaris projects were detected, set the default now */
102*4a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0)
103*4a421b63SDag-Erling Smørgrav 		solaris_set_default_project(pw);
104*4a421b63SDag-Erling Smørgrav #endif
105*4a421b63SDag-Erling Smørgrav 
106*4a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
107*4a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0)
108*4a421b63SDag-Erling Smørgrav 		setpgid(0, 0);
109*4a421b63SDag-Erling Smørgrav # endif
110*4a421b63SDag-Erling Smørgrav 
111*4a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
112*4a421b63SDag-Erling Smørgrav 	/*
113*4a421b63SDag-Erling Smørgrav 	 * If we have both LOGIN_CAP and PAM, we want to establish creds
114*4a421b63SDag-Erling Smørgrav 	 * before calling setusercontext (in session.c:do_setusercontext).
115*4a421b63SDag-Erling Smørgrav 	 */
116*4a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0) {
117*4a421b63SDag-Erling Smørgrav 		if (options.use_pam) {
118*4a421b63SDag-Erling Smørgrav 			do_pam_setcred(use_privsep);
119*4a421b63SDag-Erling Smørgrav 		}
120*4a421b63SDag-Erling Smørgrav 	}
121*4a421b63SDag-Erling Smørgrav # endif /* USE_PAM */
122*4a421b63SDag-Erling Smørgrav 
123*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
124*4a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0) {
125*4a421b63SDag-Erling Smørgrav 		/* Sets login uid for accounting */
126*4a421b63SDag-Erling Smørgrav 		if (getluid() == -1 && setluid(pw->pw_uid) == -1)
127*4a421b63SDag-Erling Smørgrav 			error("setluid: %s", strerror(errno));
128*4a421b63SDag-Erling Smørgrav 	}
129*4a421b63SDag-Erling Smørgrav #endif
130*4a421b63SDag-Erling Smørgrav }
131*4a421b63SDag-Erling Smørgrav 
132*4a421b63SDag-Erling Smørgrav /*
133*4a421b63SDag-Erling Smørgrav  * This gets called after we've established the user's groups, and is only
134*4a421b63SDag-Erling Smørgrav  * called if sshd is running as root.
135*4a421b63SDag-Erling Smørgrav  */
136*4a421b63SDag-Erling Smørgrav void
137*4a421b63SDag-Erling Smørgrav platform_setusercontext_post_groups(struct passwd *pw)
138*4a421b63SDag-Erling Smørgrav {
139*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
140*4a421b63SDag-Erling Smørgrav 	/*
141*4a421b63SDag-Erling Smørgrav 	 * PAM credentials may take the form of supplementary groups.
142*4a421b63SDag-Erling Smørgrav 	 * These will have been wiped by the above initgroups() call.
143*4a421b63SDag-Erling Smørgrav 	 * Reestablish them here.
144*4a421b63SDag-Erling Smørgrav 	 */
145*4a421b63SDag-Erling Smørgrav 	if (options.use_pam) {
146*4a421b63SDag-Erling Smørgrav 		do_pam_setcred(use_privsep);
147*4a421b63SDag-Erling Smørgrav 	}
148*4a421b63SDag-Erling Smørgrav #endif /* USE_PAM */
149*4a421b63SDag-Erling Smørgrav 
150*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
151*4a421b63SDag-Erling Smørgrav     defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
152*4a421b63SDag-Erling Smørgrav 	irix_setusercontext(pw);
153*4a421b63SDag-Erling Smørgrav #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
154*4a421b63SDag-Erling Smørgrav 
155*4a421b63SDag-Erling Smørgrav #ifdef _AIX
156*4a421b63SDag-Erling Smørgrav 	aix_usrinfo(pw);
157*4a421b63SDag-Erling Smørgrav #endif /* _AIX */
158*4a421b63SDag-Erling Smørgrav 
159*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF)
160*4a421b63SDag-Erling Smørgrav 	if (set_id(pw->pw_name) != 0) {
161*4a421b63SDag-Erling Smørgrav 		exit(1);
162*4a421b63SDag-Erling Smørgrav 	}
163*4a421b63SDag-Erling Smørgrav # endif /* USE_LIBIAF */
164*4a421b63SDag-Erling Smørgrav 
165*4a421b63SDag-Erling Smørgrav #ifdef HAVE_SETPCRED
166*4a421b63SDag-Erling Smørgrav 	/*
167*4a421b63SDag-Erling Smørgrav 	 * If we have a chroot directory, we set all creds except real
168*4a421b63SDag-Erling Smørgrav 	 * uid which we will need for chroot.  If we don't have a
169*4a421b63SDag-Erling Smørgrav 	 * chroot directory, we don't override anything.
170*4a421b63SDag-Erling Smørgrav 	 */
171*4a421b63SDag-Erling Smørgrav 	{
172*4a421b63SDag-Erling Smørgrav 		char **creds = NULL, *chroot_creds[] =
173*4a421b63SDag-Erling Smørgrav 		    { "REAL_USER=root", NULL };
174*4a421b63SDag-Erling Smørgrav 
175*4a421b63SDag-Erling Smørgrav 		if (options.chroot_directory != NULL &&
176*4a421b63SDag-Erling Smørgrav 		    strcasecmp(options.chroot_directory, "none") != 0)
177*4a421b63SDag-Erling Smørgrav 			creds = chroot_creds;
178*4a421b63SDag-Erling Smørgrav 
179*4a421b63SDag-Erling Smørgrav 		if (setpcred(pw->pw_name, creds) == -1)
180*4a421b63SDag-Erling Smørgrav 			fatal("Failed to set process credentials");
181*4a421b63SDag-Erling Smørgrav 	}
182*4a421b63SDag-Erling Smørgrav #endif /* HAVE_SETPCRED */
183*4a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX
184*4a421b63SDag-Erling Smørgrav 	ssh_selinux_setup_exec_context(pw->pw_name);
185*4a421b63SDag-Erling Smørgrav #endif
186*4a421b63SDag-Erling Smørgrav }
187*4a421b63SDag-Erling Smørgrav 
188b15c8340SDag-Erling Smørgrav char *
189b15c8340SDag-Erling Smørgrav platform_krb5_get_principal_name(const char *pw_name)
190b15c8340SDag-Erling Smørgrav {
191b15c8340SDag-Erling Smørgrav #ifdef USE_AIX_KRB_NAME
192b15c8340SDag-Erling Smørgrav 	return aix_krb5_get_principal_name(pw_name);
193b15c8340SDag-Erling Smørgrav #else
194b15c8340SDag-Erling Smørgrav 	return NULL;
195b15c8340SDag-Erling Smørgrav #endif
196761efaa7SDag-Erling Smørgrav }
197