xref: /aoo41x/main/sal/osl/unx/security.c (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include <stddef.h>
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir /* Solaris 8 has no C99 stdint.h, and Solaris generally seems not to miss it for
31*cdf0e10cSrcweir    SIZE_MAX: */
32*cdf0e10cSrcweir #if !defined __SUNPRO_C
33*cdf0e10cSrcweir #include <stdint.h>
34*cdf0e10cSrcweir #endif
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include "system.h"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <osl/security.h>
39*cdf0e10cSrcweir #include <osl/diagnose.h>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include "osl/thread.h"
42*cdf0e10cSrcweir #include "osl/file.h"
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #if defined LINUX || defined SOLARIS
45*cdf0e10cSrcweir #include <crypt.h>
46*cdf0e10cSrcweir #endif
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include "secimpl.h"
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #ifndef NOPAM
51*cdf0e10cSrcweir #ifndef PAM_BINARY_MSG
52*cdf0e10cSrcweir #define PAM_BINARY_MSG 6
53*cdf0e10cSrcweir #endif
54*cdf0e10cSrcweir #endif
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir static oslSecurityError SAL_CALL
57*cdf0e10cSrcweir osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
58*cdf0e10cSrcweir                   oslSecurity* pSecurity);
59*cdf0e10cSrcweir sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax);
60*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32  nMax);
61*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
62*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir static sal_Bool sysconf_SC_GETPW_R_SIZE_MAX(size_t * value) {
65*cdf0e10cSrcweir #if defined _SC_GETPW_R_SIZE_MAX
66*cdf0e10cSrcweir     long m;
67*cdf0e10cSrcweir     errno = 0;
68*cdf0e10cSrcweir     m = sysconf(_SC_GETPW_R_SIZE_MAX);
69*cdf0e10cSrcweir     if (m == -1) {
70*cdf0e10cSrcweir         /* _SC_GETPW_R_SIZE_MAX has no limit; some platforms like certain
71*cdf0e10cSrcweir            FreeBSD versions support sysconf(_SC_GETPW_R_SIZE_MAX) in a broken
72*cdf0e10cSrcweir            way and always set EINVAL, so be resilient here: */
73*cdf0e10cSrcweir         return sal_False;
74*cdf0e10cSrcweir     } else {
75*cdf0e10cSrcweir         OSL_ASSERT(m >= 0 && (unsigned long) m < SIZE_MAX);
76*cdf0e10cSrcweir         *value = (size_t) m;
77*cdf0e10cSrcweir         return sal_True;
78*cdf0e10cSrcweir     }
79*cdf0e10cSrcweir #else
80*cdf0e10cSrcweir     /* some platforms like Mac OS X 1.3 do not define _SC_GETPW_R_SIZE_MAX: */
81*cdf0e10cSrcweir     return sal_False;
82*cdf0e10cSrcweir #endif
83*cdf0e10cSrcweir }
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir static oslSecurityImpl * growSecurityImpl(
86*cdf0e10cSrcweir     oslSecurityImpl * impl, size_t * bufSize)
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir     size_t n = 0;
89*cdf0e10cSrcweir     oslSecurityImpl * p = NULL;
90*cdf0e10cSrcweir     if (impl == NULL) {
91*cdf0e10cSrcweir         if (!sysconf_SC_GETPW_R_SIZE_MAX(&n)) {
92*cdf0e10cSrcweir             /* choose something sensible (the callers of growSecurityImpl will
93*cdf0e10cSrcweir                detect it if the allocated buffer is too small: */
94*cdf0e10cSrcweir             n = 1024;
95*cdf0e10cSrcweir         }
96*cdf0e10cSrcweir     } else if (*bufSize <= SIZE_MAX / 2) {
97*cdf0e10cSrcweir         n = 2 * *bufSize;
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir     if (n != 0) {
100*cdf0e10cSrcweir         if (n <= SIZE_MAX - offsetof(oslSecurityImpl, m_buffer)) {
101*cdf0e10cSrcweir             *bufSize = n;
102*cdf0e10cSrcweir             n += offsetof(oslSecurityImpl, m_buffer);
103*cdf0e10cSrcweir         } else {
104*cdf0e10cSrcweir             *bufSize = SIZE_MAX - offsetof(oslSecurityImpl, m_buffer);
105*cdf0e10cSrcweir             n = SIZE_MAX;
106*cdf0e10cSrcweir         }
107*cdf0e10cSrcweir         p = realloc(impl, n);
108*cdf0e10cSrcweir     }
109*cdf0e10cSrcweir     if (p == NULL) {
110*cdf0e10cSrcweir         free(impl);
111*cdf0e10cSrcweir     }
112*cdf0e10cSrcweir     return p;
113*cdf0e10cSrcweir }
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir static void deleteSecurityImpl(oslSecurityImpl * impl) {
116*cdf0e10cSrcweir     free(impl);
117*cdf0e10cSrcweir }
118*cdf0e10cSrcweir 
119*cdf0e10cSrcweir oslSecurity SAL_CALL osl_getCurrentSecurity()
120*cdf0e10cSrcweir {
121*cdf0e10cSrcweir     size_t n = 0;
122*cdf0e10cSrcweir 	oslSecurityImpl * p = NULL;
123*cdf0e10cSrcweir     for (;;) {
124*cdf0e10cSrcweir         struct passwd * found;
125*cdf0e10cSrcweir         p = growSecurityImpl(p, &n);
126*cdf0e10cSrcweir         if (p == NULL) {
127*cdf0e10cSrcweir             return NULL;
128*cdf0e10cSrcweir         }
129*cdf0e10cSrcweir         switch (getpwuid_r(getuid(), &p->m_pPasswd, p->m_buffer, n, &found)) {
130*cdf0e10cSrcweir         case ERANGE:
131*cdf0e10cSrcweir             break;
132*cdf0e10cSrcweir         case 0:
133*cdf0e10cSrcweir             if (found != NULL) {
134*cdf0e10cSrcweir                 return p;
135*cdf0e10cSrcweir             }
136*cdf0e10cSrcweir             /* fall through */
137*cdf0e10cSrcweir         default:
138*cdf0e10cSrcweir             deleteSecurityImpl(p);
139*cdf0e10cSrcweir             return NULL;
140*cdf0e10cSrcweir         }
141*cdf0e10cSrcweir     }
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir #if defined LINUX && !defined NOPAM
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir /*
148*cdf0e10cSrcweir  *
149*cdf0e10cSrcweir  * osl Routines for Pluggable Authentication Modules (PAM)
150*cdf0e10cSrcweir  * tested with Linux-PAM 0.66 on Redhat-6.0 and
151*cdf0e10cSrcweir  * Linux-PAM 0.64 on RedHat-5.2,
152*cdf0e10cSrcweir  * XXX Will probably not run on PAM 0.59 or prior, since
153*cdf0e10cSrcweir  *     number of pam_response* responses has changed
154*cdf0e10cSrcweir  *
155*cdf0e10cSrcweir  */
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir #include <security/pam_appl.h>
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir typedef struct {
160*cdf0e10cSrcweir 	char* name;
161*cdf0e10cSrcweir 	char* password;
162*cdf0e10cSrcweir } sal_PamData;
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir typedef struct {
165*cdf0e10cSrcweir 	int (*pam_start)(const char *service_name, const char *user,
166*cdf0e10cSrcweir 		     	     const struct pam_conv *pam_conversation,
167*cdf0e10cSrcweir 		     		 pam_handle_t **pamh);
168*cdf0e10cSrcweir 	int (*pam_end)          (pam_handle_t *pamh, int pam_status);
169*cdf0e10cSrcweir 	int (*pam_authenticate) (pam_handle_t *pamh, int flags);
170*cdf0e10cSrcweir 	int (*pam_acct_mgmt)    (pam_handle_t *pamh, int flags);
171*cdf0e10cSrcweir } sal_PamModule;
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir /*
174*cdf0e10cSrcweir  * Implement a pam-conversation callback-routine,
175*cdf0e10cSrcweir  * it just supply name and password instead of prompting the user.
176*cdf0e10cSrcweir  * I guess that echo-off means 'ask for password' and echo-on means
177*cdf0e10cSrcweir  * 'ask for user-name'. In fact I've never been asked anything else
178*cdf0e10cSrcweir  * than the password
179*cdf0e10cSrcweir  * XXX Please notice that if a pam-module does ask anything else, we
180*cdf0e10cSrcweir  *     are completely lost, and a pam-module is free to do so
181*cdf0e10cSrcweir  * XXX
182*cdf0e10cSrcweir  */
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir static int
185*cdf0e10cSrcweir osl_PamConversation (int num_msg, const struct pam_message **msgm,
186*cdf0e10cSrcweir                      struct pam_response **response, void *appdata_ptr)
187*cdf0e10cSrcweir {
188*cdf0e10cSrcweir 	int	  		i;
189*cdf0e10cSrcweir 	sal_Bool	error;
190*cdf0e10cSrcweir 	sal_PamData         *pam_data;
191*cdf0e10cSrcweir 	struct pam_response *p_reply;
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 	/* resource initialization */
194*cdf0e10cSrcweir 	pam_data = (sal_PamData*) appdata_ptr;
195*cdf0e10cSrcweir 	p_reply  = (struct pam_response *) calloc( num_msg,
196*cdf0e10cSrcweir 											   sizeof(struct pam_response));
197*cdf0e10cSrcweir 	if ( p_reply == NULL || pam_data == NULL )
198*cdf0e10cSrcweir 	{
199*cdf0e10cSrcweir 		if ( p_reply != NULL )
200*cdf0e10cSrcweir 			free ( p_reply );
201*cdf0e10cSrcweir 		*response = NULL;
202*cdf0e10cSrcweir 		return PAM_CONV_ERR;
203*cdf0e10cSrcweir 	}
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 	/* pseudo dialog */
206*cdf0e10cSrcweir 	error = sal_False;
207*cdf0e10cSrcweir 	for ( i = 0; i < num_msg ; i++ )
208*cdf0e10cSrcweir 	{
209*cdf0e10cSrcweir 		switch ( msgm[ i ]->msg_style )
210*cdf0e10cSrcweir 		{
211*cdf0e10cSrcweir 			case PAM_PROMPT_ECHO_OFF:
212*cdf0e10cSrcweir 				p_reply[ i ].resp_retcode = 0;
213*cdf0e10cSrcweir 				p_reply[ i ].resp 		  = strdup( pam_data->password );
214*cdf0e10cSrcweir 			 	break;
215*cdf0e10cSrcweir 			case PAM_PROMPT_ECHO_ON:
216*cdf0e10cSrcweir 				p_reply[ i ].resp_retcode = 0;
217*cdf0e10cSrcweir 				p_reply[ i ].resp 		= strdup( pam_data->name );
218*cdf0e10cSrcweir 				break;
219*cdf0e10cSrcweir 			case PAM_ERROR_MSG:
220*cdf0e10cSrcweir 			case PAM_TEXT_INFO:
221*cdf0e10cSrcweir  			case PAM_BINARY_PROMPT:
222*cdf0e10cSrcweir 			case PAM_BINARY_MSG:
223*cdf0e10cSrcweir 				p_reply[ i ].resp_retcode 	= 0;
224*cdf0e10cSrcweir 				p_reply[ i ].resp 			= NULL;
225*cdf0e10cSrcweir 				break;
226*cdf0e10cSrcweir 			default:
227*cdf0e10cSrcweir 				error = sal_True;
228*cdf0e10cSrcweir 				break;
229*cdf0e10cSrcweir 		}
230*cdf0e10cSrcweir 	}
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 	/* free resources on error */
233*cdf0e10cSrcweir 	if ( error )
234*cdf0e10cSrcweir 	{
235*cdf0e10cSrcweir 		for ( i = 0; i < num_msg ; i++ )
236*cdf0e10cSrcweir 			if ( p_reply[ i ].resp )
237*cdf0e10cSrcweir 			{
238*cdf0e10cSrcweir 				memset ( p_reply[ i ].resp, 0,
239*cdf0e10cSrcweir 						 strlen( p_reply[ i ].resp ) );
240*cdf0e10cSrcweir 				free   ( p_reply[ i ].resp );
241*cdf0e10cSrcweir 			}
242*cdf0e10cSrcweir 		free ( p_reply );
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 		*response = NULL;
245*cdf0e10cSrcweir 		return PAM_CONV_ERR;
246*cdf0e10cSrcweir 	}
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir 	/* well done */
249*cdf0e10cSrcweir 	*response = p_reply;
250*cdf0e10cSrcweir 	return PAM_SUCCESS;
251*cdf0e10cSrcweir }
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir #ifndef PAM_LINK
254*cdf0e10cSrcweir /*
255*cdf0e10cSrcweir  * avoid linking against libpam.so, since it is not available on all systems,
256*cdf0e10cSrcweir  * instead load-on-call, returns structure which holds pointer to
257*cdf0e10cSrcweir  * pam-functions,
258*cdf0e10cSrcweir  * library is never closed in case of success
259*cdf0e10cSrcweir  */
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir static sal_PamModule* osl_getPAM()
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir 	static sal_PamModule *pam_module = NULL;
264*cdf0e10cSrcweir 	static sal_Bool load_once = sal_False;
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 	if ( !load_once )
267*cdf0e10cSrcweir 	{
268*cdf0e10cSrcweir 		/* get library-handle. cannot use osl-module, since
269*cdf0e10cSrcweir  		   RTLD_GLOBAL is required for PAM-0.64 RH 5.2
270*cdf0e10cSrcweir 		   (but not for PAM-0.66 RH 6.0) */
271*cdf0e10cSrcweir 		void *pam_hdl;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir 		pam_hdl = dlopen( "libpam.so.0", RTLD_GLOBAL | RTLD_LAZY );
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 		if ( pam_hdl != NULL )
276*cdf0e10cSrcweir 			pam_module = (sal_PamModule*)calloc( 1, sizeof(sal_PamModule) );
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 		/* load functions */
279*cdf0e10cSrcweir 		if ( pam_module  != NULL )
280*cdf0e10cSrcweir 		{
281*cdf0e10cSrcweir 			pam_module->pam_acct_mgmt = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_acct_mgmt" );
282*cdf0e10cSrcweir 			pam_module->pam_authenticate
283*cdf0e10cSrcweir 									  = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_authenticate" );
284*cdf0e10cSrcweir 			pam_module->pam_end       = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_end" );
285*cdf0e10cSrcweir 			pam_module->pam_start     = (int (*)(const char *, const char *, const struct pam_conv *, pam_handle_t **)) dlsym ( pam_hdl, "pam_start" );
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 			/* free resources, if not completely successful */
288*cdf0e10cSrcweir 			if (   (pam_module->pam_start 		 == NULL)
289*cdf0e10cSrcweir 				|| (pam_module->pam_end 		 == NULL)
290*cdf0e10cSrcweir 				|| (pam_module->pam_authenticate == NULL)
291*cdf0e10cSrcweir 				|| (pam_module->pam_acct_mgmt 	 == NULL) )
292*cdf0e10cSrcweir 			{
293*cdf0e10cSrcweir 				free( pam_module );
294*cdf0e10cSrcweir 				pam_module = NULL;
295*cdf0e10cSrcweir 				dlclose( pam_hdl );
296*cdf0e10cSrcweir 			}
297*cdf0e10cSrcweir 		}
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 		/* never try again */
300*cdf0e10cSrcweir 		load_once = sal_True;
301*cdf0e10cSrcweir 	}
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir 	return pam_module;
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir #endif
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir /*
308*cdf0e10cSrcweir  * User Identification using PAM
309*cdf0e10cSrcweir  */
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir static sal_Bool
312*cdf0e10cSrcweir osl_PamAuthentification( const sal_Char* name, const sal_Char* password )
313*cdf0e10cSrcweir {
314*cdf0e10cSrcweir 	sal_Bool success = sal_False;
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir #ifndef PAM_LINK
317*cdf0e10cSrcweir 	sal_PamModule* pam_module;
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 	pam_module = osl_getPAM();
320*cdf0e10cSrcweir 	if ( pam_module != NULL )
321*cdf0e10cSrcweir 	{
322*cdf0e10cSrcweir #endif
323*cdf0e10cSrcweir 		pam_handle_t   *pam_handle = NULL;
324*cdf0e10cSrcweir 		struct pam_conv pam_conversation;
325*cdf0e10cSrcweir 		sal_PamData     pam_data;
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 		int				return_value;
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir 		pam_data.name     = (char*) name;
330*cdf0e10cSrcweir 		pam_data.password = (char*) password;
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir 		pam_conversation.conv 		 = osl_PamConversation;
333*cdf0e10cSrcweir 		pam_conversation.appdata_ptr = (void*)(&pam_data);
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir #ifndef PAM_LINK
336*cdf0e10cSrcweir   		return_value = pam_module->pam_start( "su", name,
337*cdf0e10cSrcweir 			&pam_conversation, &pam_handle);
338*cdf0e10cSrcweir #else
339*cdf0e10cSrcweir   		return_value = pam_start( "su", name,
340*cdf0e10cSrcweir 			&pam_conversation, &pam_handle);
341*cdf0e10cSrcweir #endif
342*cdf0e10cSrcweir 		if (return_value == PAM_SUCCESS )
343*cdf0e10cSrcweir #ifndef PAM_LINK
344*cdf0e10cSrcweir 			return_value = pam_module->pam_authenticate(pam_handle, 0);
345*cdf0e10cSrcweir #else
346*cdf0e10cSrcweir 			return_value = pam_authenticate(pam_handle, 0);
347*cdf0e10cSrcweir #endif
348*cdf0e10cSrcweir   		if (return_value == PAM_SUCCESS )
349*cdf0e10cSrcweir #ifndef PAM_LINK
350*cdf0e10cSrcweir 			return_value = pam_module->pam_acct_mgmt(pam_handle, 0);
351*cdf0e10cSrcweir 		pam_module->pam_end( pam_handle, return_value );
352*cdf0e10cSrcweir #else
353*cdf0e10cSrcweir 			return_value = pam_acct_mgmt(pam_handle, 0);
354*cdf0e10cSrcweir 		pam_end( pam_handle, return_value );
355*cdf0e10cSrcweir #endif
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir 		success = (sal_Bool)(return_value == PAM_SUCCESS);
358*cdf0e10cSrcweir #ifndef PAM_LINK
359*cdf0e10cSrcweir 	}
360*cdf0e10cSrcweir #endif
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir   	return success;
363*cdf0e10cSrcweir }
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir #ifndef CRYPT_LINK
367*cdf0e10cSrcweir /* dummy crypt, matches the interface of
368*cdf0e10cSrcweir    crypt() but does not encrypt at all */
369*cdf0e10cSrcweir static const sal_Char* SAL_CALL
370*cdf0e10cSrcweir osl_noCrypt ( const sal_Char *key, const sal_Char *salt )
371*cdf0e10cSrcweir {
372*cdf0e10cSrcweir     (void) salt; /* unused */
373*cdf0e10cSrcweir 	return key;
374*cdf0e10cSrcweir }
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir /* load-on-call crypt library and crypt symbol */
377*cdf0e10cSrcweir static void*  SAL_CALL
378*cdf0e10cSrcweir osl_getCrypt()
379*cdf0e10cSrcweir {
380*cdf0e10cSrcweir 	static char* (*crypt_sym)(const char*, const char*) = NULL;
381*cdf0e10cSrcweir 	static sal_Bool load_once  = sal_False;
382*cdf0e10cSrcweir 
383*cdf0e10cSrcweir 	if ( !load_once )
384*cdf0e10cSrcweir 	{
385*cdf0e10cSrcweir 		void * crypt_library;
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir 		crypt_library = dlopen( "libcrypt.so.1", RTLD_GLOBAL | RTLD_LAZY ); /* never closed */
388*cdf0e10cSrcweir 		if ( crypt_library != NULL )
389*cdf0e10cSrcweir 			crypt_sym = (char* (*)(const char *, const char *)) dlsym(crypt_library, "crypt" );
390*cdf0e10cSrcweir 		if ( crypt_sym == NULL ) /* no libcrypt or libcrypt without crypt */
391*cdf0e10cSrcweir 			crypt_sym = (char* (*)(const char *, const char *)) &osl_noCrypt;
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir 		load_once = sal_True;
394*cdf0e10cSrcweir 	}
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 	return (void*)crypt_sym;
397*cdf0e10cSrcweir }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir /* replacement for crypt function for password encryption, uses either
400*cdf0e10cSrcweir    strong encryption of dlopen'ed libcrypt.so.1 or dummy implementation
401*cdf0e10cSrcweir    with no encryption. Objective target is to avoid linking against
402*cdf0e10cSrcweir    libcrypt (not available on caldera open linux 2.2 #63822#) */
403*cdf0e10cSrcweir static sal_Char* SAL_CALL
404*cdf0e10cSrcweir osl_dynamicCrypt ( const sal_Char *key, const sal_Char *salt )
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir 	char* (*dynamic_crypt)(char *, char *);
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir 	dynamic_crypt = (char * (*)(char *, char *)) osl_getCrypt();
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 	return dynamic_crypt( (sal_Char*)key, (sal_Char*)salt );
411*cdf0e10cSrcweir }
412*cdf0e10cSrcweir #endif
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir /*
415*cdf0e10cSrcweir  * compare an encrypted and an unencrypted password for equality
416*cdf0e10cSrcweir  * returns true if passwords are equal, false otherwise
417*cdf0e10cSrcweir  * Note: uses crypt() and a mutex instead of crypt_r() since crypt_r needs
418*cdf0e10cSrcweir  * more than 128KByte of external buffer for struct crypt_data
419*cdf0e10cSrcweir  */
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir static sal_Bool SAL_CALL
422*cdf0e10cSrcweir osl_equalPasswords ( const sal_Char *pEncryptedPassword, const sal_Char *pPlainPassword )
423*cdf0e10cSrcweir {
424*cdf0e10cSrcweir 	static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir 	sal_Bool  success;
427*cdf0e10cSrcweir 	sal_Char  salt[3];
428*cdf0e10cSrcweir 	sal_Char *encrypted_plain;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 	salt[0] = pEncryptedPassword[0];
431*cdf0e10cSrcweir 	salt[1] = pEncryptedPassword[1];
432*cdf0e10cSrcweir 	salt[2] = '\0';
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir 	pthread_mutex_lock(&crypt_mutex);
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir #ifndef CRYPT_LINK
437*cdf0e10cSrcweir 	encrypted_plain = (sal_Char *)osl_dynamicCrypt( pPlainPassword, salt );
438*cdf0e10cSrcweir #else
439*cdf0e10cSrcweir 	encrypted_plain = (sal_Char *)crypt( pPlainPassword, salt );
440*cdf0e10cSrcweir #endif
441*cdf0e10cSrcweir 	success = (sal_Bool) (strcmp(pEncryptedPassword, encrypted_plain) == 0);
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir 	pthread_mutex_unlock(&crypt_mutex);
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir 	return success;
446*cdf0e10cSrcweir }
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir #endif /* defined LINUX && !defined NOPAM */
449*cdf0e10cSrcweir oslSecurityError SAL_CALL osl_loginUser(
450*cdf0e10cSrcweir     rtl_uString *ustrUserName,
451*cdf0e10cSrcweir 	rtl_uString *ustrPassword,
452*cdf0e10cSrcweir 	oslSecurity *pSecurity
453*cdf0e10cSrcweir 	)
454*cdf0e10cSrcweir {
455*cdf0e10cSrcweir     oslSecurityError Error;
456*cdf0e10cSrcweir     rtl_String* strUserName=0;
457*cdf0e10cSrcweir     rtl_String* strPassword=0;
458*cdf0e10cSrcweir     sal_Char* pszUserName=0;
459*cdf0e10cSrcweir     sal_Char* pszPassword=0;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir     if ( ustrUserName != 0 )
462*cdf0e10cSrcweir     {
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir         rtl_uString2String( &strUserName,
465*cdf0e10cSrcweir                             rtl_uString_getStr(ustrUserName),
466*cdf0e10cSrcweir                             rtl_uString_getLength(ustrUserName),
467*cdf0e10cSrcweir                             RTL_TEXTENCODING_UTF8,
468*cdf0e10cSrcweir                             OUSTRING_TO_OSTRING_CVTFLAGS );
469*cdf0e10cSrcweir         pszUserName = rtl_string_getStr(strUserName);
470*cdf0e10cSrcweir     }
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir     if ( ustrPassword != 0 )
474*cdf0e10cSrcweir     {
475*cdf0e10cSrcweir         rtl_uString2String( &strPassword,
476*cdf0e10cSrcweir                             rtl_uString_getStr(ustrPassword),
477*cdf0e10cSrcweir                             rtl_uString_getLength(ustrPassword),
478*cdf0e10cSrcweir                             RTL_TEXTENCODING_UTF8,
479*cdf0e10cSrcweir                             OUSTRING_TO_OSTRING_CVTFLAGS );
480*cdf0e10cSrcweir         pszPassword = rtl_string_getStr(strPassword);
481*cdf0e10cSrcweir     }
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir     Error=osl_psz_loginUser(pszUserName,pszPassword,pSecurity);
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     if ( strUserName != 0 )
487*cdf0e10cSrcweir     {
488*cdf0e10cSrcweir         rtl_string_release(strUserName);
489*cdf0e10cSrcweir     }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir     if ( strPassword)
492*cdf0e10cSrcweir     {
493*cdf0e10cSrcweir         rtl_string_release(strPassword);
494*cdf0e10cSrcweir     }
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir     return Error;
498*cdf0e10cSrcweir }
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir static oslSecurityError SAL_CALL
502*cdf0e10cSrcweir osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
503*cdf0e10cSrcweir 			   oslSecurity* pSecurity)
504*cdf0e10cSrcweir {
505*cdf0e10cSrcweir #if defined NETBSD || defined SCO || defined AIX || defined FREEBSD || \
506*cdf0e10cSrcweir 	defined MACOSX
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir 	return osl_Security_E_None;
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir #else
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir     oslSecurityError nError = osl_Security_E_Unknown;
513*cdf0e10cSrcweir     oslSecurityImpl * p = NULL;
514*cdf0e10cSrcweir     if (pszUserName != NULL && pszPasswd != NULL && pSecurity != NULL) {
515*cdf0e10cSrcweir         /* get nis or normal password, should succeed for any known user, but
516*cdf0e10cSrcweir            perhaps the password is wrong (i.e. 'x') if shadow passwords are in
517*cdf0e10cSrcweir            use or authentication must be done by PAM */
518*cdf0e10cSrcweir         size_t n = 0;
519*cdf0e10cSrcweir         int err = 0;
520*cdf0e10cSrcweir         struct passwd * found = NULL;
521*cdf0e10cSrcweir         for (;;) {
522*cdf0e10cSrcweir             p = growSecurityImpl(p, &n);
523*cdf0e10cSrcweir             if (p == NULL) {
524*cdf0e10cSrcweir                 break;
525*cdf0e10cSrcweir             }
526*cdf0e10cSrcweir             err = getpwnam_r(
527*cdf0e10cSrcweir                 pszUserName, &p->m_pPasswd, p->m_buffer, n, &found);
528*cdf0e10cSrcweir             if (err != ERANGE) {
529*cdf0e10cSrcweir                 break;
530*cdf0e10cSrcweir             }
531*cdf0e10cSrcweir         }
532*cdf0e10cSrcweir         if (p != NULL && err == 0) {
533*cdf0e10cSrcweir             if (found == NULL) {
534*cdf0e10cSrcweir                 nError = osl_Security_E_UserUnknown;
535*cdf0e10cSrcweir             } else {
536*cdf0e10cSrcweir #if defined LINUX && !defined NOPAM
537*cdf0e10cSrcweir                 /* only root is able to read the /etc/shadow passwd, a normal
538*cdf0e10cSrcweir                    user even can't read his own encrypted passwd */
539*cdf0e10cSrcweir                 if (osl_equalPasswords(p->m_pPasswd.pw_passwd, pszPasswd) ||
540*cdf0e10cSrcweir                     osl_PamAuthentification(pszUserName, pszPasswd))
541*cdf0e10cSrcweir                 {
542*cdf0e10cSrcweir                     nError = osl_Security_E_None;
543*cdf0e10cSrcweir                 } else {
544*cdf0e10cSrcweir                     char buffer[1024];
545*cdf0e10cSrcweir                     struct spwd result_buf;
546*cdf0e10cSrcweir                     struct spwd * pShadowPasswd;
547*cdf0e10cSrcweir                     buffer[0] = '\0';
548*cdf0e10cSrcweir                     if (getspnam_r(
549*cdf0e10cSrcweir                             pszUserName, &result_buf, buffer, sizeof buffer,
550*cdf0e10cSrcweir                             &pShadowPasswd) == 0 &&
551*cdf0e10cSrcweir                         pShadowPasswd != NULL)
552*cdf0e10cSrcweir                     {
553*cdf0e10cSrcweir                         nError =
554*cdf0e10cSrcweir                             osl_equalPasswords(
555*cdf0e10cSrcweir                                 pShadowPasswd->sp_pwdp, pszPasswd)
556*cdf0e10cSrcweir                             ? osl_Security_E_None
557*cdf0e10cSrcweir                             : osl_Security_E_WrongPassword;
558*cdf0e10cSrcweir                     } else if (getuid() == 0) {
559*cdf0e10cSrcweir                         /* mfe: Try to verify the root-password via nis */
560*cdf0e10cSrcweir                         if (getspnam_r(
561*cdf0e10cSrcweir                                 "root", &result_buf, buffer, sizeof buffer,
562*cdf0e10cSrcweir                                 &pShadowPasswd) == 0 &&
563*cdf0e10cSrcweir                             pShadowPasswd != NULL &&
564*cdf0e10cSrcweir                             osl_equalPasswords(
565*cdf0e10cSrcweir                                 pShadowPasswd->sp_pwdp, pszPasswd))
566*cdf0e10cSrcweir                         {
567*cdf0e10cSrcweir                             nError = osl_Security_E_None;
568*cdf0e10cSrcweir                         } else {
569*cdf0e10cSrcweir                             /* mfe: we can't get via nis (glibc2.0.x has bug in
570*cdf0e10cSrcweir                                getspnam_r) we try it with the normal getspnam */
571*cdf0e10cSrcweir                             static pthread_mutex_t pwmutex =
572*cdf0e10cSrcweir                                 PTHREAD_MUTEX_INITIALIZER;
573*cdf0e10cSrcweir                             pthread_mutex_lock(&pwmutex);
574*cdf0e10cSrcweir                             pShadowPasswd = getspnam("root");
575*cdf0e10cSrcweir                             pthread_mutex_unlock(&pwmutex);
576*cdf0e10cSrcweir                             nError =
577*cdf0e10cSrcweir                                 ((pShadowPasswd != NULL &&
578*cdf0e10cSrcweir                                   osl_equalPasswords(
579*cdf0e10cSrcweir                                       pShadowPasswd->sp_pwdp, pszPasswd)) ||
580*cdf0e10cSrcweir                                  osl_PamAuthentification("root", pszPasswd))
581*cdf0e10cSrcweir                                 ? osl_Security_E_None
582*cdf0e10cSrcweir                                 : osl_Security_E_WrongPassword;
583*cdf0e10cSrcweir                         }
584*cdf0e10cSrcweir                     }
585*cdf0e10cSrcweir                 }
586*cdf0e10cSrcweir #else
587*cdf0e10cSrcweir                 char buffer[1024];
588*cdf0e10cSrcweir                 struct spwd spwdStruct;
589*cdf0e10cSrcweir                 buffer[0] = '\0';
590*cdf0e10cSrcweir #ifndef NEW_SHADOW_API
591*cdf0e10cSrcweir                 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer) != NULL)
592*cdf0e10cSrcweir #else
593*cdf0e10cSrcweir                 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer, NULL) == 0)
594*cdf0e10cSrcweir #endif
595*cdf0e10cSrcweir                 {
596*cdf0e10cSrcweir                     char salt[3];
597*cdf0e10cSrcweir                     char * cryptPasswd;
598*cdf0e10cSrcweir                     strncpy(salt, spwdStruct.sp_pwdp, 2);
599*cdf0e10cSrcweir                     salt[2] = '\0';
600*cdf0e10cSrcweir                     cryptPasswd = (char *) crypt(pszPasswd, salt);
601*cdf0e10cSrcweir                     if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
602*cdf0e10cSrcweir                         nError = osl_Security_E_None;
603*cdf0e10cSrcweir                     } else if (getuid() == 0 &&
604*cdf0e10cSrcweir #ifndef NEW_SHADOW_API
605*cdf0e10cSrcweir                                (getspnam_r("root", &spwdStruct, buffer, sizeof buffer) != NULL))
606*cdf0e10cSrcweir #else
607*cdf0e10cSrcweir                                (getspnam_r("root", &spwdStruct, buffer, sizeof buffer, NULL) == 0))
608*cdf0e10cSrcweir #endif
609*cdf0e10cSrcweir                     {
610*cdf0e10cSrcweir                         /* if current process is running as root, allow to logon
611*cdf0e10cSrcweir                            as any other user */
612*cdf0e10cSrcweir                         strncpy(salt, spwdStruct.sp_pwdp, 2);
613*cdf0e10cSrcweir                         salt[2] = '\0';
614*cdf0e10cSrcweir                         cryptPasswd = (char *) crypt(pszPasswd, salt);
615*cdf0e10cSrcweir                         if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
616*cdf0e10cSrcweir                             nError = osl_Security_E_None;
617*cdf0e10cSrcweir                         }
618*cdf0e10cSrcweir                     } else {
619*cdf0e10cSrcweir                         nError = osl_Security_E_WrongPassword;
620*cdf0e10cSrcweir                     }
621*cdf0e10cSrcweir                 }
622*cdf0e10cSrcweir #endif
623*cdf0e10cSrcweir             }
624*cdf0e10cSrcweir         }
625*cdf0e10cSrcweir     }
626*cdf0e10cSrcweir     if (nError == osl_Security_E_None) {
627*cdf0e10cSrcweir         *pSecurity = p;
628*cdf0e10cSrcweir     } else {
629*cdf0e10cSrcweir         deleteSecurityImpl(p);
630*cdf0e10cSrcweir         *pSecurity = NULL;
631*cdf0e10cSrcweir     }
632*cdf0e10cSrcweir     return nError;
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir #endif
635*cdf0e10cSrcweir }
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir oslSecurityError SAL_CALL osl_loginUserOnFileServer(
638*cdf0e10cSrcweir     rtl_uString *strUserName,
639*cdf0e10cSrcweir 	rtl_uString *strPasswd,
640*cdf0e10cSrcweir 	rtl_uString *strFileServer,
641*cdf0e10cSrcweir 	oslSecurity *pSecurity
642*cdf0e10cSrcweir 	)
643*cdf0e10cSrcweir {
644*cdf0e10cSrcweir     (void) strUserName; /* unused */
645*cdf0e10cSrcweir     (void) strPasswd; /* unused */
646*cdf0e10cSrcweir     (void) strFileServer; /* unused */
647*cdf0e10cSrcweir     (void) pSecurity; /* unused */
648*cdf0e10cSrcweir 	return osl_Security_E_UserUnknown;
649*cdf0e10cSrcweir }
650*cdf0e10cSrcweir 
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **ustrIdent)
653*cdf0e10cSrcweir {
654*cdf0e10cSrcweir     sal_Bool bRet=sal_False;
655*cdf0e10cSrcweir     sal_Char pszIdent[1024];
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir     pszIdent[0] = '\0';
658*cdf0e10cSrcweir 
659*cdf0e10cSrcweir     bRet = osl_psz_getUserIdent(Security,pszIdent,sizeof(pszIdent));
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir     rtl_string2UString( ustrIdent, pszIdent, rtl_str_getLength( pszIdent ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
662*cdf0e10cSrcweir     OSL_ASSERT(*ustrIdent != NULL);
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir     return bRet;
665*cdf0e10cSrcweir }
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax)
669*cdf0e10cSrcweir {
670*cdf0e10cSrcweir 	sal_Char  buffer[32];
671*cdf0e10cSrcweir     sal_Int32 nChr;
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir 	oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir     if (pSecImpl == NULL)
676*cdf0e10cSrcweir 	    return sal_False;
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 	nChr = snprintf(buffer, sizeof(buffer), "%u", pSecImpl->m_pPasswd.pw_uid);
679*cdf0e10cSrcweir     if ( nChr < 0 || SAL_INT_CAST(sal_uInt32, nChr) >= sizeof(buffer)
680*cdf0e10cSrcweir          || SAL_INT_CAST(sal_uInt32, nChr) >= nMax )
681*cdf0e10cSrcweir         return sal_False; /* leave *pszIdent unmodified in case of failure */
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir 	memcpy(pszIdent, buffer, nChr+1);
684*cdf0e10cSrcweir     return sal_True;
685*cdf0e10cSrcweir }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **ustrName)
688*cdf0e10cSrcweir {
689*cdf0e10cSrcweir     sal_Bool bRet=sal_False;
690*cdf0e10cSrcweir     sal_Char pszName[1024];
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir     pszName[0] = '\0';
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir     bRet = osl_psz_getUserName(Security,pszName,sizeof(pszName));
695*cdf0e10cSrcweir 
696*cdf0e10cSrcweir     rtl_string2UString( ustrName, pszName, rtl_str_getLength( pszName ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
697*cdf0e10cSrcweir     OSL_ASSERT(*ustrName != NULL);
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir     return bRet;
700*cdf0e10cSrcweir }
701*cdf0e10cSrcweir 
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir 
704*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32  nMax)
705*cdf0e10cSrcweir {
706*cdf0e10cSrcweir 	oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir     if (pSecImpl == NULL)
709*cdf0e10cSrcweir 	    return sal_False;
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir 	strncpy(pszName, pSecImpl->m_pPasswd.pw_name, nMax);
712*cdf0e10cSrcweir 
713*cdf0e10cSrcweir     return sal_True;
714*cdf0e10cSrcweir }
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
717*cdf0e10cSrcweir {
718*cdf0e10cSrcweir     sal_Bool bRet=sal_False;
719*cdf0e10cSrcweir     sal_Char pszDirectory[PATH_MAX];
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir     pszDirectory[0] = '\0';
722*cdf0e10cSrcweir 
723*cdf0e10cSrcweir     bRet = osl_psz_getHomeDir(Security,pszDirectory,sizeof(pszDirectory));
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir     if ( bRet == sal_True )
726*cdf0e10cSrcweir     {
727*cdf0e10cSrcweir         rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
728*cdf0e10cSrcweir         OSL_ASSERT(*pustrDirectory != NULL);
729*cdf0e10cSrcweir         osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
730*cdf0e10cSrcweir     }
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir     return bRet;
733*cdf0e10cSrcweir }
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
737*cdf0e10cSrcweir {
738*cdf0e10cSrcweir 	oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir     if (pSecImpl == NULL)
741*cdf0e10cSrcweir 	    return sal_False;
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir 	/* if current user, check also environment for HOME */
744*cdf0e10cSrcweir 	if (getuid() == pSecImpl->m_pPasswd.pw_uid)
745*cdf0e10cSrcweir 	{
746*cdf0e10cSrcweir 		sal_Char *pStr = NULL;
747*cdf0e10cSrcweir #ifdef SOLARIS
748*cdf0e10cSrcweir 		char	buffer[8192];
749*cdf0e10cSrcweir 
750*cdf0e10cSrcweir 		struct passwd pwd;
751*cdf0e10cSrcweir 		struct passwd *ppwd;
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir #ifdef _POSIX_PTHREAD_SEMANTICS
754*cdf0e10cSrcweir 		if ( 0 != getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer), &ppwd ) )
755*cdf0e10cSrcweir 			ppwd = NULL;
756*cdf0e10cSrcweir #else
757*cdf0e10cSrcweir 		ppwd = getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer) );
758*cdf0e10cSrcweir #endif
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 		if ( ppwd )
761*cdf0e10cSrcweir 			pStr = ppwd->pw_dir;
762*cdf0e10cSrcweir #else
763*cdf0e10cSrcweir 		pStr = getenv("HOME");
764*cdf0e10cSrcweir #endif
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir 		if ((pStr != NULL) && (strlen(pStr) > 0) &&
767*cdf0e10cSrcweir 		    (access(pStr, 0) == 0))
768*cdf0e10cSrcweir 			strncpy(pszDirectory, pStr, nMax);
769*cdf0e10cSrcweir 		else
770*cdf0e10cSrcweir             strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
771*cdf0e10cSrcweir 	}
772*cdf0e10cSrcweir 	else
773*cdf0e10cSrcweir 		strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir 	return sal_True;
776*cdf0e10cSrcweir }
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
779*cdf0e10cSrcweir {
780*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
781*cdf0e10cSrcweir     sal_Char pszDirectory[PATH_MAX];
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir     pszDirectory[0] = '\0';
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir     bRet = osl_psz_getConfigDir(Security,pszDirectory,sizeof(pszDirectory));
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir     if ( bRet == sal_True )
788*cdf0e10cSrcweir     {
789*cdf0e10cSrcweir         rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
790*cdf0e10cSrcweir         OSL_ASSERT(*pustrDirectory != NULL);
791*cdf0e10cSrcweir         osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
792*cdf0e10cSrcweir     }
793*cdf0e10cSrcweir 
794*cdf0e10cSrcweir     return bRet;
795*cdf0e10cSrcweir }
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir #ifndef MACOSX
798*cdf0e10cSrcweir 
799*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
800*cdf0e10cSrcweir {
801*cdf0e10cSrcweir     sal_Char *pStr = getenv("XDG_CONFIG_HOME");
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir     if ((pStr == NULL) || (strlen(pStr) == 0) ||
804*cdf0e10cSrcweir         (access(pStr, 0) != 0))
805*cdf0e10cSrcweir         return (osl_psz_getHomeDir(Security, pszDirectory, nMax));
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir     strncpy(pszDirectory, pStr, nMax);
808*cdf0e10cSrcweir     return sal_True;
809*cdf0e10cSrcweir }
810*cdf0e10cSrcweir 
811*cdf0e10cSrcweir #else
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir /*
814*cdf0e10cSrcweir  * FIXME: rewrite to use more flexible
815*cdf0e10cSrcweir  * NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
816*cdf0e10cSrcweir  * as soon as we can bumb the baseline to Tiger (for NSApplicationSupportDirectory) and have
817*cdf0e10cSrcweir  * support for Objective-C in the build environment
818*cdf0e10cSrcweir  */
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir #define MACOSX_CONFIG_DIR "/Library/Application Support"
821*cdf0e10cSrcweir static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
822*cdf0e10cSrcweir {
823*cdf0e10cSrcweir     if( osl_psz_getHomeDir(Security, pszDirectory, nMax - sizeof(MACOSX_CONFIG_DIR) + 1) )
824*cdf0e10cSrcweir     {
825*cdf0e10cSrcweir         strcat( pszDirectory, MACOSX_CONFIG_DIR );
826*cdf0e10cSrcweir         return sal_True;
827*cdf0e10cSrcweir     }
828*cdf0e10cSrcweir 
829*cdf0e10cSrcweir     return sal_False;
830*cdf0e10cSrcweir }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir #endif
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
835*cdf0e10cSrcweir {
836*cdf0e10cSrcweir 	oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir     if (pSecImpl == NULL)
839*cdf0e10cSrcweir 	    return sal_False;
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir     if (pSecImpl->m_pPasswd.pw_uid != 0)
842*cdf0e10cSrcweir 		return (sal_False);
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir 	return (sal_True);
845*cdf0e10cSrcweir }
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
848*cdf0e10cSrcweir {
849*cdf0e10cSrcweir     deleteSecurityImpl(Security);
850*cdf0e10cSrcweir }
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
854*cdf0e10cSrcweir {
855*cdf0e10cSrcweir     (void) Security; /* unused */
856*cdf0e10cSrcweir     return sal_False;
857*cdf0e10cSrcweir }
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
860*cdf0e10cSrcweir {
861*cdf0e10cSrcweir     (void) Security; /* unused */
862*cdf0e10cSrcweir }
863