r15327: Support 'nosize'. Also write prototypes for print and size functions that...
[jelmer/samba4-debian.git] / source / librpc / ndr / ndr_sec.c
index f9169536ae2752e6e63bdd8c8c7a987f657930d9..fb18d48909d8b65da37a90898687f6ac67b0b713 100644 (file)
@@ -23,6 +23,7 @@
 
 
 #include "includes.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 /*
   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
@@ -33,154 +34,87 @@ NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *
        if (!(ndr_flags & NDR_SCALARS)) {
                return NT_STATUS_OK;
        }
-       NDR_CHECK(ndr_pull_uint32(ndr, &num_auths));
-       return ndr_pull_dom_sid(ndr, ndr_flags, sid);
+       NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
+       NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
+       if (sid->num_auths != num_auths) {
+               return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, 
+                                     "Bad array size %u should exceed %u", 
+                                     num_auths, sid->num_auths);
+       }
+       return NT_STATUS_OK;
 }
 
 /*
   parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
 */
-NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, struct dom_sid *sid)
+NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
 {
        if (!(ndr_flags & NDR_SCALARS)) {
                return NT_STATUS_OK;
        }
-       NDR_CHECK(ndr_push_uint32(ndr, sid->num_auths));
+       NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
        return ndr_push_dom_sid(ndr, ndr_flags, sid);
 }
 
-
 /*
-  convert a dom_sid to a string
+  parse a dom_sid28 - this is a dom_sid in a fixed 28 byte buffer, so we need to ensure there are only upto 5 sub_auth
 */
-char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid)
+NTSTATUS ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
 {
-       int i, ofs, maxlen;
-       uint32_t ia;
-       char *ret;
-       
-       if (!sid) {
-               return talloc_strdup(mem_ctx, "(NULL SID)");
+       NTSTATUS status;
+       struct ndr_pull *subndr;
+
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
        }
 
-       maxlen = sid->num_auths * 11 + 25;
-       ret = talloc(mem_ctx, maxlen);
-       if (!ret) return talloc_strdup(mem_ctx, "(SID ERR)");
+       subndr = talloc_zero(ndr, struct ndr_pull);
+       NT_STATUS_HAVE_NO_MEMORY(subndr);
+       subndr->flags           = ndr->flags;
+       subndr->current_mem_ctx = ndr->current_mem_ctx;
 
-       ia = (sid->id_auth[5]) +
-               (sid->id_auth[4] << 8 ) +
-               (sid->id_auth[3] << 16) +
-               (sid->id_auth[2] << 24);
+       subndr->data            = ndr->data + ndr->offset;
+       subndr->data_size       = 28;
+       subndr->offset          = 0;
 
-       ofs = snprintf(ret, maxlen, "S-%u-%lu", 
-                      (uint_t)sid->sid_rev_num, (unsigned long)ia);
+       NDR_CHECK(ndr_pull_advance(ndr, 28));
 
-       for (i = 0; i < sid->num_auths; i++) {
-               ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
+       status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               /* handle a w2k bug which send random data in the buffer */
+               ZERO_STRUCTP(sid);
        }
-       
-       return ret;
-}
-
 
-/*
-  print a dom_sid
-*/
-void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, struct dom_sid *sid)
-{
-       ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid));
-}
-
-void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, struct dom_sid2 *sid)
-{
-       ndr_print_dom_sid(ndr, name, sid);
+       return NT_STATUS_OK;
 }
 
 /*
-  return the wire size of a dom_sid
+  push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
 */
-size_t ndr_size_dom_sid(struct dom_sid *sid)
+NTSTATUS ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
 {
-       if (!sid) return 0;
-       return 8 + 4*sid->num_auths;
-}
+       uint32_t old_offset;
+       uint32_t padding;
 
-/*
-  add a rid to a domain dom_sid to make a full dom_sid
-*/
-struct dom_sid *dom_sid_add_rid(TALLOC_CTX *mem_ctx, 
-                               const struct dom_sid *domain_sid, 
-                               uint32_t rid)
-{
-       struct dom_sid *sid;
-
-       sid = talloc_p(mem_ctx, struct dom_sid);
-       if (!sid) return NULL;
+       if (!(ndr_flags & NDR_SCALARS)) {
+               return NT_STATUS_OK;
+       }
 
-       *sid = *domain_sid;
-       /*TODO: use realloc! */
-       sid->sub_auths = talloc_array_p(mem_ctx, uint32_t, sid->num_auths+1);
-       if (!sid->sub_auths) {
-               return NULL;
+       if (sid->num_auths > 5) {
+               return ndr_push_error(ndr, NDR_ERR_RANGE, 
+                                     "dom_sid28 allows only upto 5 sub auth [%u]", 
+                                     sid->num_auths);
        }
-       memcpy(sid->sub_auths, domain_sid->sub_auths, sid->num_auths*sizeof(uint32_t));
-       sid->sub_auths[sid->num_auths] = rid;
-       sid->num_auths++;
-       return sid;
-}
 
-/*
-  return the wire size of a security_ace
-*/
-size_t ndr_size_security_ace(struct security_ace *ace)
-{
-       if (!ace) return 0;
-       return 8 + ndr_size_dom_sid(&ace->trustee);
-}
+       old_offset = ndr->offset;
+       NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
 
+       padding = 28 - (ndr->offset - old_offset);
 
-/*
-  return the wire size of a security_acl
-*/
-size_t ndr_size_security_acl(struct security_acl *acl)
-{
-       size_t ret;
-       int i;
-       if (!acl) return 0;
-       ret = 8;
-       for (i=0;i<acl->num_aces;i++) {
-               ret += ndr_size_security_ace(&acl->aces[i]);
+       if (padding > 0) {
+               NDR_CHECK(ndr_push_zero(ndr, padding));
        }
-       return ret;
-}
 
-/*
-  return the wire size of a security descriptor
-*/
-size_t ndr_size_security_descriptor(struct security_descriptor *sd)
-{
-       size_t ret;
-       if (!sd) return 0;
-       
-       ret = 20;
-       ret += ndr_size_dom_sid(sd->owner_sid);
-       ret += ndr_size_dom_sid(sd->group_sid);
-       ret += ndr_size_security_acl(sd->dacl);
-       ret += ndr_size_security_acl(sd->sacl);
-       return ret;
+       return NT_STATUS_OK;
 }
 
-/* 
-   talloc and copy a security descriptor
- */
-struct security_descriptor *copy_security_descriptor(TALLOC_CTX *mem_ctx, 
-                                                       const struct security_descriptor *osd)
-{
-       struct security_descriptor *nsd;
-
-       /* FIXME */
-       DEBUG(1, ("copy_security_descriptor: sorry unimplemented yet\n"));
-       nsd = NULL;
-
-       return nsd;
-}