summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2012-02-29 12:15:12 -0800
committerJeremy Allison <jra@samba.org>2012-02-29 17:04:46 -0800
commitbca3fb3eccef620a47e5088cbd79dfa3ea79e814 (patch)
treef4cff2ac4ac2fc704ff0c2e10aa898afbf3f003e /source3/smbd
parent3ddd9916f51f7b64527e9c33a7c3a4849c6f3017 (diff)
downloadsamba-bca3fb3eccef620a47e5088cbd79dfa3ea79e814.tar.gz
samba-bca3fb3eccef620a47e5088cbd79dfa3ea79e814.tar.bz2
samba-bca3fb3eccef620a47e5088cbd79dfa3ea79e814.zip
Implement FLAG_TRANS2_FIND_BACKUP_INTENT for trans2 with privileges.
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/trans2.c50
1 files changed, 46 insertions, 4 deletions
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);