Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
	}
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
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);
}