MCPcopy Create free account
hub / github.com/apache/httpd / resolve_symlink

Function resolve_symlink

server/request.c:533–591  ·  view source on GitHub ↗

* resolve_symlink must _always_ be called on an APR_LNK file type! * It will resolve the actual target file type, modification date, etc, * and provide any processing required for symlink evaluation. * Path must already be cleaned, no trailing slash, no multi-slashes, * and don't call this on the root! * * Simply, the number of times we deref a symlink are minimal compared * to the number o

Source from the content-addressed store, hash-verified

531 * it points at a 'nasty' - we must always rerun check_safe_file (or similar.)
532 */
533static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p)
534{
535 apr_finfo_t fi;
536 const char *savename;
537
538 if (!(opts & (OPT_SYM_OWNER | OPT_SYM_LINKS))) {
539 return HTTP_FORBIDDEN;
540 }
541
542 /* Save the name from the valid bits. */
543 savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL;
544
545 /* if OPT_SYM_OWNER is unset, we only need to check target accessible */
546 if (!(opts & OPT_SYM_OWNER)) {
547 if (apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME | APR_FINFO_LINK), p)
548 != APR_SUCCESS)
549 {
550 return HTTP_FORBIDDEN;
551 }
552
553 /* Give back the target */
554 memcpy(lfi, &fi, sizeof(fi));
555 if (savename) {
556 lfi->name = savename;
557 lfi->valid |= APR_FINFO_NAME;
558 }
559
560 return OK;
561 }
562
563 /* OPT_SYM_OWNER only works if we can get the owner of
564 * both the file and symlink. First fill in a missing
565 * owner of the symlink, then get the info of the target.
566 */
567 if (!(lfi->valid & APR_FINFO_OWNER)) {
568 if (apr_stat(lfi, d, lfi->valid | APR_FINFO_LINK | APR_FINFO_OWNER, p)
569 != APR_SUCCESS)
570 {
571 return HTTP_FORBIDDEN;
572 }
573 }
574
575 if (apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME), p) != APR_SUCCESS) {
576 return HTTP_FORBIDDEN;
577 }
578
579 if (apr_uid_compare(fi.user, lfi->user) != APR_SUCCESS) {
580 return HTTP_FORBIDDEN;
581 }
582
583 /* Give back the target */
584 memcpy(lfi, &fi, sizeof(fi));
585 if (savename) {
586 lfi->name = savename;
587 lfi->valid |= APR_FINFO_NAME;
588 }
589
590 return OK;

Callers 2

ap_directory_walkFunction · 0.85
ap_sub_req_lookup_direntFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected