static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *datap, time_t t) { struct change_data *data = (struct change_data *)datap; struct change_data data2; if (t && t < data->last_check_time + lp_change_notify_timeout()) return False; if (!change_to_user(conn,vuid)) return True; if (!set_current_service(conn,True)) { change_to_root_user(); return True; } if (!notify_hash(conn, path, flags, &data2, data) || data2.modify_time != data->modify_time || data2.status_time != data->status_time || data2.total_time != data->total_time || data2.num_entries != data->num_entries || data2.mode_sum != data->mode_sum || memcmp(data2.name_hash, data->name_hash, sizeof(data2.name_hash))) { change_to_root_user(); return True; } if (t) data->last_check_time = t; change_to_root_user(); return False; }
void conn_close_all(void) { connection_struct *conn, *next; for (conn=Connections;conn;conn=next) { next=conn->next; set_current_service(conn, 0, True); close_cnum(conn, conn->vuid); } }
bool reload_services(struct smbd_server_connection *sconn, bool (*snumused) (struct smbd_server_connection *, int), bool test) { struct smbXsrv_connection *xconn = NULL; bool ret; if (sconn != NULL) { xconn = sconn->conn; } if (lp_loaded()) { char *fname = lp_next_configfile(talloc_tos()); if (file_exist(fname) && !strcsequal(fname, get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; } TALLOC_FREE(fname); } reopen_logs(); if (test && !lp_file_list_changed()) return(True); lp_killunused(sconn, snumused); ret = lp_load(get_dyn_CONFIGFILE(), false, /* global only */ false, /* save defaults */ true, /* add_ipc */ true); /* initialize globals */ /* perhaps the config filename is now set */ if (!test) { reload_services(sconn, snumused, true); } reopen_logs(); load_interfaces(); if (xconn != NULL) { set_socket_options(xconn->transport.sock, "SO_KEEPALIVE"); set_socket_options(xconn->transport.sock, lp_socket_options()); } mangle_reset_cache(); reset_stat_cache(); /* this forces service parameters to be flushed */ set_current_service(NULL,0,True); return(ret); }
BOOL reload_services(BOOL test) { BOOL ret; if (lp_loaded()) { pstring fname; pstrcpy(fname,lp_configfile()); if (file_exist(fname, NULL) && !strcsequal(fname, dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE, fname); test = False; } } reopen_logs(); if (test && !lp_file_list_changed()) return(True); lp_killunused(conn_snum_used); ret = lp_load(dyn_CONFIGFILE, False, False, True); load_printers(); /* perhaps the config filename is now set */ if (!test) reload_services(True); reopen_logs(); load_interfaces(); { if (smbd_server_fd() != -1) { set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); set_socket_options(smbd_server_fd(), user_socket_options); } } mangle_reset_cache(); reset_stat_cache(); /* this forces service parameters to be flushed */ set_current_service(NULL,True); return (ret); }
bool reload_services(struct messaging_context *msg_ctx, int smb_sock, bool test) { bool ret; if (lp_loaded()) { char *fname = lp_configfile(); if (file_exist(fname) && !strcsequal(fname, get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; } TALLOC_FREE(fname); } reopen_logs(); if (test && !lp_file_list_changed()) return(True); lp_killunused(conn_snum_used); ret = lp_load(get_dyn_CONFIGFILE(), False, False, True, True); /* perhaps the config filename is now set */ if (!test) reload_services(msg_ctx, smb_sock, True); reopen_logs(); load_interfaces(); if (smb_sock != -1) { set_socket_options(smb_sock,"SO_KEEPALIVE"); set_socket_options(smb_sock, lp_socket_options()); } mangle_reset_cache(); reset_stat_cache(); /* this forces service parameters to be flushed */ set_current_service(NULL,0,True); return(ret); }
NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req) { const uint8_t *inhdr; int i = req->current_idx; uint32_t in_flags; uint32_t in_tid; void *p; struct smbd_smb2_tcon *tcon; req->tcon = NULL; inhdr = (const uint8_t *)req->in.vector[i+0].iov_base; in_flags = IVAL(inhdr, SMB2_HDR_FLAGS); in_tid = IVAL(inhdr, SMB2_HDR_TID); if (in_flags & SMB2_HDR_FLAG_CHAINED) { in_tid = req->last_tid; } req->last_tid = UINT32_MAX; /* lookup an existing session */ p = idr_find(req->session->tcons.idtree, in_tid); if (p == NULL) { return NT_STATUS_NETWORK_NAME_DELETED; } tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon); if (!change_to_user(tcon->compat_conn,req->session->vuid)) { return NT_STATUS_ACCESS_DENIED; } /* should we pass FLAG_CASELESS_PATHNAMES here? */ if (!set_current_service(tcon->compat_conn, 0, true)) { return NT_STATUS_ACCESS_DENIED; } req->tcon = tcon; req->last_tid = in_tid; return NT_STATUS_OK; }
static int smbd_smb2_tcon_destructor(struct smbd_smb2_tcon *tcon) { if (tcon->session == NULL) { return 0; } idr_remove(tcon->session->tcons.idtree, tcon->tid); DLIST_REMOVE(tcon->session->tcons.list, tcon); SMB_ASSERT(tcon->session->sconn->num_tcons_open > 0); tcon->session->sconn->num_tcons_open--; if (tcon->compat_conn) { set_current_service(tcon->compat_conn, 0, true); close_cnum(tcon->compat_conn, tcon->session->vuid); } tcon->compat_conn = NULL; tcon->tid = 0; tcon->session = NULL; return 0; }
NTSTATUS smbXsrv_tcon_disconnect(struct smbXsrv_tcon *tcon, uint64_t vuid) { struct smbXsrv_tcon_table *table; struct db_record *local_rec = NULL; struct db_record *global_rec = NULL; NTSTATUS status; NTSTATUS error = NT_STATUS_OK; if (tcon->table == NULL) { return NT_STATUS_OK; } table = tcon->table; tcon->table = NULL; tcon->status = NT_STATUS_NETWORK_NAME_DELETED; global_rec = tcon->global->db_rec; tcon->global->db_rec = NULL; if (global_rec == NULL) { uint8_t key_buf[SMBXSRV_TCON_GLOBAL_TDB_KEY_SIZE]; TDB_DATA key; key = smbXsrv_tcon_global_id_to_key( tcon->global->tcon_global_id, key_buf); global_rec = dbwrap_fetch_locked(table->global.db_ctx, tcon->global, key); if (global_rec == NULL) { DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "Failed to lock global key '%s'\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(global_rec, key.dptr, key.dsize))); error = NT_STATUS_INTERNAL_ERROR; } } if (global_rec != NULL) { status = dbwrap_record_delete(global_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(global_rec); DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "failed to delete global key '%s': %s\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(global_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } } TALLOC_FREE(global_rec); local_rec = tcon->db_rec; if (local_rec == NULL) { uint8_t key_buf[SMBXSRV_TCON_LOCAL_TDB_KEY_SIZE]; TDB_DATA key; key = smbXsrv_tcon_local_id_to_key(tcon->local_id, key_buf); local_rec = dbwrap_fetch_locked(table->local.db_ctx, tcon, key); if (local_rec == NULL) { DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "Failed to lock local key '%s'\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(local_rec, key.dptr, key.dsize))); error = NT_STATUS_INTERNAL_ERROR; } } if (local_rec != NULL) { status = dbwrap_record_delete(local_rec); if (!NT_STATUS_IS_OK(status)) { TDB_DATA key = dbwrap_record_get_key(local_rec); DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "failed to delete local key '%s': %s\n", tcon->global->tcon_global_id, tcon->global->share_name, hex_encode_talloc(local_rec, key.dptr, key.dsize), nt_errstr(status))); error = status; } table->local.num_tcons -= 1; } if (tcon->db_rec == NULL) { TALLOC_FREE(local_rec); } tcon->db_rec = NULL; if (tcon->compat) { bool ok; ok = set_current_service(tcon->compat, 0, true); if (!ok) { status = NT_STATUS_INTERNAL_ERROR; DEBUG(0, ("smbXsrv_tcon_disconnect(0x%08x, '%s'): " "set_current_service() failed: %s\n", tcon->global->tcon_global_id, tcon->global->share_name, nt_errstr(status))); tcon->compat = NULL; return status; } close_cnum(tcon->compat, vuid); tcon->compat = NULL; } return error; }
void process_blocking_lock_queue(struct smbd_server_connection *sconn) { struct timeval tv_curr = timeval_current(); struct blocking_lock_record *blr, *next = NULL; if (sconn->using_smb2) { process_blocking_lock_queue_smb2(sconn, tv_curr); return; } /* * Go through the queue and see if we can get any of the locks. */ for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) { next = blr->next; /* * Go through the remaining locks and try and obtain them. * The call returns True if all locks were obtained successfully * and False if we still need to wait. */ DEBUG(10, ("Processing BLR = %p\n", blr)); /* We use set_current_service so connections with * pending locks are not marked as idle. */ set_current_service(blr->fsp->conn, SVAL(blr->req->inbuf,smb_flg), false); if(blocking_lock_record_process(blr)) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("BLR_process returned true: cancelling and " "removing lock. BLR = %p\n", blr)); if (br_lck) { brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); TALLOC_FREE(blr); continue; } /* * We couldn't get the locks for this record on the list. * If the time has expired, return a lock error. */ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { struct byte_range_lock *br_lck = brl_get_locks( talloc_tos(), blr->fsp); DEBUG(10, ("Lock timed out! BLR = %p\n", blr)); /* * Lock expired - throw away all previously * obtained locks and return lock error. */ if (br_lck) { DEBUG(5,("process_blocking_lock_queue: " "pending lock for %s, file %s " "timed out.\n", fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp))); brl_lock_cancel(br_lck, blr->smblctx, messaging_server_id(sconn->msg_ctx), blr->offset, blr->count, blr->lock_flav, blr); TALLOC_FREE(br_lck); } blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr); TALLOC_FREE(blr); } } recalc_brl_timeout(sconn); }