From bca3fb3eccef620a47e5088cbd79dfa3ea79e814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Feb 2012 12:15:12 -0800 Subject: Implement FLAG_TRANS2_FIND_BACKUP_INTENT for trans2 with privileges. --- source3/smbd/trans2.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'source3/smbd/trans2.c') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5ee02c4278..21f31f17b3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2296,6 +2296,7 @@ static void call_trans2findfirst(connection_struct *conn, struct dptr_struct *dirptr = NULL; struct smbd_server_connection *sconn = req->sconn; uint32_t ucf_flags = (UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP); + bool backup_priv = false; if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -2308,11 +2309,16 @@ static void call_trans2findfirst(connection_struct *conn, close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE); close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END); requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME); + backup_priv = ((findfirst_flags & FLAG_TRANS2_FIND_BACKUP_INTENT) && + security_token_has_privilege(get_current_nttok(conn), + SEC_PRIV_BACKUP)); + info_level = SVAL(params,6); DEBUG(3,("call_trans2findfirst: dirtype = %x, maxentries = %d, close_after_first=%d, \ -close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", +close_if_end = %d requires_resume_key = %d backup_priv = %d level = 0x%x, max_data_bytes = %d\n", (unsigned int)dirtype, maxentries, close_after_first, close_if_end, requires_resume_key, + (int)backup_priv, info_level, max_data_bytes)); if (!maxentries) { @@ -2354,12 +2360,24 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", goto out; } - ntstatus = filename_convert(ctx, conn, + if (backup_priv) { + become_root(); + ntstatus = filename_convert_with_privilege(ctx, + conn, + req, + directory, + ucf_flags, + &mask_contains_wcard, + &smb_dname); + } else { + ntstatus = filename_convert(ctx, conn, req->flags2 & FLAGS2_DFS_PATHNAMES, directory, ucf_flags, &mask_contains_wcard, &smb_dname); + } + if (!NT_STATUS_IS_OK(ntstatus)) { if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) { reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, @@ -2465,6 +2483,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd goto out; } + if (backup_priv) { + /* Remember this in case we have + to do a findnext. */ + dptr_set_priv(dirptr); + } + dptr_num = dptr_dnum(dirptr); DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype)); @@ -2591,6 +2615,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd name_to_8_3(mask, mangled_name, True, conn->params); } out: + + if (backup_priv) { + unbecome_root(); + } + TALLOC_FREE(smb_dname); return; } @@ -2640,6 +2669,7 @@ static void call_trans2findnext(connection_struct *conn, TALLOC_CTX *ctx = talloc_tos(); struct dptr_struct *dirptr; struct smbd_server_connection *sconn = req->sconn; + bool backup_priv = false; if (total_params < 13) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -2782,10 +2812,14 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd /* Get the attr mask from the dptr */ dirtype = dptr_attr(sconn, dptr_num); - DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld)\n", + backup_priv = dptr_get_priv(dirptr); + + DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%ld) " + "backup_priv = %d\n", dptr_num, mask, dirtype, (long)dirptr, - dptr_TellDir(dirptr))); + dptr_TellDir(dirptr), + (int)backup_priv)); /* Initialize per TRANS2_FIND_NEXT operation data */ dptr_init_search_op(dirptr); @@ -2802,6 +2836,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd space_remaining = max_data_bytes; out_of_space = False; + if (backup_priv) { + become_root(); + } + /* * Seek to the correct position. We no longer use the resume key but * depend on the last file name instead. @@ -2891,6 +2929,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dptr_close(sconn, &dptr_num); /* This frees up the saved mask */ } + if (backup_priv) { + unbecome_root(); + } + /* Set up the return parameter block */ SSVAL(params,0,numentries); SSVAL(params,2,finished); -- cgit