1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: security.c,v $
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 ************************************************************************/
33 /* Solaris 8 has no C99 stdint.h, and Solaris generally seems not to miss it for
35 #if !defined __SUNPRO_C
41 #include <osl/security.h>
42 #include <osl/diagnose.h>
44 #include "osl/thread.h"
47 #if defined LINUX || defined SOLARIS
54 #ifndef PAM_BINARY_MSG
55 #define PAM_BINARY_MSG 6
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
71 m
= sysconf(_SC_GETPW_R_SIZE_MAX
);
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: */
78 OSL_ASSERT(m
>= 0 && (unsigned long) m
< SIZE_MAX
);
83 /* some platforms like Mac OS X 1.3 do not define _SC_GETPW_R_SIZE_MAX: */
88 static oslSecurityImpl
* growSecurityImpl(
89 oslSecurityImpl
* impl
, size_t * bufSize
)
92 oslSecurityImpl
* p
= 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: */
99 } else if (*bufSize
<= SIZE_MAX
/ 2) {
103 if (n
<= SIZE_MAX
- offsetof(oslSecurityImpl
, m_buffer
)) {
105 n
+= offsetof(oslSecurityImpl
, m_buffer
);
107 *bufSize
= SIZE_MAX
- offsetof(oslSecurityImpl
, m_buffer
);
110 p
= realloc(impl
, n
);
118 static void deleteSecurityImpl(oslSecurityImpl
* impl
) {
122 oslSecurity SAL_CALL
osl_getCurrentSecurity()
125 oslSecurityImpl
* p
= NULL
;
127 struct passwd
* found
;
128 p
= growSecurityImpl(p
, &n
);
132 switch (getpwuid_r(getuid(), &p
->m_pPasswd
, p
->m_buffer
, n
, &found
)) {
141 deleteSecurityImpl(p
);
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>
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
);
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
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
188 osl_PamConversation (int num_msg
, const struct pam_message
**msgm
,
189 struct pam_response
**response
, void *appdata_ptr
)
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
)
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
);
218 case PAM_PROMPT_ECHO_ON
:
219 p_reply
[ i
].resp_retcode
= 0;
220 p_reply
[ i
].resp
= strdup( pam_data
->name
);
224 case PAM_BINARY_PROMPT
:
226 p_reply
[ i
].resp_retcode
= 0;
227 p_reply
[ i
].resp
= NULL
;
235 /* free resources on 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
);
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
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
;
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) */
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
) );
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
) )
302 /* never try again */
303 load_once
= sal_True
;
311 * User Identification using PAM
315 osl_PamAuthentification( const sal_Char
* name
, const sal_Char
* password
)
317 sal_Bool success
= sal_False
;
320 sal_PamModule
* pam_module
;
322 pam_module
= osl_getPAM();
323 if ( pam_module
!= NULL
)
326 pam_handle_t
*pam_handle
= NULL
;
327 struct pam_conv pam_conversation
;
328 sal_PamData pam_data
;
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
);
339 return_value
= pam_module
->pam_start( "su", name
,
340 &pam_conversation
, &pam_handle
);
342 return_value
= pam_start( "su", name
,
343 &pam_conversation
, &pam_handle
);
345 if (return_value
== PAM_SUCCESS
)
347 return_value
= pam_module
->pam_authenticate(pam_handle
, 0);
349 return_value
= pam_authenticate(pam_handle
, 0);
351 if (return_value
== PAM_SUCCESS
)
353 return_value
= pam_module
->pam_acct_mgmt(pam_handle
, 0);
354 pam_module
->pam_end( pam_handle
, return_value
);
356 return_value
= pam_acct_mgmt(pam_handle
, 0);
357 pam_end( pam_handle
, return_value
);
360 success
= (sal_Bool
)(return_value
== PAM_SUCCESS
);
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 */
379 /* load-on-call crypt library and crypt symbol */
380 static void* SAL_CALL
383 static char* (*crypt_sym
)(const char*, const char*) = NULL
;
384 static sal_Bool load_once
= sal_False
;
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
);
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
;
431 sal_Char
*encrypted_plain
;
433 salt
[0] = pEncryptedPassword
[0];
434 salt
[1] = pEncryptedPassword
[1];
437 pthread_mutex_lock(&crypt_mutex
);
440 encrypted_plain
= (sal_Char
*)osl_dynamicCrypt( pPlainPassword
, salt
);
442 encrypted_plain
= (sal_Char
*)crypt( pPlainPassword
, salt
);
444 success
= (sal_Bool
) (strcmp(pEncryptedPassword
, encrypted_plain
) == 0);
446 pthread_mutex_unlock(&crypt_mutex
);
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
);
496 rtl_string_release(strPassword
);
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 || \
511 return osl_Security_E_None
;
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 */
523 struct passwd
* found
= NULL
;
525 p
= growSecurityImpl(p
, &n
);
530 pszUserName
, &p
->m_pPasswd
, p
->m_buffer
, n
, &found
);
535 if (p
!= NULL
&& err
== 0) {
537 nError
= osl_Security_E_UserUnknown
;
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
;
548 struct spwd result_buf
;
549 struct spwd
* pShadowPasswd
;
552 pszUserName
, &result_buf
, buffer
, sizeof buffer
,
553 &pShadowPasswd
) == 0 &&
554 pShadowPasswd
!= NULL
)
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 */
564 "root", &result_buf
, buffer
, sizeof buffer
,
565 &pShadowPasswd
) == 0 &&
566 pShadowPasswd
!= NULL
&&
568 pShadowPasswd
->sp_pwdp
, pszPasswd
))
570 nError
= osl_Security_E_None
;
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
);
580 ((pShadowPasswd
!= NULL
&&
582 pShadowPasswd
->sp_pwdp
, pszPasswd
)) ||
583 osl_PamAuthentification("root", pszPasswd
))
584 ? osl_Security_E_None
585 : osl_Security_E_WrongPassword
;
591 struct spwd spwdStruct
;
593 #ifndef NEW_SHADOW_API
594 if (getspnam_r(pszUserName
, &spwdStruct
, buffer
, sizeof buffer
) != NULL
)
596 if (getspnam_r(pszUserName
, &spwdStruct
, buffer
, sizeof buffer
, NULL
) == 0)
601 strncpy(salt
, spwdStruct
.sp_pwdp
, 2);
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
))
610 (getspnam_r("root", &spwdStruct
, buffer
, sizeof buffer
, NULL
) == 0))
613 /* if current process is running as root, allow to logon
615 strncpy(salt
, spwdStruct
.sp_pwdp
, 2);
617 cryptPasswd
= (char *) crypt(pszPasswd
, salt
);
618 if (strcmp(spwdStruct
.sp_pwdp
, cryptPasswd
) == 0) {
619 nError
= osl_Security_E_None
;
622 nError
= osl_Security_E_WrongPassword
;
629 if (nError
== osl_Security_E_None
) {
632 deleteSecurityImpl(p
);
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];
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
);
671 sal_Bool SAL_CALL
osl_psz_getUserIdent(oslSecurity Security
, sal_Char
*pszIdent
, sal_uInt32 nMax
)
676 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
678 if (pSecImpl
== NULL
)
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);
690 sal_Bool SAL_CALL
osl_getUserName(oslSecurity Security
, rtl_uString
**ustrName
)
692 sal_Bool bRet
=sal_False
;
693 sal_Char pszName
[1024];
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
);
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
)
714 strncpy(pszName
, pSecImpl
->m_pPasswd
.pw_name
, nMax
);
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
);
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
)
746 /* if current user, check also environment for HOME */
747 if (getuid() == pSecImpl
->m_pPasswd
.pw_uid
)
749 sal_Char
*pStr
= NULL
;
756 #ifdef _POSIX_PTHREAD_SEMANTICS
757 if ( 0 != getpwuid_r(getuid(), &pwd
, buffer
, sizeof(buffer
), &ppwd
) )
760 ppwd
= getpwuid_r(getuid(), &pwd
, buffer
, sizeof(buffer
) );
766 pStr
= getenv("HOME");
769 if ((pStr
!= NULL
) && (strlen(pStr
) > 0) &&
770 (access(pStr
, 0) == 0))
771 strncpy(pszDirectory
, pStr
, nMax
);
773 strncpy(pszDirectory
, pSecImpl
->m_pPasswd
.pw_dir
, nMax
);
776 strncpy(pszDirectory
, pSecImpl
->m_pPasswd
.pw_dir
, nMax
);
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
);
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
);
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
);
837 sal_Bool SAL_CALL
osl_isAdministrator(oslSecurity Security
)
839 oslSecurityImpl
*pSecImpl
= (oslSecurityImpl
*)Security
;
841 if (pSecImpl
== NULL
)
844 if (pSecImpl
->m_pPasswd
.pw_uid
!= 0)
850 void SAL_CALL
osl_freeSecurityHandle(oslSecurity Security
)
852 deleteSecurityImpl(Security
);
856 sal_Bool SAL_CALL
osl_loadUserProfile(oslSecurity Security
)
858 (void) Security
; /* unused */
862 void SAL_CALL
osl_unloadUserProfile(oslSecurity Security
)
864 (void) Security
; /* unused */