auth/auth_sam_reply: let make_user_info_dc_netlogon_validation() correctly handle...
[sharpe/samba-autobuild/.git] / auth / auth_sam_reply.c
index 00e04b941edbefec1babc5846ec96107dee4f36a..0e2c008984f869a215a0503d087b9ee8df2b7868 100644 (file)
@@ -26,7 +26,7 @@
 #include "auth/auth_sam_reply.h"
 
 NTSTATUS auth_convert_user_info_dc_sambaseinfo(TALLOC_CTX *mem_ctx,
-                                             struct auth_user_info_dc *user_info_dc,
+                                             const struct auth_user_info_dc *user_info_dc,
                                              struct netr_SamBaseInfo **_sam)
 {
        NTSTATUS status;
@@ -133,7 +133,7 @@ NTSTATUS auth_convert_user_info_dc_sambaseinfo(TALLOC_CTX *mem_ctx,
 /* Note that the validity of the _sam3 structure is only as long as
  * the user_info_dc it was generated from */
 NTSTATUS auth_convert_user_info_dc_saminfo3(TALLOC_CTX *mem_ctx,
-                                          struct auth_user_info_dc *user_info_dc,
+                                          const struct auth_user_info_dc *user_info_dc,
                                           struct netr_SamInfo3 **_sam3)
 {
        struct netr_SamBaseInfo *sam;
@@ -154,7 +154,10 @@ NTSTATUS auth_convert_user_info_dc_saminfo3(TALLOC_CTX *mem_ctx,
 
        sam3->sids = talloc_array(sam, struct netr_SidAttr,
                                  user_info_dc->num_sids);
-       NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sam3->sids, sam3);
+       if (sam3->sids == NULL) {
+               TALLOC_FREE(sam3);
+               return NT_STATUS_NO_MEMORY;
+       }
 
        /* We don't put the user and group SIDs in there */
        for (i=2; i<user_info_dc->num_sids; i++) {
@@ -162,7 +165,10 @@ NTSTATUS auth_convert_user_info_dc_saminfo3(TALLOC_CTX *mem_ctx,
                        continue;
                }
                sam3->sids[sam3->sidcount].sid = dom_sid_dup(sam3->sids, &user_info_dc->sids[i]);
-               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sam3->sids[sam3->sidcount].sid, sam3);
+               if (sam3->sids[sam3->sidcount].sid == NULL) {
+                       TALLOC_FREE(sam3);
+                       return NT_STATUS_NO_MEMORY;
+               }
                sam3->sids[sam3->sidcount].attributes =
                        SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
                sam3->sidcount += 1;
@@ -185,7 +191,7 @@ NTSTATUS auth_convert_user_info_dc_saminfo3(TALLOC_CTX *mem_ctx,
 
 NTSTATUS make_user_info_SamBaseInfo(TALLOC_CTX *mem_ctx,
                                    const char *account_name,
-                                   struct netr_SamBaseInfo *base,
+                                   const struct netr_SamBaseInfo *base,
                                    bool authenticated,
                                    struct auth_user_info **_user_info)
 {
@@ -253,13 +259,17 @@ NTSTATUS make_user_info_SamBaseInfo(TALLOC_CTX *mem_ctx,
 NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx,
                                              const char *account_name,
                                              uint16_t validation_level,
-                                             union netr_Validation *validation,
+                                             const union netr_Validation *validation,
                                               bool authenticated,
                                              struct auth_user_info_dc **_user_info_dc)
 {
        NTSTATUS status;
-       struct auth_user_info_dc *user_info_dc;
-       struct netr_SamBaseInfo *base = NULL;
+       struct auth_user_info_dc *user_info_dc = NULL;
+       const struct netr_SamBaseInfo *base = NULL;
+       uint32_t sidcount = 0;
+       const struct netr_SidAttr *sids = NULL;
+       const char *dns_domainname = NULL;
+       const char *principal = NULL;
        uint32_t i;
 
        switch (validation_level) {
@@ -274,12 +284,18 @@ NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx,
                        return NT_STATUS_INVALID_PARAMETER;
                }
                base = &validation->sam3->base;
+               sidcount = validation->sam3->sidcount;
+               sids = validation->sam3->sids;
                break;
        case 6:
                if (!validation || !validation->sam6) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
                base = &validation->sam6->base;
+               sidcount = validation->sam6->sidcount;
+               sids = validation->sam6->sids;
+               dns_domainname = validation->sam6->dns_domainname.string;
+               principal = validation->sam6->principal_name.string;
                break;
        default:
                return NT_STATUS_INVALID_LEVEL;
@@ -333,26 +349,29 @@ NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx,
            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
          */
 
-       if (validation_level == 3) {
+       /*
+        * The IDL layer would be a better place to check this, but to
+        * guard the integer addition below, we double-check
+        */
+       if (sidcount > UINT16_MAX) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (sidcount > 0) {
                struct dom_sid *dgrps = user_info_dc->sids;
-               size_t sidcount;
+               size_t dgrps_count;
 
-               /* The IDL layer would be a better place to check this, but to
-                * guard the integer addition below, we double-check */
-               if (validation->sam3->sidcount > 65535) {
-                       return NT_STATUS_INVALID_PARAMETER;
+               dgrps_count = user_info_dc->num_sids + sidcount;
+               dgrps = talloc_realloc(user_info_dc, dgrps, struct dom_sid,
+                                      dgrps_count);
+               if (dgrps == NULL) {
+                       return NT_STATUS_NO_MEMORY;
                }
 
-               sidcount = user_info_dc->num_sids + validation->sam3->sidcount;
-               if (validation->sam3->sidcount > 0) {
-                       dgrps = talloc_realloc(user_info_dc, dgrps, struct dom_sid, sidcount);
-                       NT_STATUS_HAVE_NO_MEMORY(dgrps);
-
-                       for (i = 0; i < validation->sam3->sidcount; i++) {
-                               if (validation->sam3->sids[i].sid) {
-                                       dgrps[user_info_dc->num_sids] = *validation->sam3->sids[i].sid;
-                                       user_info_dc->num_sids++;
-                               }
+               for (i = 0; i < sidcount; i++) {
+                       if (sids[i].sid) {
+                               dgrps[user_info_dc->num_sids] = *sids[i].sid;
+                               user_info_dc->num_sids++;
                        }
                }
 
@@ -366,6 +385,22 @@ NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx,
                return status;
        }
 
+       if (dns_domainname != NULL) {
+               user_info_dc->info->dns_domain_name = talloc_strdup(user_info_dc->info,
+                                                                   dns_domainname);
+               if (user_info_dc->info->dns_domain_name == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       if (principal != NULL) {
+               user_info_dc->info->user_principal_name = talloc_strdup(user_info_dc->info,
+                                                                       principal);
+               if (user_info_dc->info->user_principal_name == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
        /* ensure we are never given NULL session keys */
 
        if (all_zero(base->key.key, sizeof(base->key.key))) {
@@ -390,7 +425,7 @@ NTSTATUS make_user_info_dc_netlogon_validation(TALLOC_CTX *mem_ctx,
  * Make a user_info_dc struct from the PAC_LOGON_INFO supplied in the krb5 logon
  */
 NTSTATUS make_user_info_dc_pac(TALLOC_CTX *mem_ctx,
-                             struct PAC_LOGON_INFO *pac_logon_info,
+                             const struct PAC_LOGON_INFO *pac_logon_info,
                              struct auth_user_info_dc **_user_info_dc)
 {
        uint32_t i;
@@ -398,7 +433,7 @@ NTSTATUS make_user_info_dc_pac(TALLOC_CTX *mem_ctx,
        union netr_Validation validation;
        struct auth_user_info_dc *user_info_dc;
 
-       validation.sam3 = &pac_logon_info->info3;
+       validation.sam3 = discard_const_p(struct netr_SamInfo3, &pac_logon_info->info3);
 
        nt_status = make_user_info_dc_netlogon_validation(mem_ctx, "", 3, &validation,
                                                          true, /* This user was authenticated */
@@ -429,7 +464,10 @@ NTSTATUS make_user_info_dc_pac(TALLOC_CTX *mem_ctx,
                sidcount = user_info_dc->num_sids + pac_logon_info->res_groups.count;
                user_info_dc->sids
                        = talloc_realloc(user_info_dc, user_info_dc->sids, struct dom_sid, sidcount);
-               NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
+               if (user_info_dc->sids == NULL) {
+                       TALLOC_FREE(user_info_dc);
+                       return NT_STATUS_NO_MEMORY;
+               }
 
                for (i = 0; pac_logon_info->res_group_dom_sid && i < pac_logon_info->res_groups.count; i++) {
                        user_info_dc->sids[user_info_dc->num_sids] = *pac_logon_info->res_group_dom_sid;