static bool smbd_scavenger_running(struct smbd_scavenger_state *state) { if (state->scavenger_id == NULL) { return false; } return serverid_exists(state->scavenger_id); }
/* * In case d->share_modes[i] conflicts with something or otherwise is * being used, we need to make sure the corresponding process still * exists. */ bool share_mode_stale_pid(struct share_mode_data *d, unsigned idx) { struct share_mode_entry *e; if (idx > d->num_share_modes) { DEBUG(1, ("Asking for index %u, only %u around\n", idx, (unsigned)d->num_share_modes)); return false; } e = &d->share_modes[idx]; if (serverid_exists(&e->pid)) { DEBUG(10, ("PID %s (index %u out of %u) still exists\n", procid_str_static(&e->pid), idx, (unsigned)d->num_share_modes)); return false; } DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n", procid_str_static(&e->pid), idx, (unsigned)d->num_share_modes)); e->stale = true; if (d->num_delete_tokens != 0) { uint32_t i, num_stale; /* * We cannot have any delete tokens * if there are no valid share modes. */ num_stale = 0; for (i=0; i<d->num_share_modes; i++) { if (d->share_modes[i].stale) { num_stale += 1; } } if (num_stale == d->num_share_modes) { /* * No non-stale share mode found */ TALLOC_FREE(d->delete_tokens); d->num_delete_tokens = 0; } } d->modified = true; return true; }
bool is_valid_share_mode_entry(const struct share_mode_entry *e) { int num_props = 0; if (e->stale) { return false; } num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0); num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0); if ((num_props > 1) && serverid_exists(&e->pid)) { smb_panic("Invalid share mode entry"); } return (num_props != 0); }
static void smbXsrv_tcon_global_verify_record(struct db_record *db_rec, bool *is_free, bool *was_free, TALLOC_CTX *mem_ctx, struct smbXsrv_tcon_global0 **_g) { TDB_DATA key; TDB_DATA val; DATA_BLOB blob; struct smbXsrv_tcon_globalB global_blob; enum ndr_err_code ndr_err; struct smbXsrv_tcon_global0 *global = NULL; bool exists; TALLOC_CTX *frame = talloc_stackframe(); *is_free = false; if (was_free) { *was_free = false; } if (_g) { *_g = NULL; } key = dbwrap_record_get_key(db_rec); val = dbwrap_record_get_value(db_rec); if (val.dsize == 0) { TALLOC_FREE(frame); *is_free = true; if (was_free) { *was_free = true; } return; } blob = data_blob_const(val.dptr, val.dsize); ndr_err = ndr_pull_struct_blob(&blob, frame, &global_blob, (ndr_pull_flags_fn_t)ndr_pull_smbXsrv_tcon_globalB); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { NTSTATUS status = ndr_map_error2ntstatus(ndr_err); DEBUG(1,("smbXsrv_tcon_global_verify_record: " "key '%s' ndr_pull_struct_blob - %s\n", hex_encode_talloc(frame, key.dptr, key.dsize), nt_errstr(status))); TALLOC_FREE(frame); return; } DEBUG(10,("smbXsrv_tcon_global_verify_record\n")); if (DEBUGLVL(10)) { NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); } if (global_blob.version != SMBXSRV_VERSION_0) { DEBUG(0,("smbXsrv_tcon_global_verify_record: " "key '%s' use unsupported version %u\n", hex_encode_talloc(frame, key.dptr, key.dsize), global_blob.version)); NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); TALLOC_FREE(frame); return; } global = global_blob.info.info0; exists = serverid_exists(&global->server_id); if (!exists) { struct server_id_buf idbuf; DEBUG(2,("smbXsrv_tcon_global_verify_record: " "key '%s' server_id %s does not exist.\n", hex_encode_talloc(frame, key.dptr, key.dsize), server_id_str_buf(global->server_id, &idbuf))); if (DEBUGLVL(2)) { NDR_PRINT_DEBUG(smbXsrv_tcon_globalB, &global_blob); } TALLOC_FREE(frame); dbwrap_record_delete(db_rec); *is_free = true; return; } if (_g) { *_g = talloc_move(mem_ctx, &global); } TALLOC_FREE(frame); }
NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id) { NTSTATUS status = NT_STATUS_OK; TALLOC_CTX *frame = talloc_stackframe(); struct smbXsrv_open_global0 *op = NULL; TDB_DATA val; struct db_record *rec; bool delete_open = false; uint32_t global_id = persistent_id & UINT32_MAX; rec = smbXsrv_open_global_fetch_locked(smbXsrv_open_global_db_ctx, global_id, frame); if (rec == NULL) { status = NT_STATUS_NOT_FOUND; goto done; } val = dbwrap_record_get_value(rec); if (val.dsize == 0) { DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] " "empty record in %s, skipping...\n", global_id, dbwrap_name(smbXsrv_open_global_db_ctx))); goto done; } status = smbXsrv_open_global_parse_record(talloc_tos(), rec, &op); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("smbXsrv_open_cleanup[global: 0x%08x] " "failed to read record: %s\n", global_id, nt_errstr(status))); goto done; } if (server_id_is_disconnected(&op->server_id)) { struct timeval now, disconnect_time; int64_t tdiff; now = timeval_current(); nttime_to_timeval(&disconnect_time, op->disconnect_time); tdiff = usec_time_diff(&now, &disconnect_time); delete_open = (tdiff >= 1000*op->durable_timeout_msec); DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] " "disconnected at [%s] %us ago with " "timeout of %us -%s reached\n", global_id, nt_time_string(frame, op->disconnect_time), (unsigned)(tdiff/1000000), op->durable_timeout_msec / 1000, delete_open ? "" : " not")); } else if (!serverid_exists(&op->server_id)) { struct server_id_buf idbuf; DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] " "server[%s] does not exist\n", global_id, server_id_str_buf(op->server_id, &idbuf))); delete_open = true; } if (!delete_open) { goto done; } status = dbwrap_record_delete(rec); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("smbXsrv_open_cleanup[global: 0x%08x] " "failed to delete record" "from %s: %s\n", global_id, dbwrap_name(smbXsrv_open_global_db_ctx), nt_errstr(status))); goto done; } DEBUG(10, ("smbXsrv_open_cleanup[global: 0x%08x] " "delete record from %s\n", global_id, dbwrap_name(smbXsrv_open_global_db_ctx))); done: talloc_free(frame); return status; }
static int print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname, const char *sname, void *dummy) { static int count; if (do_checks && !is_valid_share_mode_entry(e)) { return 0; } if (count==0) { d_printf("Locked files:\n"); d_printf("Pid Uid DenyMode Access R/W Oplock SharePath Name Time\n"); d_printf("--------------------------------------------------------------------------------------------------\n"); } count++; if (do_checks && !serverid_exists(&e->pid)) { /* the process for this entry does not exist any more */ return 0; } if (Ucrit_checkPid(e->pid)) { struct server_id_buf tmp; d_printf("%-11s ", server_id_str_buf(e->pid, &tmp)); d_printf("%-9u ", (unsigned int)e->uid); switch (map_share_mode_to_deny_mode(e->share_access, e->private_options)) { case DENY_NONE: d_printf("DENY_NONE "); break; case DENY_ALL: d_printf("DENY_ALL "); break; case DENY_DOS: d_printf("DENY_DOS "); break; case DENY_READ: d_printf("DENY_READ "); break; case DENY_WRITE:printf("DENY_WRITE "); break; case DENY_FCB: d_printf("DENY_FCB "); break; default: { d_printf("unknown-please report ! " "e->share_access = 0x%x, " "e->private_options = 0x%x\n", (unsigned int)e->share_access, (unsigned int)e->private_options ); break; } } d_printf("0x%-8x ",(unsigned int)e->access_mask); if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))== (FILE_READ_DATA|FILE_WRITE_DATA)) { d_printf("RDWR "); } else if (e->access_mask & FILE_WRITE_DATA) { d_printf("WRONLY "); } else { d_printf("RDONLY "); } if((e->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) { d_printf("EXCLUSIVE+BATCH "); } else if (e->op_type & EXCLUSIVE_OPLOCK) { d_printf("EXCLUSIVE "); } else if (e->op_type & BATCH_OPLOCK) { d_printf("BATCH "); } else if (e->op_type & LEVEL_II_OPLOCK) { d_printf("LEVEL_II "); } else if (e->op_type == LEASE_OPLOCK) { uint32_t lstate = e->lease->current_state; d_printf("LEASE(%s%s%s)%s%s%s ", (lstate & SMB2_LEASE_READ)?"R":"", (lstate & SMB2_LEASE_WRITE)?"W":"", (lstate & SMB2_LEASE_HANDLE)?"H":"", (lstate & SMB2_LEASE_READ)?"":" ", (lstate & SMB2_LEASE_WRITE)?"":" ", (lstate & SMB2_LEASE_HANDLE)?"":" "); } else { d_printf("NONE "); } d_printf(" %s %s%s %s", sharepath, fname, sname ? sname : "", time_to_asc((time_t)e->time.tv_sec)); } return 0; }