From: Ralph Boehme Date: Sat, 26 Jul 2025 16:12:03 +0000 (+0200) Subject: smbstatus: print persistent handles X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=452fcef325f34e072637e810cb5c892600be25c4;p=thirdparty%2Fsamba.git smbstatus: print persistent handles While at it, add all other share_mode_entry flags to the json output. Signed-off-by: Ralph Boehme Reviewed-by: Anoop C S --- diff --git a/source3/utils/status.c b/source3/utils/status.c index a9df2855768..7d2b8434411 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -133,7 +133,7 @@ static int print_share_mode_stdout(struct traverse_state *state, const char *pid, const char *user_name, const char *denymode, - int access_mask, + const struct share_mode_entry *e, const char *rw, const char *oplock, const char *servicepath, @@ -142,14 +142,16 @@ static int print_share_mode_stdout(struct traverse_state *state, { if (state->first) { d_printf("\nLocked files:\n"); - d_printf("Pid User(ID) DenyMode Access R/W Oplock SharePath Name Time\n"); - d_printf("--------------------------------------------------------------------------------------------------\n"); + d_printf("Pid User(ID) DenyMode Access R/W Oplock Persistent SharePath Name Time\n"); + d_printf("------------------------------------------------------------------------------------------------------\n"); state->first = false; } - d_printf("%-11s %-9s %-10s 0x%-8x %-10s %-14s %s %s %s", - pid, user_name, denymode, access_mask, rw, oplock, + d_printf("%-11s %-9s %-10s 0x%-8x %-10s %-16s %-10s %s %s %s", + pid, user_name, denymode, e->access_mask, + rw, oplock, + e->flags & SHARE_ENTRY_FLAG_PERSISTENT_OPEN ? "yes" : "no", servicepath, filename, timestr); return 0; } @@ -213,7 +215,10 @@ static int print_share_mode(struct file_id fid, return 0; } - if (do_checks && !serverid_exists(&e->pid)) { + if (do_checks && + !(e->flags & SHARE_ENTRY_FLAG_PERSISTENT_OPEN) && + !serverid_exists(&e->pid)) + { /* the process for this entry does not exist any more */ TALLOC_FREE(tmp_ctx); return 0; @@ -329,7 +334,7 @@ static int print_share_mode(struct file_id fid, pid, user_str, denymode, - (unsigned int)e->access_mask, + e, rw, oplock, d->servicepath, diff --git a/source3/utils/status_json.c b/source3/utils/status_json.c index 169cea69960..04508c16ec2 100644 --- a/source3/utils/status_json.c +++ b/source3/utils/status_json.c @@ -185,6 +185,15 @@ static const struct mask2txt lease_mask[] = { {0, NULL} }; +static const struct mask2txt flags_mask[] = { + {SHARE_ENTRY_FLAG_POSIX_OPEN, "posix"}, + {SHARE_ENTRY_FLAG_STREAM_BASEOPEN, "baseopen"}, + {SHARE_ENTRY_FLAG_DENY_DOS, "deny-dos"}, + {SHARE_ENTRY_FLAG_DENY_FCB, "deny-fcb"}, + {SHARE_ENTRY_FLAG_PERSISTENT_OPEN, "persistent"}, + {0, NULL} +}; + /* Add nested json key:value entry, up to 4 levels deep */ static int add_nested_item_to_json(struct json_object *root_json, const char **subs, @@ -721,6 +730,49 @@ failure: return -1; } +static int add_flags_to_json(struct json_object *parent_json, + uint16_t flags) +{ + struct json_object flags_json; + char *flags_hex = NULL; + int result; + + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return -1; + } + + flags_json = json_new_object(); + if (json_is_invalid(&flags_json)) { + goto failure; + } + + flags_hex = talloc_asprintf(tmp_ctx, "0x%08x", flags); + if (flags_hex == NULL) { + goto failure; + } + result = json_add_string(&flags_json, "hex", flags_hex); + if (result < 0) { + goto failure; + } + result = map_mask_to_json(&flags_json, flags, flags_mask); + if (result < 0) { + goto failure; + } + + result = json_add_object(parent_json, "flags_mask", &flags_json); + if (result < 0) { + goto failure; + } + + TALLOC_FREE(tmp_ctx); + return 0; +failure: + json_free(&flags_json); + TALLOC_FREE(tmp_ctx); + return -1; +} + static int add_caching_to_json(struct json_object *parent_json, int op_type, int lease_type) @@ -1064,6 +1116,10 @@ static int add_open_to_json(struct json_object *parent_json, if (result < 0) { goto failure; } + result = add_flags_to_json(&sub_json, e->flags); + if (result < 0) { + goto failure; + } timestr = timeval_str_buf(&e->time, true, true, &tv_buf); if (timestr == NULL) {