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