Changeset 79007 in vbox for trunk/src/VBox/Runtime/r3/posix
- Timestamp:
- Jun 5, 2019 5:24:03 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 131152
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r76553 r79007 265 265 return VERR_AUTHENTICATION_FAILURE; 266 266 267 #elif defined(RT_OS_LINUX) 268 struct passwd *pw; 269 270 pw = getpwnam(pszUser); 271 if (!pw) 267 #else 268 /* 269 * Lookup the user in /etc/passwd first. 270 * 271 * Note! On FreeBSD and OS/2 the root user will open /etc/shadow here, so 272 * the getspnam_r step is not necessary. 273 */ 274 struct passwd Pwd; 275 char szBuf[_4K]; 276 struct passwd *pPwd = NULL; 277 if (getpwnam_r(pszUser, &Pwd, szBuf, sizeof(szBuf), &pPwd) != 0) 272 278 return VERR_AUTHENTICATION_FAILURE; 273 274 if (!pszPasswd) 275 pszPasswd = ""; 276 277 struct spwd *spwd; 278 /* works only if /etc/shadow is accessible */ 279 spwd = getspnam(pszUser); 280 if (spwd) 281 pw->pw_passwd = spwd->sp_pwdp; 282 283 /* Default fCorrect=true if no password specified. In that case, pw->pw_passwd 284 * must be NULL (no password set for this user). Fail if a password is specified 285 * but the user does not have one assigned. */ 286 int fCorrect = !pszPasswd || !*pszPasswd; 287 if (pw->pw_passwd && *pw->pw_passwd) 288 { 289 struct crypt_data *data = (struct crypt_data*)RTMemTmpAllocZ(sizeof(*data)); 290 /* be reentrant */ 291 char *pszEncPasswd = crypt_r(pszPasswd, pw->pw_passwd, data); 292 fCorrect = pszEncPasswd && !strcmp(pszEncPasswd, pw->pw_passwd); 293 RTMemTmpFree(data); 294 } 295 if (!fCorrect) 279 if (pPwd == NULL) 296 280 return VERR_AUTHENTICATION_FAILURE; 297 281 298 *pGid = pw->pw_gid; 299 *pUid = pw->pw_uid; 300 return VINF_SUCCESS; 301 302 #elif defined(RT_OS_SOLARIS) 303 struct passwd *ppw, pw; 304 char szBuf[1024]; 305 306 if (getpwnam_r(pszUser, &pw, szBuf, sizeof(szBuf), &ppw) != 0 || ppw == NULL) 307 return VERR_AUTHENTICATION_FAILURE; 308 309 if (!pszPasswd) 310 pszPasswd = ""; 311 312 struct spwd spwd; 313 char szPwdBuf[1024]; 314 /* works only if /etc/shadow is accessible */ 315 if (getspnam_r(pszUser, &spwd, szPwdBuf, sizeof(szPwdBuf)) != NULL) 316 ppw->pw_passwd = spwd.sp_pwdp; 317 318 char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); 319 if (strcmp(pszEncPasswd, ppw->pw_passwd)) 320 return VERR_AUTHENTICATION_FAILURE; 321 322 *pGid = ppw->pw_gid; 323 *pUid = ppw->pw_uid; 324 return VINF_SUCCESS; 325 326 #else 327 NOREF(pszUser); NOREF(pszPasswd); NOREF(pGid); NOREF(pUid); 328 return VERR_AUTHENTICATION_FAILURE; 282 # if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) 283 /* 284 * Ditto for /etc/shadow and replace pw_passwd from above if we can access it: 285 */ 286 struct spwd ShwPwd; 287 char szBuf2[_4K]; 288 # if defined(RT_OS_LINUX) 289 struct spwd *pShwPwd = NULL; 290 if (getspnam_r(pszUser, &ShwPwd, szBuf2, sizeof(szBuf2), &pShwPwd) != 0) 291 pShwPwd = NULL; 292 # else 293 struct spwd *pShwPwd = getspnam_r(pszUser, &ShwPwd, szBuf2, sizeof(szBuf2)); 294 # endif 295 if (pShwPwd != NULL) 296 pPwd->pw_passwd = pShwPwd->sp_pwdp; 297 # endif 298 299 /* 300 * Encrypt the passed in password and see if it matches. 301 */ 302 # if !defined(RT_OS_LINUX) 303 int rc; 304 # else 305 /* Default fCorrect=true if no password specified. In that case, pPwd->pw_passwd 306 must be NULL (no password set for this user). Fail if a password is specified 307 but the user does not have one assigned. */ 308 int rc = !pszPasswd || !*pszPasswd ? VINF_SUCCESS : VERR_AUTHENTICATION_FAILURE; 309 if (pPwd->pw_passwd && *pPwd->pw_passwd) 310 # endif 311 { 312 # if defined(RT_OS_LINUX) || defined(RT_OS_OS2) 313 struct crypt_data CryptData; 314 RT_ZERO(CryptData); 315 char *pszEncPasswd = crypt_r(pszPasswd, pPwd->pw_passwd, &CryptData); 316 rc = pszEncPasswd && !strcmp(pszEncPasswd, pPwd->pw_passwd) ? VINF_SUCCESS : VERR_AUTHENTICATION_FAILURE; 317 RTMemWipeThoroughly(&CryptData, sizeof(CryptData), 3); 318 # else 319 char *pszEncPasswd = crypt(pszPasswd, ppw->pw_passwd); 320 rc = strcmp(pszEncPasswd, ppw->pw_passwd) == 0 ? VINF_SUCCESS : VERR_AUTHENTICATION_FAILURE; 321 # endif 322 } 323 324 /* 325 * Return GID and UID on success. Always wipe stack buffers. 326 */ 327 if (RT_SUCCESS(rc)) 328 { 329 *pGid = pPwd->pw_gid; 330 *pUid = pPwd->pw_uid; 331 } 332 RTMemWipeThoroughly(szBuf, sizeof(szBuf), 3); 333 # if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) 334 RTMemWipeThoroughly(szBuf2, sizeof(szBuf2), 3); 335 # endif 336 return rc; 329 337 #endif 330 338 }
Note:
See TracChangeset
for help on using the changeset viewer.