+static void smbsrv_sesssetup_backend_send(struct smbsrv_request *req,
+ union smb_sesssetup *sess,
+ NTSTATUS status)
+{
+ if (NT_STATUS_IS_OK(status)) {
+ req->smb_conn->negotiate.done_sesssetup = True;
+ /* we need to keep the session long term */
+ req->session = talloc_steal(req->smb_conn, req->session);
+ }
+ smbsrv_reply_sesssetup_send(req, sess, status);
+}
+
+static void sesssetup_old_send(struct auth_check_password_request *areq,
+ void *private_data)
+{
+ struct smbsrv_request *req = talloc_get_type(private_data, struct smbsrv_request);
+ union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
+ struct auth_serversupplied_info *server_info = NULL;
+ struct auth_session_info *session_info;
+ struct smbsrv_session *smb_sess;
+ NTSTATUS status;
+
+ status = auth_check_password_recv(areq, req, &server_info);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ /* This references server_info into session_info */
+ status = auth_generate_session_info(req, server_info, &session_info);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ /* allocate a new session */
+ smb_sess = smbsrv_session_new(req->smb_conn, req, NULL);
+ if (!smb_sess) {
+ status = NT_STATUS_INSUFFICIENT_RESOURCES;
+ goto failed;
+ }
+
+ /* Ensure this is marked as a 'real' vuid, not one
+ * simply valid for the session setup leg */
+ status = smbsrv_session_sesssetup_finished(smb_sess, session_info);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+
+ /* To correctly process any AndX packet (like a tree connect)
+ * we need to fill in the session on the request here */
+ req->session = smb_sess;
+ sess->old.out.vuid = smb_sess->vuid;
+
+failed:
+ status = auth_nt_status_squash(status);
+ smbsrv_sesssetup_backend_send(req, sess, status);
+}