LCOV - code coverage report
Current view: top level - source4/lib/policy - gp_manage.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 159 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  Group Policy Object Support
       4             :  *  Copyright (C) Wilco Baan Hofman 2010
       5             :  *
       6             :  *  This program is free software; you can redistribute it and/or modify
       7             :  *  it under the terms of the GNU General Public License as published by
       8             :  *  the Free Software Foundation; either version 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      11             :  *  This program is distributed in the hope that it will be useful,
      12             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  *  GNU General Public License for more details.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : #include "includes.h"
      20             : #include "../libcli/security/dom_sid.h"
      21             : #include "../libcli/security/security_descriptor.h"
      22             : #include "../librpc/ndr/libndr.h"
      23             : #include "../lib/util/charset/charset.h"
      24             : #include "param/param.h"
      25             : #include "lib/policy/policy.h"
      26             : 
      27           0 : uint32_t gp_ads_to_dir_access_mask(uint32_t access_mask)
      28             : {
      29             :         uint32_t fs_mask;
      30             : 
      31             :         /* Copy the standard access mask */
      32           0 :         fs_mask = access_mask & 0x001F0000;
      33             : 
      34             :         /* When READ_PROP and LIST_CONTENTS are set, read access is granted on the GPT */
      35           0 :         if (access_mask & SEC_ADS_READ_PROP && access_mask & SEC_ADS_LIST) {
      36           0 :                 fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_LIST | SEC_DIR_READ_ATTRIBUTE |
      37             :                                 SEC_DIR_READ_EA | SEC_DIR_TRAVERSE;
      38             :         }
      39             : 
      40             :         /* When WRITE_PROP is set, full write access is granted on the GPT */
      41           0 :         if (access_mask & SEC_ADS_WRITE_PROP) {
      42           0 :                 fs_mask |= SEC_STD_SYNCHRONIZE | SEC_DIR_WRITE_ATTRIBUTE |
      43             :                                 SEC_DIR_WRITE_EA | SEC_DIR_ADD_FILE |
      44             :                                 SEC_DIR_ADD_SUBDIR;
      45             :         }
      46             : 
      47             :         /* Map CREATE_CHILD to add file and add subdir */
      48           0 :         if (access_mask & SEC_ADS_CREATE_CHILD)
      49           0 :                 fs_mask |= SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR;
      50             : 
      51             :         /* Map ADS delete child to dir delete child */
      52           0 :         if (access_mask & SEC_ADS_DELETE_CHILD)
      53           0 :                 fs_mask |= SEC_DIR_DELETE_CHILD;
      54             : 
      55           0 :         return fs_mask;
      56             : }
      57             : 
      58           0 : NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret)
      59             : {
      60             :         struct security_descriptor *fs_sd;
      61             :         NTSTATUS status;
      62             :         uint32_t i;
      63             : 
      64             :         /* Allocate the file system security descriptor */
      65           0 :         fs_sd = talloc(mem_ctx, struct security_descriptor);
      66           0 :         NT_STATUS_HAVE_NO_MEMORY(fs_sd);
      67             : 
      68             :         /* Copy the basic information from the directory server security descriptor */
      69           0 :         fs_sd->owner_sid = talloc_memdup(fs_sd, ds_sd->owner_sid, sizeof(struct dom_sid));
      70           0 :         if (fs_sd->owner_sid == NULL) {
      71           0 :                 TALLOC_FREE(fs_sd);
      72           0 :                 return NT_STATUS_NO_MEMORY;
      73             :         }
      74             : 
      75           0 :         fs_sd->group_sid = talloc_memdup(fs_sd, ds_sd->group_sid, sizeof(struct dom_sid));
      76           0 :         if (fs_sd->group_sid == NULL) {
      77           0 :                 TALLOC_FREE(fs_sd);
      78           0 :                 return NT_STATUS_NO_MEMORY;
      79             :         }
      80             : 
      81           0 :         fs_sd->type = ds_sd->type;
      82           0 :         fs_sd->revision = ds_sd->revision;
      83             : 
      84             :         /* Copy the sacl */
      85           0 :         fs_sd->sacl = security_acl_dup(fs_sd, ds_sd->sacl);
      86           0 :         if (fs_sd->sacl == NULL) {
      87           0 :                 TALLOC_FREE(fs_sd);
      88           0 :                 return NT_STATUS_NO_MEMORY;
      89             :         }
      90             : 
      91             :         /* Copy the dacl */
      92           0 :         fs_sd->dacl = talloc_zero(fs_sd, struct security_acl);
      93           0 :         if (fs_sd->dacl == NULL) {
      94           0 :                 TALLOC_FREE(fs_sd);
      95           0 :                 return NT_STATUS_NO_MEMORY;
      96             :         }
      97             : 
      98           0 :         for (i = 0; i < ds_sd->dacl->num_aces; i++) {
      99           0 :                 char *trustee = dom_sid_string(fs_sd, &ds_sd->dacl->aces[i].trustee);
     100             :                 struct security_ace *ace;
     101             : 
     102             :                 /* Don't add the allow for SID_BUILTIN_PREW2K */
     103           0 :                 if ((ds_sd->dacl->aces[i].type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
     104           0 :                      ds_sd->dacl->aces[i].type == SEC_ACE_TYPE_ACCESS_ALLOWED) &&
     105           0 :                                 strcmp(trustee, SID_BUILTIN_PREW2K) == 0) {
     106           0 :                         talloc_free(trustee);
     107           0 :                         continue;
     108             :                 }
     109             : 
     110             :                 /* Copy the ace from the directory server security descriptor */
     111           0 :                 ace = talloc_memdup(fs_sd, &ds_sd->dacl->aces[i], sizeof(struct security_ace));
     112           0 :                 if (ace == NULL) {
     113           0 :                         TALLOC_FREE(fs_sd);
     114           0 :                         return NT_STATUS_NO_MEMORY;
     115             :                 }
     116             : 
     117             :                 /* Set specific inheritance flags for within the GPO */
     118           0 :                 ace->flags |= SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT;
     119           0 :                 if (strcmp(trustee, SID_CREATOR_OWNER) == 0) {
     120           0 :                         ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     121             :                 }
     122             : 
     123             :                 /* Get a directory access mask from the assigned access mask on the LDAP object */
     124           0 :                 ace->access_mask = gp_ads_to_dir_access_mask(ace->access_mask);
     125             : 
     126             :                 /* Add the ace to the security descriptor DACL */
     127           0 :                 status = security_descriptor_dacl_add(fs_sd, ace);
     128           0 :                 if (!NT_STATUS_IS_OK(status)) {
     129           0 :                         DEBUG(0, ("Failed to add a dacl to file system security descriptor\n"));
     130           0 :                         return status;
     131             :                 }
     132             : 
     133             :                 /* Clean up the allocated data in this iteration */
     134           0 :                 talloc_free(trustee);
     135             :         }
     136             : 
     137           0 :         *ret = fs_sd;
     138           0 :         return NT_STATUS_OK;
     139             : }
     140             : 
     141             : 
     142           0 : NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret)
     143             : {
     144             :         struct GUID guid_struct;
     145             :         char *guid_str;
     146             :         char *name;
     147             :         struct security_descriptor *sd;
     148             :         TALLOC_CTX *mem_ctx;
     149             :         struct gp_object *gpo;
     150             :         NTSTATUS status;
     151             : 
     152             :         /* Create a forked memory context, as a base for everything here */
     153           0 :         mem_ctx = talloc_new(gp_ctx);
     154           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     155             : 
     156             :         /* Create the gpo struct to return later */
     157           0 :         gpo = talloc(gp_ctx, struct gp_object);
     158           0 :         if (gpo == NULL) {
     159           0 :                 TALLOC_FREE(mem_ctx);
     160           0 :                 return NT_STATUS_NO_MEMORY;
     161             :         }
     162             : 
     163             :         /* Generate a GUID */
     164           0 :         guid_struct = GUID_random();
     165           0 :         guid_str = GUID_string2(mem_ctx, &guid_struct);
     166           0 :         if (guid_str == NULL) {
     167           0 :                 TALLOC_FREE(mem_ctx);
     168           0 :                 return NT_STATUS_NO_MEMORY;
     169             :         }
     170           0 :         name = strupper_talloc(mem_ctx, guid_str);
     171           0 :         if (name == NULL) {
     172           0 :                 TALLOC_FREE(mem_ctx);
     173           0 :                 return NT_STATUS_NO_MEMORY;
     174             :         }
     175             : 
     176             :         /* Prepare the GPO struct */
     177           0 :         gpo->dn = NULL;
     178           0 :         gpo->name = name;
     179           0 :         gpo->flags = 0;
     180           0 :         gpo->version = 0;
     181           0 :         gpo->display_name = talloc_strdup(gpo, display_name);
     182           0 :         if (gpo->display_name == NULL) {
     183           0 :                 TALLOC_FREE(mem_ctx);
     184           0 :                 return NT_STATUS_NO_MEMORY;
     185             :         }
     186             : 
     187           0 :         gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lpcfg_dnsdomain(gp_ctx->lp_ctx), lpcfg_dnsdomain(gp_ctx->lp_ctx), name);
     188           0 :         if (gpo->file_sys_path == NULL) {
     189           0 :                 TALLOC_FREE(mem_ctx);
     190           0 :                 return NT_STATUS_NO_MEMORY;
     191             :         }
     192             : 
     193             :         /* Create the GPT */
     194           0 :         status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path);
     195           0 :         if (!NT_STATUS_IS_OK(status)) {
     196           0 :                 DEBUG(0, ("Failed to create GPT\n"));
     197           0 :                 talloc_free(mem_ctx);
     198           0 :                 return status;
     199             :         }
     200             : 
     201             : 
     202             :         /* Create the LDAP GPO, including CN=User and CN=Machine */
     203           0 :         status = gp_create_ldap_gpo(gp_ctx, gpo);
     204           0 :         if (!NT_STATUS_IS_OK(status)) {
     205           0 :                 DEBUG(0, ("Failed to create LDAP group policy object\n"));
     206           0 :                 talloc_free(mem_ctx);
     207           0 :                 return status;
     208             :         }
     209             : 
     210             :         /* Get the new security descriptor */
     211           0 :         status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo);
     212           0 :         if (!NT_STATUS_IS_OK(status)) {
     213           0 :                 DEBUG(0, ("Failed to fetch LDAP group policy object\n"));
     214           0 :                 talloc_free(mem_ctx);
     215           0 :                 return status;
     216             :         }
     217             : 
     218             :         /* Create matching file and DS security descriptors */
     219           0 :         status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd);
     220           0 :         if (!NT_STATUS_IS_OK(status)) {
     221           0 :                 DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
     222           0 :                 talloc_free(mem_ctx);
     223           0 :                 return status;
     224             :         }
     225             : 
     226             :         /* Set the security descriptor on the filesystem for this GPO */
     227           0 :         status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd);
     228           0 :         if (!NT_STATUS_IS_OK(status)) {
     229           0 :                 DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
     230           0 :                 talloc_free(mem_ctx);
     231           0 :                 return status;
     232             :         }
     233             : 
     234           0 :         talloc_free(mem_ctx);
     235             : 
     236           0 :         *ret = gpo;
     237           0 :         return NT_STATUS_OK;
     238             : }
     239             : 
     240           0 : NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
     241             : {
     242             :         TALLOC_CTX *mem_ctx;
     243             :         struct security_descriptor *fs_sd;
     244             :         struct gp_object *gpo;
     245             :         NTSTATUS status;
     246             : 
     247             :         /* Create a forked memory context, as a base for everything here */
     248           0 :         mem_ctx = talloc_new(gp_ctx);
     249           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     250             : 
     251             :         /* Set the ACL on LDAP database */
     252           0 :         status = gp_set_ads_acl(gp_ctx, dn_str, sd);
     253           0 :         if (!NT_STATUS_IS_OK(status)) {
     254           0 :                 DEBUG(0, ("Failed to set ACL on ADS\n"));
     255           0 :                 talloc_free(mem_ctx);
     256           0 :                 return status;
     257             :         }
     258             : 
     259             :         /* Get the group policy object information, for filesystem location and merged sd */
     260           0 :         status = gp_get_gpo_info(gp_ctx, dn_str, &gpo);
     261           0 :         if (!NT_STATUS_IS_OK(status)) {
     262           0 :                 DEBUG(0, ("Failed to set ACL on ADS\n"));
     263           0 :                 talloc_free(mem_ctx);
     264           0 :                 return status;
     265             :         }
     266             : 
     267             :         /* Create matching file and DS security descriptors */
     268           0 :         status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &fs_sd);
     269           0 :         if (!NT_STATUS_IS_OK(status)) {
     270           0 :                 DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
     271           0 :                 talloc_free(mem_ctx);
     272           0 :                 return status;
     273             :         }
     274             : 
     275             :         /* Set the security descriptor on the filesystem for this GPO */
     276           0 :         status = gp_set_gpt_security_descriptor(gp_ctx, gpo, fs_sd);
     277           0 :         if (!NT_STATUS_IS_OK(status)) {
     278           0 :                 DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
     279           0 :                 talloc_free(mem_ctx);
     280           0 :                 return status;
     281             :         }
     282             : 
     283           0 :         talloc_free(mem_ctx);
     284           0 :         return NT_STATUS_OK;
     285             : }
     286             : 
     287           0 : NTSTATUS gp_push_gpo (struct gp_context *gp_ctx, const char *local_path, struct gp_object *gpo)
     288             : {
     289             :         NTSTATUS status;
     290             :         TALLOC_CTX *mem_ctx;
     291             :         struct gp_ini_context *ini;
     292             :         char *filename;
     293             : 
     294           0 :         mem_ctx = talloc_new(gp_ctx);
     295           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     296             : 
     297             :         /* Get version from ini file */
     298             :         /* FIXME: The local file system may be case sensitive */
     299           0 :         filename = talloc_asprintf(mem_ctx, "%s/%s", local_path, "GPT.INI");
     300           0 :         if (filename == NULL) {
     301           0 :                 TALLOC_FREE(mem_ctx);
     302           0 :                 return NT_STATUS_NO_MEMORY;
     303             :         }
     304           0 :         status = gp_parse_ini(mem_ctx, gp_ctx, local_path, &ini);
     305           0 :         if (!NT_STATUS_IS_OK(status)) {
     306           0 :                 DEBUG(0, ("Failed to parse GPT.INI.\n"));
     307           0 :                 talloc_free(mem_ctx);
     308           0 :                 return status;
     309             :         }
     310             : 
     311             :         /* Push the GPT to the remote sysvol */
     312           0 :         status = gp_push_gpt(gp_ctx, local_path, gpo->file_sys_path);
     313           0 :         if (!NT_STATUS_IS_OK(status)) {
     314           0 :                 DEBUG(0, ("Failed to push GPT to DC's sysvol share.\n"));
     315           0 :                 talloc_free(mem_ctx);
     316           0 :                 return status;
     317             :         }
     318             : 
     319             :         /* Write version to LDAP */
     320           0 :         status = gp_set_ldap_gpo(gp_ctx, gpo);
     321           0 :         if (!NT_STATUS_IS_OK(status)) {
     322           0 :                 DEBUG(0, ("Failed to set GPO options in DC's LDAP.\n"));
     323           0 :                 talloc_free(mem_ctx);
     324           0 :                 return status;
     325             :         }
     326             : 
     327           0 :         talloc_free(mem_ctx);
     328           0 :         return NT_STATUS_OK;
     329             : }

Generated by: LCOV version 1.13