STEP01: librpc/rpc/dcerpc_connection.c: dcerpc_ncacn_push_auth
authorStefan Metzmacher <metze@samba.org>
Sat, 11 Jan 2014 08:50:30 +0000 (09:50 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:45:39 +0000 (12:45 +0200)
librpc/rpc/dcerpc_connection.c

index e3c4dd6cc5e5ff314da57414cfd7a5ed3eaf0eec..787189056c8c422a418d7417773ebd78ba9f939b 100644 (file)
@@ -302,6 +302,66 @@ static NTSTATUS dcerpc_guess_pdu_sizes(struct dcerpc_security *sec,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS dcerpc_ncacn_push_auth(DATA_BLOB *blob,
+                                      TALLOC_CTX *mem_ctx,
+                                      struct ncacn_packet *pkt,
+                                      struct dcerpc_auth *auth_info)
+{
+       struct ndr_push *ndr;
+       enum ndr_err_code ndr_err;
+
+       ndr = ndr_push_init_ctx(mem_ctx);
+       if (!ndr) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!(pkt->drep[0] & DCERPC_DREP_LE)) {
+               ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
+       }
+
+       if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
+               ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
+       }
+
+       if (auth_info) {
+               pkt->auth_length = auth_info->credentials.length;
+       } else {
+               pkt->auth_length = 0;
+       }
+
+       ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               return ndr_map_error2ntstatus(ndr_err);
+       }
+
+       if (auth_info) {
+#if 0
+               /* the s3 rpc server doesn't handle auth padding in
+                  bind requests. Use zero auth padding to keep us
+                  working with old servers */
+               uint32_t offset = ndr->offset;
+               ndr_err = ndr_push_align(ndr, 16);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return ndr_map_error2ntstatus(ndr_err);
+               }
+               auth_info->auth_pad_length = ndr->offset - offset;
+#else
+               auth_info->auth_pad_length = 0;
+#endif
+               ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       return ndr_map_error2ntstatus(ndr_err);
+               }
+       }
+
+       *blob = ndr_push_blob(ndr);
+
+       /* fill in the frag length */
+       dcerpc_set_frag_length(blob, blob->length);
+
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS dcerpc_ncacn_packet_blob(TALLOC_CTX *mem_ctx,
                                         enum dcerpc_pkt_type ptype,
                                         uint8_t pfc_flags,
@@ -311,7 +371,7 @@ static NTSTATUS dcerpc_ncacn_packet_blob(TALLOC_CTX *mem_ctx,
                                         DATA_BLOB *blob)
 {
        struct ncacn_packet r;
-       enum ndr_err_code ndr_err;
+       NTSTATUS status;
 
        r.rpc_vers              = 5;
        r.rpc_vers_minor        = 0;
@@ -325,14 +385,11 @@ static NTSTATUS dcerpc_ncacn_packet_blob(TALLOC_CTX *mem_ctx,
        r.call_id               = call_id;
        r.u                     = *u;
 
-       ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
-               (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return ndr_map_error2ntstatus(ndr_err);
+       status = dcerpc_ncacn_push_auth(blob, mem_ctx, &r, NULL);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
 
-       dcerpc_set_frag_length(blob, blob->length);
-
        if (DEBUGLEVEL >= 10) {
                /* set frag len for print function */
                r.frag_length = blob->length;