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