LCOV - code coverage report
Current view: top level - source4/lib/policy - gp_manage.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 180 0.0 %
Date: 2024-04-21 15:09:00 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           0 :         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           0 :         struct security_descriptor *fs_sd;
      61           0 :         NTSTATUS status;
      62           0 :         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           0 :                 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 :                         TALLOC_FREE(fs_sd);
     131           0 :                         return status;
     132             :                 }
     133             : 
     134             :                 /* Clean up the allocated data in this iteration */
     135           0 :                 talloc_free(trustee);
     136             :         }
     137             : 
     138           0 :         *ret = fs_sd;
     139           0 :         return NT_STATUS_OK;
     140             : }
     141             : 
     142             : 
     143           0 : NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret)
     144             : {
     145           0 :         struct GUID guid_struct;
     146           0 :         char *guid_str;
     147           0 :         char *name;
     148           0 :         struct security_descriptor *sd;
     149           0 :         TALLOC_CTX *mem_ctx;
     150           0 :         struct gp_object *gpo;
     151           0 :         NTSTATUS status;
     152             : 
     153             :         /* Create a forked memory context, as a base for everything here */
     154           0 :         mem_ctx = talloc_new(gp_ctx);
     155           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     156             : 
     157             :         /* Create the gpo struct to return later */
     158           0 :         gpo = talloc(gp_ctx, struct gp_object);
     159           0 :         if (gpo == NULL) {
     160           0 :                 TALLOC_FREE(mem_ctx);
     161           0 :                 return NT_STATUS_NO_MEMORY;
     162             :         }
     163             : 
     164             :         /* Generate a GUID */
     165           0 :         guid_struct = GUID_random();
     166           0 :         guid_str = GUID_string2(mem_ctx, &guid_struct);
     167           0 :         if (guid_str == NULL) {
     168           0 :                 TALLOC_FREE(mem_ctx);
     169           0 :                 return NT_STATUS_NO_MEMORY;
     170             :         }
     171           0 :         name = strupper_talloc(mem_ctx, guid_str);
     172           0 :         if (name == NULL) {
     173           0 :                 TALLOC_FREE(mem_ctx);
     174           0 :                 return NT_STATUS_NO_MEMORY;
     175             :         }
     176             : 
     177             :         /* Prepare the GPO struct */
     178           0 :         gpo->dn = NULL;
     179           0 :         gpo->name = name;
     180           0 :         gpo->flags = 0;
     181           0 :         gpo->version = 0;
     182           0 :         gpo->display_name = talloc_strdup(gpo, display_name);
     183           0 :         if (gpo->display_name == NULL) {
     184           0 :                 TALLOC_FREE(mem_ctx);
     185           0 :                 return NT_STATUS_NO_MEMORY;
     186             :         }
     187             : 
     188           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);
     189           0 :         if (gpo->file_sys_path == NULL) {
     190           0 :                 TALLOC_FREE(mem_ctx);
     191           0 :                 return NT_STATUS_NO_MEMORY;
     192             :         }
     193             : 
     194             :         /* Create the GPT */
     195           0 :         status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path);
     196           0 :         if (!NT_STATUS_IS_OK(status)) {
     197           0 :                 DEBUG(0, ("Failed to create GPT\n"));
     198           0 :                 talloc_free(mem_ctx);
     199           0 :                 return status;
     200             :         }
     201             : 
     202             : 
     203             :         /* Create the LDAP GPO, including CN=User and CN=Machine */
     204           0 :         status = gp_create_ldap_gpo(gp_ctx, gpo);
     205           0 :         if (!NT_STATUS_IS_OK(status)) {
     206           0 :                 DEBUG(0, ("Failed to create LDAP group policy object\n"));
     207           0 :                 talloc_free(mem_ctx);
     208           0 :                 return status;
     209             :         }
     210             : 
     211             :         /* Get the new security descriptor */
     212           0 :         status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo);
     213           0 :         if (!NT_STATUS_IS_OK(status)) {
     214           0 :                 DEBUG(0, ("Failed to fetch LDAP group policy object\n"));
     215           0 :                 talloc_free(mem_ctx);
     216           0 :                 return status;
     217             :         }
     218             : 
     219             :         /* Create matching file and DS security descriptors */
     220           0 :         status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd);
     221           0 :         if (!NT_STATUS_IS_OK(status)) {
     222           0 :                 DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
     223           0 :                 talloc_free(mem_ctx);
     224           0 :                 return status;
     225             :         }
     226             : 
     227             :         /* Set the security descriptor on the filesystem for this GPO */
     228           0 :         status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd);
     229           0 :         if (!NT_STATUS_IS_OK(status)) {
     230           0 :                 DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
     231           0 :                 talloc_free(mem_ctx);
     232           0 :                 return status;
     233             :         }
     234             : 
     235           0 :         talloc_free(mem_ctx);
     236             : 
     237           0 :         *ret = gpo;
     238           0 :         return NT_STATUS_OK;
     239             : }
     240             : 
     241           0 : NTSTATUS gp_set_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
     242             : {
     243           0 :         TALLOC_CTX *mem_ctx;
     244           0 :         struct security_descriptor *fs_sd;
     245           0 :         struct gp_object *gpo;
     246           0 :         NTSTATUS status;
     247             : 
     248             :         /* Create a forked memory context, as a base for everything here */
     249           0 :         mem_ctx = talloc_new(gp_ctx);
     250           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     251             : 
     252             :         /* Set the ACL on LDAP database */
     253           0 :         status = gp_set_ads_acl(gp_ctx, dn_str, sd);
     254           0 :         if (!NT_STATUS_IS_OK(status)) {
     255           0 :                 DEBUG(0, ("Failed to set ACL on ADS\n"));
     256           0 :                 talloc_free(mem_ctx);
     257           0 :                 return status;
     258             :         }
     259             : 
     260             :         /* Get the group policy object information, for filesystem location and merged sd */
     261           0 :         status = gp_get_gpo_info(gp_ctx, dn_str, &gpo);
     262           0 :         if (!NT_STATUS_IS_OK(status)) {
     263           0 :                 DEBUG(0, ("Failed to set ACL on ADS\n"));
     264           0 :                 talloc_free(mem_ctx);
     265           0 :                 return status;
     266             :         }
     267             : 
     268             :         /* Create matching file and DS security descriptors */
     269           0 :         status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &fs_sd);
     270           0 :         if (!NT_STATUS_IS_OK(status)) {
     271           0 :                 DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
     272           0 :                 talloc_free(mem_ctx);
     273           0 :                 return status;
     274             :         }
     275             : 
     276             :         /* Set the security descriptor on the filesystem for this GPO */
     277           0 :         status = gp_set_gpt_security_descriptor(gp_ctx, gpo, fs_sd);
     278           0 :         if (!NT_STATUS_IS_OK(status)) {
     279           0 :                 DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
     280           0 :                 talloc_free(mem_ctx);
     281           0 :                 return status;
     282             :         }
     283             : 
     284           0 :         talloc_free(mem_ctx);
     285           0 :         return NT_STATUS_OK;
     286             : }
     287             : 
     288           0 : NTSTATUS gp_push_gpo (struct gp_context *gp_ctx, const char *local_path, struct gp_object *gpo)
     289             : {
     290           0 :         NTSTATUS status;
     291           0 :         TALLOC_CTX *mem_ctx;
     292           0 :         struct gp_ini_context *ini;
     293           0 :         char *filename;
     294             : 
     295           0 :         mem_ctx = talloc_new(gp_ctx);
     296           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     297             : 
     298             :         /* Get version from ini file */
     299             :         /* FIXME: The local file system may be case sensitive */
     300           0 :         filename = talloc_asprintf(mem_ctx, "%s/%s", local_path, "GPT.INI");
     301           0 :         if (filename == NULL) {
     302           0 :                 TALLOC_FREE(mem_ctx);
     303           0 :                 return NT_STATUS_NO_MEMORY;
     304             :         }
     305           0 :         status = gp_parse_ini(mem_ctx, gp_ctx, local_path, &ini);
     306           0 :         if (!NT_STATUS_IS_OK(status)) {
     307           0 :                 DEBUG(0, ("Failed to parse GPT.INI.\n"));
     308           0 :                 talloc_free(mem_ctx);
     309           0 :                 return status;
     310             :         }
     311             : 
     312             :         /* Push the GPT to the remote sysvol */
     313           0 :         status = gp_push_gpt(gp_ctx, local_path, gpo->file_sys_path);
     314           0 :         if (!NT_STATUS_IS_OK(status)) {
     315           0 :                 DEBUG(0, ("Failed to push GPT to DC's sysvol share.\n"));
     316           0 :                 talloc_free(mem_ctx);
     317           0 :                 return status;
     318             :         }
     319             : 
     320             :         /* Write version to LDAP */
     321           0 :         status = gp_set_ldap_gpo(gp_ctx, gpo);
     322           0 :         if (!NT_STATUS_IS_OK(status)) {
     323           0 :                 DEBUG(0, ("Failed to set GPO options in DC's LDAP.\n"));
     324           0 :                 talloc_free(mem_ctx);
     325           0 :                 return status;
     326             :         }
     327             : 
     328           0 :         talloc_free(mem_ctx);
     329           0 :         return NT_STATUS_OK;
     330             : }

Generated by: LCOV version 1.14