Esempio n. 1
0
NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
				struct auth_session_info **session_info)
{
	if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
	*session_info = copy_session_info(mem_ctx, system_info);
	return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
Esempio n. 2
0
struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
					      const struct ndr_syntax_id *syntax,
					      const struct tsocket_address *remote_address,
					      const struct auth_session_info *session_info,
					      struct messaging_context *msg_ctx)
{
	struct pipes_struct *p;
	struct pipe_rpc_fns *context_fns;
	const char *pipe_name;
	int ret;

	pipe_name = get_pipe_name_from_syntax(talloc_tos(), syntax);

	DEBUG(4,("Create pipe requested %s\n", pipe_name));

	ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
				     NCALRPC, RPC_LITTLE_ENDIAN, false,
				     remote_address, NULL, &p);
	if (ret) {
		DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
		return NULL;
	}

	if (!init_pipe_handles(p, syntax)) {
		DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	p->session_info = copy_session_info(p, session_info);
	if (p->session_info == NULL) {
		DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
		close_policy_by_pipe(p);
		TALLOC_FREE(p);
		return NULL;
	}

	context_fns = talloc(p, struct pipe_rpc_fns);
	if (context_fns == NULL) {
		DEBUG(0,("talloc() failed!\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	context_fns->next = context_fns->prev = NULL;
	context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(syntax);
	context_fns->cmds = rpc_srv_get_pipe_cmds(syntax);
	context_fns->context_id = 0;
	context_fns->syntax = *syntax;

	/* add to the list of open contexts */
	DLIST_ADD(p->contexts, context_fns);

	DEBUG(4,("Created internal pipe %s\n", pipe_name));

	return p;
}
Esempio n. 3
0
static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn,
					      TALLOC_CTX *mem_ctx, int snum,
                                              struct auth_session_info *session_info,
                                              struct auth_session_info **presult)
{
	struct auth_session_info *result;

        if (lp_guest_only(snum)) {
                return make_session_info_guest(mem_ctx, presult);
        }

	/*
	 * This is the normal security != share case where we have a
	 * valid vuid from the session setup.                 */

	if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
		if (!lp_guest_ok(snum)) {
			DEBUG(2, ("guest user (from session setup) "
				  "not permitted to access this share "
				  "(%s)\n", lp_servicename(talloc_tos(), snum)));
			return NT_STATUS_ACCESS_DENIED;
		}
	} else {
		if (!user_ok_token(session_info->unix_info->unix_name,
				   session_info->info->domain_name,
				   session_info->security_token, snum)) {
			DEBUG(2, ("user '%s' (from session setup) not "
				  "permitted to access this share "
				  "(%s)\n",
				  session_info->unix_info->unix_name,
				  lp_servicename(talloc_tos(), snum)));
			return NT_STATUS_ACCESS_DENIED;
		}
	}

	result = copy_session_info(mem_ctx, session_info);
	if (result == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	*presult = result;
	return NT_STATUS_OK;
}
Esempio n. 4
0
NTSTATUS make_internal_rpc_pipe_socketpair(
	TALLOC_CTX *mem_ctx,
	struct tevent_context *ev_ctx,
	struct messaging_context *msg_ctx,
	const char *pipe_name,
	const struct ndr_syntax_id *syntax,
	const struct tsocket_address *remote_address,
	const struct tsocket_address *local_address,
	const struct auth_session_info *session_info,
	struct npa_state **pnpa)
{
	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	struct named_pipe_client *npc;
	struct tevent_req *subreq;
	struct npa_state *npa;
	NTSTATUS status;
	int error;
	int rc;

	DEBUG(4, ("Create of internal pipe %s requested\n", pipe_name));

	npa = npa_state_init(tmp_ctx);
	if (npa == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	npa->file_type = FILE_TYPE_MESSAGE_MODE_PIPE;
	npa->device_state = 0xff | 0x0400 | 0x0100;
	npa->allocation_size = 4096;

	npc = named_pipe_client_init(npa,
				     ev_ctx,
				     msg_ctx,
				     pipe_name,
				     NULL, /* term_fn */
				     npa->file_type,
				     npa->device_state,
				     npa->allocation_size,
				     NULL); /* private_data */
	if (npc == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}
	npa->private_data = (void*) npc;

	rc = tstream_npa_socketpair(npa->file_type,
				    npa,
				    &npa->stream,
				    npc,
				    &npc->tstream);
	if (rc == -1) {
		status = map_nt_error_from_unix(errno);
		goto out;
	}

	npc->remote_client_addr = tsocket_address_copy(remote_address, npc);
	if (npc->remote_client_addr == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	npc->remote_client_name = tsocket_address_inet_addr_string(npc->remote_client_addr,
								   npc);
	if (npc->remote_client_name == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	npc->local_server_addr = tsocket_address_copy(local_address, npc);
	if (npc->local_server_addr == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	npc->local_server_name = tsocket_address_inet_addr_string(
		npc->local_server_addr, npc);
	if (npc->local_server_name == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	npc->session_info = copy_session_info(npc, session_info);
	if (npc->session_info == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	rc = make_server_pipes_struct(npc,
				      npc->msg_ctx,
				      npc->pipe_name,
				      NCACN_NP,
				      npc->remote_client_addr,
				      npc->local_server_addr,
				      npc->session_info,
				      &npc->p,
				      &error);
	if (rc == -1) {
		status = map_nt_error_from_unix(error);
		goto out;
	}

	npc->write_queue = tevent_queue_create(npc, "npa_server_write_queue");
	if (npc->write_queue == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto out;
	}

	subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream);
	if (subreq == NULL) {
		DEBUG(2, ("Failed to start receiving packets\n"));
		status = NT_STATUS_PIPE_BROKEN;
		goto out;
	}
	tevent_req_set_callback(subreq, named_pipe_packet_process, npc);

	*pnpa = talloc_steal(mem_ctx, npa);
	status = NT_STATUS_OK;
out:
	talloc_free(tmp_ctx);
	return status;
}
Esempio n. 5
0
struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
					      const struct ndr_syntax_id *syntax,
					      const struct tsocket_address *remote_address,
					      const struct tsocket_address *local_address,
					      const struct auth_session_info *session_info,
					      struct messaging_context *msg_ctx)
{
	struct pipes_struct *p;
	struct pipe_rpc_fns *context_fns;
	const char *pipe_name;
	int ret;
	const struct ndr_interface_table *table;

	table = ndr_table_by_uuid(&syntax->uuid);
	if (table == NULL) {
		DEBUG(0,("unknown interface\n"));
		return NULL;
	}

	pipe_name = dcerpc_default_transport_endpoint(mem_ctx, NCACN_NP, table);

	DEBUG(4,("Create pipe requested %s\n", pipe_name));

	ret = make_base_pipes_struct(mem_ctx, msg_ctx, pipe_name,
				     NCALRPC, RPC_LITTLE_ENDIAN,
				     remote_address, local_address, &p);
	if (ret) {
		DEBUG(0,("ERROR! no memory for pipes_struct!\n"));
		return NULL;
	}

	if (!init_pipe_handles(p, syntax)) {
		DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	p->session_info = copy_session_info(p, session_info);
	if (p->session_info == NULL) {
		DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n"));
		close_policy_by_pipe(p);
		TALLOC_FREE(p);
		return NULL;
	}

	context_fns = talloc_zero(p, struct pipe_rpc_fns);
	if (context_fns == NULL) {
		DEBUG(0,("talloc() failed!\n"));
		TALLOC_FREE(p);
		return NULL;
	}

	context_fns->next = context_fns->prev = NULL;
	context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(syntax);
	context_fns->cmds = rpc_srv_get_pipe_cmds(syntax);
	context_fns->context_id = 0;
	context_fns->syntax = *syntax;

	/* add to the list of open contexts */
	DLIST_ADD(p->contexts, context_fns);

	DEBUG(4,("Created internal pipe %s\n", pipe_name));

	return p;
}
Esempio n. 6
0
static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
			    struct tevent_context *ev,
			    struct messaging_context *msg,
			    connection_struct **pconn,
			    int snum,
			    const char *path,
			    const struct auth_session_info *session_info)
{
	connection_struct *conn;
	char *connpath;
	const char *vfs_user;
	struct smbd_server_connection *sconn;
	const char *servicename = lp_const_servicename(snum);

	sconn = talloc_zero(ctx, struct smbd_server_connection);
	if (sconn == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	sconn->ev_ctx = ev;
	sconn->msg_ctx = msg;
	sconn->sock = -1;
	sconn->smb1.echo_handler.trusted_fd = -1;
	sconn->smb1.echo_handler.socket_lock_fd = -1;

	conn = conn_new(sconn);
	if (conn == NULL) {
		TALLOC_FREE(sconn);
		return NT_STATUS_NO_MEMORY;
	}

	/* Now we have conn, we need to make sconn a child of conn,
	 * for a proper talloc tree */
	talloc_steal(conn, sconn);

	if (snum == -1 && servicename == NULL) {
		servicename = "Unknown Service (snum == -1)";
	}

	connpath = talloc_strdup(conn, path);
	if (!connpath) {
		TALLOC_FREE(conn);
		return NT_STATUS_NO_MEMORY;
	}
	connpath = talloc_string_sub(conn,
				     connpath,
				     "%S",
				     servicename);
	if (!connpath) {
		TALLOC_FREE(conn);
		return NT_STATUS_NO_MEMORY;
	}

	/* needed for smbd_vfs_init() */

	conn->params->service = snum;
	conn->cnum = TID_FIELD_INVALID;

	if (session_info != NULL) {
		conn->session_info = copy_session_info(conn, session_info);
		if (conn->session_info == NULL) {
			DEBUG(0, ("copy_serverinfo failed\n"));
			TALLOC_FREE(conn);
			return NT_STATUS_NO_MEMORY;
		}
		vfs_user = conn->session_info->unix_info->unix_name;
	} else {
		/* use current authenticated user in absence of session_info */
		vfs_user = get_current_username();
	}

	set_conn_connectpath(conn, connpath);

	/*
	 * New code to check if there's a share security descripter
	 * added from NT server manager. This is done after the
	 * smb.conf checks are done as we need a uid and token. JRA.
	 *
	 */
	if (conn->session_info) {
		share_access_check(conn->session_info->security_token,
				   servicename,
				   MAXIMUM_ALLOWED_ACCESS,
				   &conn->share_access);

		if ((conn->share_access & FILE_WRITE_DATA) == 0) {
			if ((conn->share_access & FILE_READ_DATA) == 0) {
				/* No access, read or write. */
				DEBUG(0,("create_conn_struct: connection to %s "
					 "denied due to security "
					 "descriptor.\n",
					 servicename));
				conn_free(conn);
				return NT_STATUS_ACCESS_DENIED;
			} else {
				conn->read_only = true;
			}
		}
	} else {
		conn->share_access = 0;
		conn->read_only = true;
	}

	if (!smbd_vfs_init(conn)) {
		NTSTATUS status = map_nt_error_from_unix(errno);
		DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
		conn_free(conn);
		return status;
	}

	/* this must be the first filesystem operation that we do */
	if (SMB_VFS_CONNECT(conn, servicename, vfs_user) < 0) {
		DEBUG(0,("VFS connect failed!\n"));
		conn_free(conn);
		return NT_STATUS_UNSUCCESSFUL;
	}

	conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
	*pconn = conn;

	return NT_STATUS_OK;
}
Esempio n. 7
0
static NTSTATUS create_connection_session_info(struct smbd_server_connection *sconn,
					      TALLOC_CTX *mem_ctx, int snum,
                                              struct auth_session_info *vuid_serverinfo,
					      DATA_BLOB password,
                                              struct auth_session_info **presult)
{
        if (lp_guest_only(snum)) {
                return make_session_info_guest(mem_ctx, presult);
        }

        if (vuid_serverinfo != NULL) {

		struct auth_session_info *result;

                /*
                 * This is the normal security != share case where we have a
                 * valid vuid from the session setup.                 */

		if (security_session_user_level(vuid_serverinfo, NULL) < SECURITY_USER) {
                      if (!lp_guest_ok(snum)) {
                                DEBUG(2, ("guest user (from session setup) "
                                          "not permitted to access this share "
                                          "(%s)\n", lp_servicename(snum)));
                                return NT_STATUS_ACCESS_DENIED;
                        }
                } else {
                        if (!user_ok_token(vuid_serverinfo->unix_info->unix_name,
					   vuid_serverinfo->info->domain_name,
                                           vuid_serverinfo->security_token, snum)) {
                                DEBUG(2, ("user '%s' (from session setup) not "
                                          "permitted to access this share "
                                          "(%s)\n",
                                          vuid_serverinfo->unix_info->unix_name,
                                          lp_servicename(snum)));
                                return NT_STATUS_ACCESS_DENIED;
                        }
                }

                result = copy_session_info(mem_ctx, vuid_serverinfo);
		if (result == NULL) {
			return NT_STATUS_NO_MEMORY;
		}

		*presult = result;
		return NT_STATUS_OK;
        }

        if (lp_security() == SEC_SHARE) {

                fstring user;
		bool guest;

                /* add the sharename as a possible user name if we
                   are in share mode security */

                add_session_user(sconn, lp_servicename(snum));

                /* shall we let them in? */

                if (!authorise_login(sconn, snum,user,password,&guest)) {
                        DEBUG( 2, ( "Invalid username/password for [%s]\n",
                                    lp_servicename(snum)) );
			return NT_STATUS_WRONG_PASSWORD;
                }

		return make_session_info_from_username(mem_ctx, user, guest,
						       presult);
        }

	DEBUG(0, ("invalid VUID (vuser) but not in security=share\n"));
	return NT_STATUS_ACCESS_DENIED;
}
Esempio n. 8
0
NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
				struct auth_session_info **session_info)
{
	*session_info = copy_session_info(mem_ctx, guest_info);
	return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
Esempio n. 9
0
static bool check_user_ok(connection_struct *conn,
			uint64_t vuid,
			const struct auth_session_info *session_info,
			int snum)
{
	unsigned int i;
	bool readonly_share = false;
	bool admin_user = false;
	struct vuid_cache_entry *ent = NULL;
	uint32_t share_access = 0;
	NTSTATUS status;

	for (i=0; i<VUID_CACHE_SIZE; i++) {
		ent = &conn->vuid_cache->array[i];
		if (ent->vuid == vuid) {
			if (vuid == UID_FIELD_INVALID) {
				/*
				 * Slow path, we don't care
				 * about the array traversal.
				*/
				continue;
			}
			free_conn_session_info_if_unused(conn);
			conn->session_info = ent->session_info;
			conn->read_only = ent->read_only;
			conn->share_access = ent->share_access;
			return(True);
		}
	}

	status = check_user_share_access(conn,
					session_info,
					&share_access,
					&readonly_share);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	admin_user = token_contains_name_in_list(
		session_info->unix_info->unix_name,
		session_info->info->domain_name,
		NULL, session_info->security_token, lp_admin_users(snum));

	ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];

	conn->vuid_cache->next_entry =
		(conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;

	TALLOC_FREE(ent->session_info);

	/*
	 * If force_user was set, all session_info's are based on the same
	 * username-based faked one.
	 */

	ent->session_info = copy_session_info(
		conn, conn->force_user ? conn->session_info : session_info);

	if (ent->session_info == NULL) {
		ent->vuid = UID_FIELD_INVALID;
		return false;
	}

	/*
	 * It's actually OK to call check_user_ok() with
	 * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
	 * All this will do is throw away one entry in the cache.
	 */

	ent->vuid = vuid;
	ent->read_only = readonly_share;
	ent->share_access = share_access;
	free_conn_session_info_if_unused(conn);
	conn->session_info = ent->session_info;
	if (vuid == UID_FIELD_INVALID) {
		/*
		 * Not strictly needed, just make it really
		 * clear this entry is actually an unused one.
		 */
		ent->read_only = false;
		ent->share_access = 0;
		ent->session_info = NULL;
	}

	conn->read_only = readonly_share;
	conn->share_access = share_access;

	if (admin_user) {
		DEBUG(2,("check_user_ok: user %s is an admin user. "
			"Setting uid as %d\n",
			conn->session_info->unix_info->unix_name,
			sec_initial_uid() ));
		conn->session_info->unix_token->uid = sec_initial_uid();
	}

	return(True);
}