update dev300-m57
[ooovba.git] / sal / osl / unx / security.c
bloba5b883b356c3651b6e0270aa14df7846106fe543
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: security.c,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <stddef.h>
33 /* Solaris 8 has no C99 stdint.h, and Solaris generally seems not to miss it for
34 SIZE_MAX: */
35 #if !defined __SUNPRO_C
36 #include <stdint.h>
37 #endif
39 #include "system.h"
41 #include <osl/security.h>
42 #include <osl/diagnose.h>
44 #include "osl/thread.h"
45 #include "osl/file.h"
47 #if defined LINUX || defined SOLARIS
48 #include <crypt.h>
49 #endif
51 #include "secimpl.h"
53 #ifndef NOPAM
54 #ifndef PAM_BINARY_MSG
55 #define PAM_BINARY_MSG 6
56 #endif
57 #endif
59 static oslSecurityError SAL_CALL
60 osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
61 oslSecurity* pSecurity);
62 sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax);
63 static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32 nMax);
64 static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
65 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax);
67 static sal_Bool sysconf_SC_GETPW_R_SIZE_MAX(size_t * value) {
68 #if defined _SC_GETPW_R_SIZE_MAX
69 long m;
70 errno = 0;
71 m = sysconf(_SC_GETPW_R_SIZE_MAX);
72 if (m == -1) {
73 /* _SC_GETPW_R_SIZE_MAX has no limit; some platforms like certain
74 FreeBSD versions support sysconf(_SC_GETPW_R_SIZE_MAX) in a broken
75 way and always set EINVAL, so be resilient here: */
76 return sal_False;
77 } else {
78 OSL_ASSERT(m >= 0 && (unsigned long) m < SIZE_MAX);
79 *value = (size_t) m;
80 return sal_True;
82 #else
83 /* some platforms like Mac OS X 1.3 do not define _SC_GETPW_R_SIZE_MAX: */
84 return sal_False;
85 #endif
88 static oslSecurityImpl * growSecurityImpl(
89 oslSecurityImpl * impl, size_t * bufSize)
91 size_t n = 0;
92 oslSecurityImpl * p = NULL;
93 if (impl == NULL) {
94 if (!sysconf_SC_GETPW_R_SIZE_MAX(&n)) {
95 /* choose something sensible (the callers of growSecurityImpl will
96 detect it if the allocated buffer is too small: */
97 n = 1024;
99 } else if (*bufSize <= SIZE_MAX / 2) {
100 n = 2 * *bufSize;
102 if (n != 0) {
103 if (n <= SIZE_MAX - offsetof(oslSecurityImpl, m_buffer)) {
104 *bufSize = n;
105 n += offsetof(oslSecurityImpl, m_buffer);
106 } else {
107 *bufSize = SIZE_MAX - offsetof(oslSecurityImpl, m_buffer);
108 n = SIZE_MAX;
110 p = realloc(impl, n);
112 if (p == NULL) {
113 free(impl);
115 return p;
118 static void deleteSecurityImpl(oslSecurityImpl * impl) {
119 free(impl);
122 oslSecurity SAL_CALL osl_getCurrentSecurity()
124 size_t n = 0;
125 oslSecurityImpl * p = NULL;
126 for (;;) {
127 struct passwd * found;
128 p = growSecurityImpl(p, &n);
129 if (p == NULL) {
130 return NULL;
132 switch (getpwuid_r(getuid(), &p->m_pPasswd, p->m_buffer, n, &found)) {
133 case ERANGE:
134 break;
135 case 0:
136 if (found != NULL) {
137 return p;
139 /* fall through */
140 default:
141 deleteSecurityImpl(p);
142 return NULL;
148 #if defined LINUX && !defined NOPAM
152 * osl Routines for Pluggable Authentication Modules (PAM)
153 * tested with Linux-PAM 0.66 on Redhat-6.0 and
154 * Linux-PAM 0.64 on RedHat-5.2,
155 * XXX Will probably not run on PAM 0.59 or prior, since
156 * number of pam_response* responses has changed
160 #include <security/pam_appl.h>
162 typedef struct {
163 char* name;
164 char* password;
165 } sal_PamData;
167 typedef struct {
168 int (*pam_start)(const char *service_name, const char *user,
169 const struct pam_conv *pam_conversation,
170 pam_handle_t **pamh);
171 int (*pam_end) (pam_handle_t *pamh, int pam_status);
172 int (*pam_authenticate) (pam_handle_t *pamh, int flags);
173 int (*pam_acct_mgmt) (pam_handle_t *pamh, int flags);
174 } sal_PamModule;
177 * Implement a pam-conversation callback-routine,
178 * it just supply name and password instead of prompting the user.
179 * I guess that echo-off means 'ask for password' and echo-on means
180 * 'ask for user-name'. In fact I've never been asked anything else
181 * than the password
182 * XXX Please notice that if a pam-module does ask anything else, we
183 * are completely lost, and a pam-module is free to do so
184 * XXX
187 static int
188 osl_PamConversation (int num_msg, const struct pam_message **msgm,
189 struct pam_response **response, void *appdata_ptr)
191 int i;
192 sal_Bool error;
193 sal_PamData *pam_data;
194 struct pam_response *p_reply;
196 /* resource initialization */
197 pam_data = (sal_PamData*) appdata_ptr;
198 p_reply = (struct pam_response *) calloc( num_msg,
199 sizeof(struct pam_response));
200 if ( p_reply == NULL || pam_data == NULL )
202 if ( p_reply != NULL )
203 free ( p_reply );
204 *response = NULL;
205 return PAM_CONV_ERR;
208 /* pseudo dialog */
209 error = sal_False;
210 for ( i = 0; i < num_msg ; i++ )
212 switch ( msgm[ i ]->msg_style )
214 case PAM_PROMPT_ECHO_OFF:
215 p_reply[ i ].resp_retcode = 0;
216 p_reply[ i ].resp = strdup( pam_data->password );
217 break;
218 case PAM_PROMPT_ECHO_ON:
219 p_reply[ i ].resp_retcode = 0;
220 p_reply[ i ].resp = strdup( pam_data->name );
221 break;
222 case PAM_ERROR_MSG:
223 case PAM_TEXT_INFO:
224 case PAM_BINARY_PROMPT:
225 case PAM_BINARY_MSG:
226 p_reply[ i ].resp_retcode = 0;
227 p_reply[ i ].resp = NULL;
228 break;
229 default:
230 error = sal_True;
231 break;
235 /* free resources on error */
236 if ( error )
238 for ( i = 0; i < num_msg ; i++ )
239 if ( p_reply[ i ].resp )
241 memset ( p_reply[ i ].resp, 0,
242 strlen( p_reply[ i ].resp ) );
243 free ( p_reply[ i ].resp );
245 free ( p_reply );
247 *response = NULL;
248 return PAM_CONV_ERR;
251 /* well done */
252 *response = p_reply;
253 return PAM_SUCCESS;
256 #ifndef PAM_LINK
258 * avoid linking against libpam.so, since it is not available on all systems,
259 * instead load-on-call, returns structure which holds pointer to
260 * pam-functions,
261 * library is never closed in case of success
264 static sal_PamModule* osl_getPAM()
266 static sal_PamModule *pam_module = NULL;
267 static sal_Bool load_once = sal_False;
269 if ( !load_once )
271 /* get library-handle. cannot use osl-module, since
272 RTLD_GLOBAL is required for PAM-0.64 RH 5.2
273 (but not for PAM-0.66 RH 6.0) */
274 void *pam_hdl;
276 pam_hdl = dlopen( "libpam.so.0", RTLD_GLOBAL | RTLD_LAZY );
278 if ( pam_hdl != NULL )
279 pam_module = (sal_PamModule*)calloc( 1, sizeof(sal_PamModule) );
281 /* load functions */
282 if ( pam_module != NULL )
284 pam_module->pam_acct_mgmt = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_acct_mgmt" );
285 pam_module->pam_authenticate
286 = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_authenticate" );
287 pam_module->pam_end = (int (*)(pam_handle_t *, int)) dlsym ( pam_hdl, "pam_end" );
288 pam_module->pam_start = (int (*)(const char *, const char *, const struct pam_conv *, pam_handle_t **)) dlsym ( pam_hdl, "pam_start" );
290 /* free resources, if not completely successful */
291 if ( (pam_module->pam_start == NULL)
292 || (pam_module->pam_end == NULL)
293 || (pam_module->pam_authenticate == NULL)
294 || (pam_module->pam_acct_mgmt == NULL) )
296 free( pam_module );
297 pam_module = NULL;
298 dlclose( pam_hdl );
302 /* never try again */
303 load_once = sal_True;
306 return pam_module;
308 #endif
311 * User Identification using PAM
314 static sal_Bool
315 osl_PamAuthentification( const sal_Char* name, const sal_Char* password )
317 sal_Bool success = sal_False;
319 #ifndef PAM_LINK
320 sal_PamModule* pam_module;
322 pam_module = osl_getPAM();
323 if ( pam_module != NULL )
325 #endif
326 pam_handle_t *pam_handle = NULL;
327 struct pam_conv pam_conversation;
328 sal_PamData pam_data;
330 int return_value;
332 pam_data.name = (char*) name;
333 pam_data.password = (char*) password;
335 pam_conversation.conv = osl_PamConversation;
336 pam_conversation.appdata_ptr = (void*)(&pam_data);
338 #ifndef PAM_LINK
339 return_value = pam_module->pam_start( "su", name,
340 &pam_conversation, &pam_handle);
341 #else
342 return_value = pam_start( "su", name,
343 &pam_conversation, &pam_handle);
344 #endif
345 if (return_value == PAM_SUCCESS )
346 #ifndef PAM_LINK
347 return_value = pam_module->pam_authenticate(pam_handle, 0);
348 #else
349 return_value = pam_authenticate(pam_handle, 0);
350 #endif
351 if (return_value == PAM_SUCCESS )
352 #ifndef PAM_LINK
353 return_value = pam_module->pam_acct_mgmt(pam_handle, 0);
354 pam_module->pam_end( pam_handle, return_value );
355 #else
356 return_value = pam_acct_mgmt(pam_handle, 0);
357 pam_end( pam_handle, return_value );
358 #endif
360 success = (sal_Bool)(return_value == PAM_SUCCESS);
361 #ifndef PAM_LINK
363 #endif
365 return success;
369 #ifndef CRYPT_LINK
370 /* dummy crypt, matches the interface of
371 crypt() but does not encrypt at all */
372 static const sal_Char* SAL_CALL
373 osl_noCrypt ( const sal_Char *key, const sal_Char *salt )
375 (void) salt; /* unused */
376 return key;
379 /* load-on-call crypt library and crypt symbol */
380 static void* SAL_CALL
381 osl_getCrypt()
383 static char* (*crypt_sym)(const char*, const char*) = NULL;
384 static sal_Bool load_once = sal_False;
386 if ( !load_once )
388 void * crypt_library;
390 crypt_library = dlopen( "libcrypt.so.1", RTLD_GLOBAL | RTLD_LAZY ); /* never closed */
391 if ( crypt_library != NULL )
392 crypt_sym = (char* (*)(const char *, const char *)) dlsym(crypt_library, "crypt" );
393 if ( crypt_sym == NULL ) /* no libcrypt or libcrypt without crypt */
394 crypt_sym = (char* (*)(const char *, const char *)) &osl_noCrypt;
396 load_once = sal_True;
399 return (void*)crypt_sym;
402 /* replacement for crypt function for password encryption, uses either
403 strong encryption of dlopen'ed libcrypt.so.1 or dummy implementation
404 with no encryption. Objective target is to avoid linking against
405 libcrypt (not available on caldera open linux 2.2 #63822#) */
406 static sal_Char* SAL_CALL
407 osl_dynamicCrypt ( const sal_Char *key, const sal_Char *salt )
409 char* (*dynamic_crypt)(char *, char *);
411 dynamic_crypt = (char * (*)(char *, char *)) osl_getCrypt();
413 return dynamic_crypt( (sal_Char*)key, (sal_Char*)salt );
415 #endif
418 * compare an encrypted and an unencrypted password for equality
419 * returns true if passwords are equal, false otherwise
420 * Note: uses crypt() and a mutex instead of crypt_r() since crypt_r needs
421 * more than 128KByte of external buffer for struct crypt_data
424 static sal_Bool SAL_CALL
425 osl_equalPasswords ( const sal_Char *pEncryptedPassword, const sal_Char *pPlainPassword )
427 static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
429 sal_Bool success;
430 sal_Char salt[3];
431 sal_Char *encrypted_plain;
433 salt[0] = pEncryptedPassword[0];
434 salt[1] = pEncryptedPassword[1];
435 salt[2] = '\0';
437 pthread_mutex_lock(&crypt_mutex);
439 #ifndef CRYPT_LINK
440 encrypted_plain = (sal_Char *)osl_dynamicCrypt( pPlainPassword, salt );
441 #else
442 encrypted_plain = (sal_Char *)crypt( pPlainPassword, salt );
443 #endif
444 success = (sal_Bool) (strcmp(pEncryptedPassword, encrypted_plain) == 0);
446 pthread_mutex_unlock(&crypt_mutex);
448 return success;
451 #endif /* defined LINUX && !defined NOPAM */
452 oslSecurityError SAL_CALL osl_loginUser(
453 rtl_uString *ustrUserName,
454 rtl_uString *ustrPassword,
455 oslSecurity *pSecurity
458 oslSecurityError Error;
459 rtl_String* strUserName=0;
460 rtl_String* strPassword=0;
461 sal_Char* pszUserName=0;
462 sal_Char* pszPassword=0;
464 if ( ustrUserName != 0 )
467 rtl_uString2String( &strUserName,
468 rtl_uString_getStr(ustrUserName),
469 rtl_uString_getLength(ustrUserName),
470 RTL_TEXTENCODING_UTF8,
471 OUSTRING_TO_OSTRING_CVTFLAGS );
472 pszUserName = rtl_string_getStr(strUserName);
476 if ( ustrPassword != 0 )
478 rtl_uString2String( &strPassword,
479 rtl_uString_getStr(ustrPassword),
480 rtl_uString_getLength(ustrPassword),
481 RTL_TEXTENCODING_UTF8,
482 OUSTRING_TO_OSTRING_CVTFLAGS );
483 pszPassword = rtl_string_getStr(strPassword);
487 Error=osl_psz_loginUser(pszUserName,pszPassword,pSecurity);
489 if ( strUserName != 0 )
491 rtl_string_release(strUserName);
494 if ( strPassword)
496 rtl_string_release(strPassword);
500 return Error;
504 static oslSecurityError SAL_CALL
505 osl_psz_loginUser(const sal_Char* pszUserName, const sal_Char* pszPasswd,
506 oslSecurity* pSecurity)
508 #if defined NETBSD || defined SCO || defined AIX || defined FREEBSD || \
509 defined MACOSX
511 return osl_Security_E_None;
513 #else
515 oslSecurityError nError = osl_Security_E_Unknown;
516 oslSecurityImpl * p = NULL;
517 if (pszUserName != NULL && pszPasswd != NULL && pSecurity != NULL) {
518 /* get nis or normal password, should succeed for any known user, but
519 perhaps the password is wrong (i.e. 'x') if shadow passwords are in
520 use or authentication must be done by PAM */
521 size_t n = 0;
522 int err = 0;
523 struct passwd * found = NULL;
524 for (;;) {
525 p = growSecurityImpl(p, &n);
526 if (p == NULL) {
527 break;
529 err = getpwnam_r(
530 pszUserName, &p->m_pPasswd, p->m_buffer, n, &found);
531 if (err != ERANGE) {
532 break;
535 if (p != NULL && err == 0) {
536 if (found == NULL) {
537 nError = osl_Security_E_UserUnknown;
538 } else {
539 #if defined LINUX && !defined NOPAM
540 /* only root is able to read the /etc/shadow passwd, a normal
541 user even can't read his own encrypted passwd */
542 if (osl_equalPasswords(p->m_pPasswd.pw_passwd, pszPasswd) ||
543 osl_PamAuthentification(pszUserName, pszPasswd))
545 nError = osl_Security_E_None;
546 } else {
547 char buffer[1024];
548 struct spwd result_buf;
549 struct spwd * pShadowPasswd;
550 buffer[0] = '\0';
551 if (getspnam_r(
552 pszUserName, &result_buf, buffer, sizeof buffer,
553 &pShadowPasswd) == 0 &&
554 pShadowPasswd != NULL)
556 nError =
557 osl_equalPasswords(
558 pShadowPasswd->sp_pwdp, pszPasswd)
559 ? osl_Security_E_None
560 : osl_Security_E_WrongPassword;
561 } else if (getuid() == 0) {
562 /* mfe: Try to verify the root-password via nis */
563 if (getspnam_r(
564 "root", &result_buf, buffer, sizeof buffer,
565 &pShadowPasswd) == 0 &&
566 pShadowPasswd != NULL &&
567 osl_equalPasswords(
568 pShadowPasswd->sp_pwdp, pszPasswd))
570 nError = osl_Security_E_None;
571 } else {
572 /* mfe: we can't get via nis (glibc2.0.x has bug in
573 getspnam_r) we try it with the normal getspnam */
574 static pthread_mutex_t pwmutex =
575 PTHREAD_MUTEX_INITIALIZER;
576 pthread_mutex_lock(&pwmutex);
577 pShadowPasswd = getspnam("root");
578 pthread_mutex_unlock(&pwmutex);
579 nError =
580 ((pShadowPasswd != NULL &&
581 osl_equalPasswords(
582 pShadowPasswd->sp_pwdp, pszPasswd)) ||
583 osl_PamAuthentification("root", pszPasswd))
584 ? osl_Security_E_None
585 : osl_Security_E_WrongPassword;
589 #else
590 char buffer[1024];
591 struct spwd spwdStruct;
592 buffer[0] = '\0';
593 #ifndef NEW_SHADOW_API
594 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer) != NULL)
595 #else
596 if (getspnam_r(pszUserName, &spwdStruct, buffer, sizeof buffer, NULL) == 0)
597 #endif
599 char salt[3];
600 char * cryptPasswd;
601 strncpy(salt, spwdStruct.sp_pwdp, 2);
602 salt[2] = '\0';
603 cryptPasswd = (char *) crypt(pszPasswd, salt);
604 if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
605 nError = osl_Security_E_None;
606 } else if (getuid() == 0 &&
607 #ifndef NEW_SHADOW_API
608 (getspnam_r("root", &spwdStruct, buffer, sizeof buffer) != NULL))
609 #else
610 (getspnam_r("root", &spwdStruct, buffer, sizeof buffer, NULL) == 0))
611 #endif
613 /* if current process is running as root, allow to logon
614 as any other user */
615 strncpy(salt, spwdStruct.sp_pwdp, 2);
616 salt[2] = '\0';
617 cryptPasswd = (char *) crypt(pszPasswd, salt);
618 if (strcmp(spwdStruct.sp_pwdp, cryptPasswd) == 0) {
619 nError = osl_Security_E_None;
621 } else {
622 nError = osl_Security_E_WrongPassword;
625 #endif
629 if (nError == osl_Security_E_None) {
630 *pSecurity = p;
631 } else {
632 deleteSecurityImpl(p);
633 *pSecurity = NULL;
635 return nError;
637 #endif
640 oslSecurityError SAL_CALL osl_loginUserOnFileServer(
641 rtl_uString *strUserName,
642 rtl_uString *strPasswd,
643 rtl_uString *strFileServer,
644 oslSecurity *pSecurity
647 (void) strUserName; /* unused */
648 (void) strPasswd; /* unused */
649 (void) strFileServer; /* unused */
650 (void) pSecurity; /* unused */
651 return osl_Security_E_UserUnknown;
655 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **ustrIdent)
657 sal_Bool bRet=sal_False;
658 sal_Char pszIdent[1024];
660 pszIdent[0] = '\0';
662 bRet = osl_psz_getUserIdent(Security,pszIdent,sizeof(pszIdent));
664 rtl_string2UString( ustrIdent, pszIdent, rtl_str_getLength( pszIdent ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
665 OSL_ASSERT(*ustrIdent != NULL);
667 return bRet;
671 sal_Bool SAL_CALL osl_psz_getUserIdent(oslSecurity Security, sal_Char *pszIdent, sal_uInt32 nMax)
673 sal_Char buffer[32];
674 sal_Int32 nChr;
676 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
678 if (pSecImpl == NULL)
679 return sal_False;
681 nChr = snprintf(buffer, sizeof(buffer), "%u", pSecImpl->m_pPasswd.pw_uid);
682 if ( nChr < 0 || SAL_INT_CAST(sal_uInt32, nChr) >= sizeof(buffer)
683 || SAL_INT_CAST(sal_uInt32, nChr) >= nMax )
684 return sal_False; /* leave *pszIdent unmodified in case of failure */
686 memcpy(pszIdent, buffer, nChr+1);
687 return sal_True;
690 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **ustrName)
692 sal_Bool bRet=sal_False;
693 sal_Char pszName[1024];
695 pszName[0] = '\0';
697 bRet = osl_psz_getUserName(Security,pszName,sizeof(pszName));
699 rtl_string2UString( ustrName, pszName, rtl_str_getLength( pszName ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
700 OSL_ASSERT(*ustrName != NULL);
702 return bRet;
707 static sal_Bool SAL_CALL osl_psz_getUserName(oslSecurity Security, sal_Char* pszName, sal_uInt32 nMax)
709 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
711 if (pSecImpl == NULL)
712 return sal_False;
714 strncpy(pszName, pSecImpl->m_pPasswd.pw_name, nMax);
716 return sal_True;
719 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
721 sal_Bool bRet=sal_False;
722 sal_Char pszDirectory[PATH_MAX];
724 pszDirectory[0] = '\0';
726 bRet = osl_psz_getHomeDir(Security,pszDirectory,sizeof(pszDirectory));
728 if ( bRet == sal_True )
730 rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
731 OSL_ASSERT(*pustrDirectory != NULL);
732 osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
735 return bRet;
739 static sal_Bool SAL_CALL osl_psz_getHomeDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
741 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
743 if (pSecImpl == NULL)
744 return sal_False;
746 /* if current user, check also environment for HOME */
747 if (getuid() == pSecImpl->m_pPasswd.pw_uid)
749 sal_Char *pStr = NULL;
750 #ifdef SOLARIS
751 char buffer[8192];
753 struct passwd pwd;
754 struct passwd *ppwd;
756 #ifdef _POSIX_PTHREAD_SEMANTICS
757 if ( 0 != getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer), &ppwd ) )
758 ppwd = NULL;
759 #else
760 ppwd = getpwuid_r(getuid(), &pwd, buffer, sizeof(buffer) );
761 #endif
763 if ( ppwd )
764 pStr = ppwd->pw_dir;
765 #else
766 pStr = getenv("HOME");
767 #endif
769 if ((pStr != NULL) && (strlen(pStr) > 0) &&
770 (access(pStr, 0) == 0))
771 strncpy(pszDirectory, pStr, nMax);
772 else
773 strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
775 else
776 strncpy(pszDirectory, pSecImpl->m_pPasswd.pw_dir, nMax);
778 return sal_True;
781 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
783 sal_Bool bRet = sal_False;
784 sal_Char pszDirectory[PATH_MAX];
786 pszDirectory[0] = '\0';
788 bRet = osl_psz_getConfigDir(Security,pszDirectory,sizeof(pszDirectory));
790 if ( bRet == sal_True )
792 rtl_string2UString( pustrDirectory, pszDirectory, rtl_str_getLength( pszDirectory ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS );
793 OSL_ASSERT(*pustrDirectory != NULL);
794 osl_getFileURLFromSystemPath( *pustrDirectory, pustrDirectory );
797 return bRet;
800 #ifndef MACOSX
802 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
804 sal_Char *pStr = getenv("XDG_CONFIG_HOME");
806 if ((pStr == NULL) || (strlen(pStr) == 0) ||
807 (access(pStr, 0) != 0))
808 return (osl_psz_getHomeDir(Security, pszDirectory, nMax));
810 strncpy(pszDirectory, pStr, nMax);
811 return sal_True;
814 #else
817 * FIXME: rewrite to use more flexible
818 * NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)
819 * as soon as we can bumb the baseline to Tiger (for NSApplicationSupportDirectory) and have
820 * support for Objective-C in the build environment
823 #define MACOSX_CONFIG_DIR "/Library/Application Support"
824 static sal_Bool SAL_CALL osl_psz_getConfigDir(oslSecurity Security, sal_Char* pszDirectory, sal_uInt32 nMax)
826 if( osl_psz_getHomeDir(Security, pszDirectory, nMax - sizeof(MACOSX_CONFIG_DIR) + 1) )
828 strcat( pszDirectory, MACOSX_CONFIG_DIR );
829 return sal_True;
832 return sal_False;
835 #endif
837 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
839 oslSecurityImpl *pSecImpl = (oslSecurityImpl *)Security;
841 if (pSecImpl == NULL)
842 return sal_False;
844 if (pSecImpl->m_pPasswd.pw_uid != 0)
845 return (sal_False);
847 return (sal_True);
850 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
852 deleteSecurityImpl(Security);
856 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
858 (void) Security; /* unused */
859 return sal_False;
862 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
864 (void) Security; /* unused */