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