LCOV - code coverage report
Current view: top level - source4/lib/policy - gp_ldap.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 28 694 4.0 %
Date: 2024-01-11 09:59:51 Functions: 2 16 12.5 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  Group Policy Object Support
       4             :  *  Copyright (C) Jelmer Vernooij 2008
       5             :  *  Copyright (C) Wilco Baan Hofman 2008-2010
       6             :  *
       7             :  *  This program is free software; you can redistribute it and/or modify
       8             :  *  it under the terms of the GNU General Public License as published by
       9             :  *  the Free Software Foundation; either version 3 of the License, or
      10             :  *  (at your option) any later version.
      11             :  *
      12             :  *  This program is distributed in the hope that it will be useful,
      13             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  *  GNU General Public License for more details.
      16             :  *
      17             :  *  You should have received a copy of the GNU General Public License
      18             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : #include "includes.h"
      21             : #include "param/param.h"
      22             : #include <ldb.h>
      23             : #include "lib/ldb-samba/ldb_wrap.h"
      24             : #include "auth/credentials/credentials.h"
      25             : #include "../librpc/gen_ndr/nbt.h"
      26             : #include "libcli/libcli.h"
      27             : #include "libnet/libnet.h"
      28             : #include "../librpc/gen_ndr/ndr_security.h"
      29             : #include "../libcli/security/security.h"
      30             : #include "libcli/ldap/ldap_ndr.h"
      31             : #include "../lib/talloc/talloc.h"
      32             : #include "lib/policy/policy.h"
      33             : 
      34             : struct gpo_stringmap {
      35             :         const char *str;
      36             :         uint32_t flags;
      37             : };
      38             : static const struct gpo_stringmap gplink_options [] = {
      39             :         { "GPLINK_OPT_DISABLE", GPLINK_OPT_DISABLE },
      40             :         { "GPLINK_OPT_ENFORCE", GPLINK_OPT_ENFORCE },
      41             :         { NULL, 0 }
      42             : };
      43             : static const struct gpo_stringmap gpo_flags [] = {
      44             :         { "GPO_FLAG_USER_DISABLE", GPO_FLAG_USER_DISABLE },
      45             :         { "GPO_FLAG_MACHINE_DISABLE", GPO_FLAG_MACHINE_DISABLE },
      46             :         { NULL, 0 }
      47             : };
      48             : 
      49           0 : static NTSTATUS parse_gpo(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct gp_object **ret)
      50             : {
      51           0 :         struct gp_object *gpo = talloc(mem_ctx, struct gp_object);
      52           0 :         enum ndr_err_code ndr_err;
      53           0 :         const DATA_BLOB *data;
      54             : 
      55           0 :         NT_STATUS_HAVE_NO_MEMORY(gpo);
      56             : 
      57           0 :         gpo->dn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(msg->dn));
      58           0 :         if (gpo->dn == NULL) {
      59           0 :                 TALLOC_FREE(gpo);
      60           0 :                 return NT_STATUS_NO_MEMORY;
      61             :         }
      62             : 
      63           0 :         DEBUG(9, ("Parsing GPO LDAP data for %s\n", gpo->dn));
      64             : 
      65           0 :         gpo->display_name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "displayName", ""));
      66           0 :         if (gpo->display_name == NULL) {
      67           0 :                 TALLOC_FREE(gpo);
      68           0 :                 return NT_STATUS_NO_MEMORY;
      69             :         }
      70             : 
      71           0 :         gpo->name = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "name", ""));
      72           0 :         if (gpo->name == NULL) {
      73           0 :                 TALLOC_FREE(gpo);
      74           0 :                 return NT_STATUS_NO_MEMORY;
      75             :         }
      76             : 
      77           0 :         gpo->flags = ldb_msg_find_attr_as_uint(msg, "flags", 0);
      78           0 :         gpo->version = ldb_msg_find_attr_as_uint(msg, "versionNumber", 0);
      79             : 
      80           0 :         gpo->file_sys_path = talloc_strdup(gpo, ldb_msg_find_attr_as_string(msg, "gPCFileSysPath", ""));
      81           0 :         if (gpo->file_sys_path == NULL) {
      82           0 :                 TALLOC_FREE(gpo);
      83           0 :                 return NT_STATUS_NO_MEMORY;
      84             :         }
      85             : 
      86             :         /* Pull the security descriptor through the NDR library */
      87           0 :         data = ldb_msg_find_ldb_val(msg, "nTSecurityDescriptor");
      88           0 :         gpo->security_descriptor = talloc(gpo, struct security_descriptor);
      89           0 :         if (gpo->security_descriptor == NULL) {
      90           0 :                 TALLOC_FREE(gpo);
      91           0 :                 return NT_STATUS_NO_MEMORY;
      92             :         }
      93             : 
      94           0 :         ndr_err = ndr_pull_struct_blob(data,
      95             :                         mem_ctx,
      96           0 :                         gpo->security_descriptor,
      97             :                         (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
      98           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
      99           0 :                 return ndr_map_error2ntstatus(ndr_err);
     100             :         }
     101             : 
     102           0 :         *ret = gpo;
     103           0 :         return NT_STATUS_OK;
     104             : }
     105             : 
     106          43 : NTSTATUS gp_get_gpo_flags(TALLOC_CTX *mem_ctx, uint32_t flags, const char ***ret)
     107             : {
     108          43 :         unsigned int i, count=0;
     109          43 :         const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
     110             : 
     111          43 :         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
     112             : 
     113          43 :         flag_strs[0] = NULL;
     114             : 
     115         129 :         for (i = 0; gpo_flags[i].str != NULL; i++) {
     116          86 :                 if (flags & gpo_flags[i].flags) {
     117           1 :                         flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
     118           1 :                         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
     119           1 :                         flag_strs[count] = gpo_flags[i].str;
     120           1 :                         flag_strs[count+1] = NULL;
     121           1 :                         count++;
     122             :                 }
     123             :         }
     124          43 :         *ret = flag_strs;
     125          43 :         return NT_STATUS_OK;
     126             : }
     127             : 
     128           1 : NTSTATUS gp_get_gplink_options(TALLOC_CTX *mem_ctx, uint32_t options, const char ***ret)
     129             : {
     130           1 :         unsigned int i, count=0;
     131           1 :         const char **flag_strs = talloc_array(mem_ctx, const char *, 1);
     132             : 
     133           1 :         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
     134           1 :         flag_strs[0] = NULL;
     135             : 
     136           3 :         for (i = 0; gplink_options[i].str != NULL; i++) {
     137           2 :                 if (options & gplink_options[i].flags) {
     138           1 :                         flag_strs = talloc_realloc(mem_ctx, flag_strs, const char *, count+2);
     139           1 :                         NT_STATUS_HAVE_NO_MEMORY(flag_strs);
     140           1 :                         flag_strs[count] = gplink_options[i].str;
     141           1 :                         flag_strs[count+1] = NULL;
     142           1 :                         count++;
     143             :                 }
     144             :         }
     145           1 :         *ret = flag_strs;
     146           1 :         return NT_STATUS_OK;
     147             : }
     148             : 
     149           0 : NTSTATUS gp_init(TALLOC_CTX *mem_ctx,
     150             :                 struct loadparm_context *lp_ctx,
     151             :                 struct cli_credentials *credentials,
     152             :                 struct tevent_context *ev_ctx,
     153             :                 struct gp_context **gp_ctx)
     154             : {
     155             : 
     156           0 :         struct libnet_LookupDCs *io;
     157           0 :         char *url;
     158           0 :         struct libnet_context *net_ctx;
     159           0 :         struct ldb_context *ldb_ctx;
     160           0 :         NTSTATUS rv;
     161             : 
     162             :         /* Initialise the libnet context */
     163           0 :         net_ctx = libnet_context_init(ev_ctx, lp_ctx);
     164           0 :         net_ctx->cred = credentials;
     165             : 
     166             :         /* Prepare libnet lookup structure for looking a DC (PDC is correct). */
     167           0 :         io = talloc_zero(mem_ctx, struct libnet_LookupDCs);
     168           0 :         NT_STATUS_HAVE_NO_MEMORY(io);
     169           0 :         io->in.name_type = NBT_NAME_PDC;
     170           0 :         io->in.domain_name = lpcfg_workgroup(lp_ctx);
     171             : 
     172             :         /* Find Active DC's */
     173           0 :         rv = libnet_LookupDCs(net_ctx, mem_ctx, io);
     174           0 :         if (!NT_STATUS_IS_OK(rv)) {
     175           0 :                 DEBUG(0, ("Failed to lookup DCs in domain\n"));
     176           0 :                 return rv;
     177             :         }
     178             : 
     179             :         /* Connect to ldap://DC_NAME with all relevant contexts*/
     180           0 :         url = talloc_asprintf(mem_ctx, "ldap://%s", io->out.dcs[0].name);
     181           0 :         NT_STATUS_HAVE_NO_MEMORY(url);
     182           0 :         ldb_ctx = ldb_wrap_connect(mem_ctx, net_ctx->event_ctx, lp_ctx,
     183             :                         url, NULL, net_ctx->cred, 0);
     184           0 :         if (ldb_ctx == NULL) {
     185           0 :                 DEBUG(0, ("Can't connect to DC's LDAP with url %s\n", url));
     186           0 :                 return NT_STATUS_UNSUCCESSFUL;
     187             :         }
     188             : 
     189           0 :         *gp_ctx = talloc_zero(mem_ctx, struct gp_context);
     190           0 :         NT_STATUS_HAVE_NO_MEMORY(gp_ctx);
     191             : 
     192           0 :         (*gp_ctx)->lp_ctx = lp_ctx;
     193           0 :         (*gp_ctx)->credentials = credentials;
     194           0 :         (*gp_ctx)->ev_ctx = ev_ctx;
     195           0 :         (*gp_ctx)->ldb_ctx = ldb_ctx;
     196           0 :         (*gp_ctx)->active_dc = talloc_reference(*gp_ctx, &io->out.dcs[0]);
     197             : 
     198             :         /* We don't need to keep the libnet context */
     199           0 :         talloc_free(net_ctx);
     200           0 :         return NT_STATUS_OK;
     201             : }
     202             : 
     203           0 : NTSTATUS gp_list_all_gpos(struct gp_context *gp_ctx, struct gp_object ***ret)
     204             : {
     205           0 :         struct ldb_result *result;
     206           0 :         int rv;
     207           0 :         NTSTATUS status;
     208           0 :         TALLOC_CTX *mem_ctx;
     209           0 :         struct ldb_dn *dn;
     210           0 :         struct gp_object **gpo;
     211           0 :         unsigned int i; /* same as in struct ldb_result */
     212           0 :         const char **attrs;
     213             : 
     214             :         /* Create a forked memory context, as a base for everything here */
     215           0 :         mem_ctx = talloc_new(gp_ctx);
     216           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     217             : 
     218             :         /* Create full ldb dn of the policies base object */
     219           0 :         dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
     220           0 :         rv = ldb_dn_add_child(dn, ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Policies,CN=System"));
     221           0 :         if (!rv) {
     222           0 :                 DEBUG(0, ("Can't append subtree to DN\n"));
     223           0 :                 talloc_free(mem_ctx);
     224           0 :                 return NT_STATUS_UNSUCCESSFUL;
     225             :         }
     226             : 
     227           0 :         DEBUG(10, ("Searching for policies in DN: %s\n", ldb_dn_get_linearized(dn)));
     228             : 
     229           0 :         attrs = talloc_array(mem_ctx, const char *, 7);
     230           0 :         if (attrs == NULL) {
     231           0 :                 TALLOC_FREE(mem_ctx);
     232           0 :                 return NT_STATUS_NO_MEMORY;
     233             :         }
     234             : 
     235           0 :         attrs[0] = "nTSecurityDescriptor";
     236           0 :         attrs[1] = "versionNumber";
     237           0 :         attrs[2] = "flags";
     238           0 :         attrs[3] = "name";
     239           0 :         attrs[4] = "displayName";
     240           0 :         attrs[5] = "gPCFileSysPath";
     241           0 :         attrs[6] = NULL;
     242             : 
     243           0 :         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_ONELEVEL, attrs, "(objectClass=groupPolicyContainer)");
     244           0 :         if (rv != LDB_SUCCESS) {
     245           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     246           0 :                 talloc_free(mem_ctx);
     247           0 :                 return NT_STATUS_UNSUCCESSFUL;
     248             :         }
     249             : 
     250           0 :         gpo = talloc_array(gp_ctx, struct gp_object *, result->count+1);
     251           0 :         if (gpo == NULL) {
     252           0 :                 TALLOC_FREE(mem_ctx);
     253           0 :                 return NT_STATUS_NO_MEMORY;
     254             :         }
     255             : 
     256           0 :         gpo[result->count] = NULL;
     257             : 
     258           0 :         for (i = 0; i < result->count; i++) {
     259           0 :                 status = parse_gpo(gp_ctx, result->msgs[i], &gpo[i]);
     260           0 :                 if (!NT_STATUS_IS_OK(status)) {
     261           0 :                         DEBUG(0, ("Failed to parse GPO.\n"));
     262           0 :                         talloc_free(mem_ctx);
     263           0 :                         return status;
     264             :                 }
     265             :         }
     266             : 
     267           0 :         talloc_free(mem_ctx);
     268             : 
     269           0 :         *ret = gpo;
     270           0 :         return NT_STATUS_OK;
     271             : }
     272             : 
     273           0 : NTSTATUS gp_get_gpo_info(struct gp_context *gp_ctx, const char *dn_str, struct gp_object **ret)
     274             : {
     275           0 :         struct ldb_result *result;
     276           0 :         struct ldb_dn *dn;
     277           0 :         struct gp_object *gpo;
     278           0 :         int rv;
     279           0 :         NTSTATUS status;
     280           0 :         TALLOC_CTX *mem_ctx;
     281           0 :         const char **attrs;
     282             : 
     283             :         /* Create a forked memory context, as a base for everything here */
     284           0 :         mem_ctx = talloc_new(gp_ctx);
     285           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     286             : 
     287             :         /* Create an ldb dn struct for the dn string */
     288           0 :         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     289             : 
     290           0 :         attrs = talloc_array(mem_ctx, const char *, 7);
     291           0 :         if (attrs == NULL) {
     292           0 :                 TALLOC_FREE(mem_ctx);
     293           0 :                 return NT_STATUS_NO_MEMORY;
     294             :         }
     295             : 
     296           0 :         attrs[0] = "nTSecurityDescriptor";
     297           0 :         attrs[1] = "versionNumber";
     298           0 :         attrs[2] = "flags";
     299           0 :         attrs[3] = "name";
     300           0 :         attrs[4] = "displayName";
     301           0 :         attrs[5] = "gPCFileSysPath";
     302           0 :         attrs[6] = NULL;
     303             : 
     304           0 :         rv = ldb_search(gp_ctx->ldb_ctx,
     305             :                         mem_ctx,
     306             :                         &result,
     307             :                         dn,
     308             :                         LDB_SCOPE_BASE,
     309             :                         attrs,
     310             :                         "objectClass=groupPolicyContainer");
     311           0 :         if (rv != LDB_SUCCESS) {
     312           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     313           0 :                 talloc_free(mem_ctx);
     314           0 :                 return NT_STATUS_UNSUCCESSFUL;
     315             :         }
     316             : 
     317             :         /* We expect exactly one record */
     318           0 :         if (result->count != 1) {
     319           0 :                 DEBUG(0, ("Could not find GPC with dn %s\n", dn_str));
     320           0 :                 talloc_free(mem_ctx);
     321           0 :                 return NT_STATUS_NOT_FOUND;
     322             :         }
     323             : 
     324           0 :         status = parse_gpo(gp_ctx, result->msgs[0], &gpo);
     325           0 :         if (!NT_STATUS_IS_OK(status)) {
     326           0 :                 DEBUG(0, ("Failed to parse GPO.\n"));
     327           0 :                 talloc_free(mem_ctx);
     328           0 :                 return status;
     329             :         }
     330             : 
     331           0 :         talloc_free(mem_ctx);
     332             : 
     333           0 :         *ret = gpo;
     334           0 :         return NT_STATUS_OK;
     335             : }
     336             : 
     337           0 : static NTSTATUS parse_gplink (TALLOC_CTX *mem_ctx, const char *gplink_str, struct gp_link ***ret)
     338             : {
     339           0 :         int start, idx=0;
     340           0 :         int pos;
     341           0 :         struct gp_link **gplinks;
     342           0 :         char *buf, *end;
     343           0 :         const char *gplink_start = "[LDAP://";
     344             : 
     345           0 :         gplinks = talloc_array(mem_ctx, struct gp_link *, 1);
     346           0 :         NT_STATUS_HAVE_NO_MEMORY(gplinks);
     347             : 
     348           0 :         gplinks[0] = NULL;
     349             : 
     350             :         /* Assuming every gPLink starts with "[LDAP://" */
     351           0 :         start = strlen(gplink_start);
     352             : 
     353           0 :         for (pos = start; pos < strlen(gplink_str); pos++) {
     354           0 :                 if (gplink_str[pos] == ';') {
     355           0 :                         gplinks = talloc_realloc(mem_ctx, gplinks, struct gp_link *, idx+2);
     356           0 :                         NT_STATUS_HAVE_NO_MEMORY(gplinks);
     357           0 :                         gplinks[idx] = talloc(mem_ctx, struct gp_link);
     358           0 :                         NT_STATUS_HAVE_NO_MEMORY(gplinks[idx]);
     359           0 :                         gplinks[idx]->dn = talloc_strndup(mem_ctx,
     360             :                                                           gplink_str + start,
     361           0 :                                                           pos - start);
     362           0 :                         if (gplinks[idx]->dn == NULL) {
     363           0 :                                 TALLOC_FREE(gplinks);
     364           0 :                                 return NT_STATUS_NO_MEMORY;
     365             :                         }
     366             : 
     367           0 :                         for (start = pos + 1; gplink_str[pos] != ']'; pos++);
     368             : 
     369           0 :                         buf = talloc_strndup(gplinks, gplink_str + start, pos - start);
     370           0 :                         if (buf == NULL) {
     371           0 :                                 TALLOC_FREE(gplinks);
     372           0 :                                 return NT_STATUS_NO_MEMORY;
     373             :                         }
     374           0 :                         gplinks[idx]->options = (uint32_t) strtoll(buf, &end, 0);
     375           0 :                         talloc_free(buf);
     376             : 
     377             :                         /* Set the last entry in the array to be NULL */
     378           0 :                         gplinks[idx + 1] = NULL;
     379             : 
     380             :                         /* Increment the array index, the string position past
     381             :                            the next "[LDAP://", and set the start reference */
     382           0 :                         idx++;
     383           0 :                         pos += strlen(gplink_start)+1;
     384           0 :                         start = pos;
     385             :                 }
     386             :         }
     387             : 
     388           0 :         *ret = gplinks;
     389           0 :         return NT_STATUS_OK;
     390             : }
     391             : 
     392             : 
     393           0 : NTSTATUS gp_get_gplinks(struct gp_context *gp_ctx, const char *dn_str, struct gp_link ***ret)
     394             : {
     395           0 :         TALLOC_CTX *mem_ctx;
     396           0 :         struct ldb_dn *dn;
     397           0 :         struct ldb_result *result;
     398           0 :         struct gp_link **gplinks;
     399           0 :         char *gplink_str;
     400           0 :         int rv;
     401           0 :         unsigned int i;
     402           0 :         NTSTATUS status;
     403             : 
     404             :         /* Create a forked memory context, as a base for everything here */
     405           0 :         mem_ctx = talloc_new(gp_ctx);
     406           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     407             : 
     408           0 :         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     409             : 
     410           0 :         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, NULL, "(objectclass=*)");
     411           0 :         if (rv != LDB_SUCCESS) {
     412           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     413           0 :                 talloc_free(mem_ctx);
     414           0 :                 return NT_STATUS_UNSUCCESSFUL;
     415             :         }
     416             : 
     417           0 :         for (i = 0; i < result->count; i++) {
     418           0 :                 struct ldb_message_element *element = \
     419           0 :                         ldb_msg_find_element(result->msgs[i], "gPLink");
     420           0 :                 if (element != NULL) {
     421           0 :                         SMB_ASSERT(element->num_values > 0);
     422           0 :                         gplink_str = talloc_strdup(
     423             :                                 mem_ctx,
     424           0 :                                 (char *) element->values[0].data);
     425           0 :                         if (gplink_str == NULL) {
     426           0 :                                 TALLOC_FREE(mem_ctx);
     427           0 :                                 return NT_STATUS_NO_MEMORY;
     428             :                         }
     429           0 :                         goto found;
     430             :                 }
     431             :         }
     432           0 :         gplink_str = talloc_strdup(mem_ctx, "");
     433           0 :         if (gplink_str == NULL) {
     434           0 :                 TALLOC_FREE(mem_ctx);
     435           0 :                 return NT_STATUS_NO_MEMORY;
     436             :         }
     437             : 
     438           0 :         found:
     439             : 
     440           0 :         status = parse_gplink(gp_ctx, gplink_str, &gplinks);
     441           0 :         if (!NT_STATUS_IS_OK(status)) {
     442           0 :                 DEBUG(0, ("Failed to parse gPLink\n"));
     443           0 :                 return status;
     444             :         }
     445             : 
     446           0 :         talloc_free(mem_ctx);
     447             : 
     448           0 :         *ret = gplinks;
     449           0 :         return NT_STATUS_OK;
     450             : }
     451             : 
     452           0 : NTSTATUS gp_list_gpos(struct gp_context *gp_ctx, struct security_token *token, const char ***ret)
     453             : {
     454           0 :         TALLOC_CTX *mem_ctx;
     455           0 :         const char **gpos;
     456           0 :         struct ldb_result *result;
     457           0 :         char *sid;
     458           0 :         struct ldb_dn *dn;
     459           0 :         struct ldb_message_element *element;
     460           0 :         bool inherit;
     461           0 :         const char *attrs[] = { "objectClass", NULL };
     462           0 :         int rv;
     463           0 :         NTSTATUS status;
     464           0 :         unsigned int count = 0;
     465           0 :         unsigned int i;
     466           0 :         enum {
     467             :                 ACCOUNT_TYPE_USER = 0,
     468             :                 ACCOUNT_TYPE_MACHINE = 1
     469             :         } account_type;
     470             : 
     471             :         /* Create a forked memory context, as a base for everything here */
     472           0 :         mem_ctx = talloc_new(gp_ctx);
     473           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     474             : 
     475           0 :         sid = ldap_encode_ndr_dom_sid(mem_ctx,
     476           0 :                                       &token->sids[PRIMARY_USER_SID_INDEX]);
     477           0 :         NT_STATUS_HAVE_NO_MEMORY(sid);
     478             : 
     479             :         /* Find the user DN and objectclass via the sid from the security token */
     480           0 :         rv = ldb_search(gp_ctx->ldb_ctx,
     481             :                         mem_ctx,
     482             :                         &result,
     483             :                         ldb_get_default_basedn(gp_ctx->ldb_ctx),
     484             :                         LDB_SCOPE_SUBTREE,
     485             :                         attrs,
     486             :                         "(&(objectclass=user)(objectSid=%s))", sid);
     487           0 :         if (rv != LDB_SUCCESS) {
     488           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
     489             :                                 ldb_errstring(gp_ctx->ldb_ctx)));
     490           0 :                 talloc_free(mem_ctx);
     491           0 :                 return NT_STATUS_UNSUCCESSFUL;
     492             :         }
     493           0 :         if (result->count != 1) {
     494           0 :                 DEBUG(0, ("Could not find user with sid %s.\n", sid));
     495           0 :                 talloc_free(mem_ctx);
     496           0 :                 return NT_STATUS_UNSUCCESSFUL;
     497             :         }
     498           0 :         DEBUG(10,("Found DN for this user: %s\n", ldb_dn_get_linearized(result->msgs[0]->dn)));
     499             : 
     500           0 :         element = ldb_msg_find_element(result->msgs[0], "objectClass");
     501             : 
     502             :         /* We need to know if this account is a user or machine. */
     503           0 :         account_type = ACCOUNT_TYPE_USER;
     504           0 :         for (i = 0; i < element->num_values; i++) {
     505           0 :                 if (strcmp((char *)element->values[i].data, "computer") == 0) {
     506           0 :                         account_type = ACCOUNT_TYPE_MACHINE;
     507           0 :                         DEBUG(10, ("This user is a machine\n"));
     508             :                 }
     509             :         }
     510             : 
     511           0 :         gpos = talloc_array(gp_ctx, const char *, 1);
     512           0 :         if (gpos == NULL) {
     513           0 :                 TALLOC_FREE(mem_ctx);
     514           0 :                 return NT_STATUS_NO_MEMORY;
     515             :         }
     516           0 :         gpos[0] = NULL;
     517             : 
     518             :         /* Walk through the containers until we hit the root */
     519           0 :         inherit = 1;
     520           0 :         dn = ldb_dn_get_parent(mem_ctx, result->msgs[0]->dn);
     521           0 :         while (ldb_dn_compare_base(ldb_get_default_basedn(gp_ctx->ldb_ctx), dn) == 0) {
     522           0 :                 const char *gpo_attrs[] = { "gPLink", "gPOptions", NULL };
     523           0 :                 struct gp_link **gplinks;
     524           0 :                 enum gpo_inheritance gpoptions;
     525             : 
     526           0 :                 DEBUG(10, ("Getting gPLinks for DN: %s\n", ldb_dn_get_linearized(dn)));
     527             : 
     528             :                 /* Get the gPLink and gPOptions attributes from the container */
     529           0 :                 rv = ldb_search(gp_ctx->ldb_ctx,
     530             :                                 mem_ctx,
     531             :                                 &result,
     532             :                                 dn,
     533             :                                 LDB_SCOPE_BASE,
     534             :                                 gpo_attrs,
     535             :                                 "objectclass=*");
     536           0 :                 if (rv != LDB_SUCCESS) {
     537           0 :                         DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv),
     538             :                                         ldb_errstring(gp_ctx->ldb_ctx)));
     539           0 :                         talloc_free(mem_ctx);
     540           0 :                         return NT_STATUS_UNSUCCESSFUL;
     541             :                 }
     542             : 
     543             :                 /* Parse the gPLink attribute, put it into a nice struct array */
     544           0 :                 status = parse_gplink(mem_ctx, ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", ""), &gplinks);
     545           0 :                 if (!NT_STATUS_IS_OK(status)) {
     546           0 :                         DEBUG(0, ("Failed to parse gPLink\n"));
     547           0 :                         talloc_free(mem_ctx);
     548           0 :                         return status;
     549             :                 }
     550             : 
     551             :                 /* Check all group policy links on this container */
     552           0 :                 for (i = 0; gplinks[i] != NULL; i++) {
     553           0 :                         struct gp_object *gpo;
     554           0 :                         uint32_t access_granted;
     555             : 
     556             :                         /* If inheritance was blocked at a higher level and this
     557             :                          * gplink is not enforced, it should not be applied */
     558           0 :                         if (!inherit && !(gplinks[i]->options & GPLINK_OPT_ENFORCE))
     559           0 :                                 continue;
     560             : 
     561             :                         /* Don't apply disabled links */
     562           0 :                         if (gplinks[i]->options & GPLINK_OPT_DISABLE)
     563           0 :                                 continue;
     564             : 
     565             :                         /* Get GPO information */
     566           0 :                         status = gp_get_gpo_info(gp_ctx, gplinks[i]->dn, &gpo);
     567           0 :                         if (!NT_STATUS_IS_OK(status)) {
     568           0 :                                 DEBUG(0, ("Failed to get gpo information for %s\n", gplinks[i]->dn));
     569           0 :                                 talloc_free(mem_ctx);
     570           0 :                                 return status;
     571             :                         }
     572             : 
     573             :                         /* If the account does not have read access, this GPO does not apply
     574             :                          * to this account */
     575           0 :                         status = se_access_check(gpo->security_descriptor,
     576             :                                         token,
     577             :                                         (SEC_STD_READ_CONTROL | SEC_ADS_LIST | SEC_ADS_READ_PROP),
     578             :                                         &access_granted);
     579           0 :                         if (!NT_STATUS_IS_OK(status)) {
     580           0 :                                 continue;
     581             :                         }
     582             : 
     583             :                         /* If the account is a user and the GPO has user disabled flag, or
     584             :                          * a machine and the GPO has machine disabled flag, this GPO does
     585             :                          * not apply to this account */
     586           0 :                         if ((account_type == ACCOUNT_TYPE_USER &&
     587           0 :                                         (gpo->flags & GPO_FLAG_USER_DISABLE)) ||
     588           0 :                                         (account_type == ACCOUNT_TYPE_MACHINE &&
     589           0 :                                         (gpo->flags & GPO_FLAG_MACHINE_DISABLE))) {
     590           0 :                                 continue;
     591             :                         }
     592             : 
     593             :                         /* Add the GPO to the list */
     594           0 :                         gpos = talloc_realloc(gp_ctx, gpos, const char *, count+2);
     595           0 :                         if (gpos == NULL) {
     596           0 :                                 TALLOC_FREE(mem_ctx);
     597           0 :                                 return NT_STATUS_NO_MEMORY;
     598             :                         }
     599           0 :                         gpos[count] = talloc_strdup(gp_ctx, gplinks[i]->dn);
     600           0 :                         if (gpos[count] == NULL) {
     601           0 :                                 TALLOC_FREE(mem_ctx);
     602           0 :                                 return NT_STATUS_NO_MEMORY;
     603             :                         }
     604           0 :                         gpos[count+1] = NULL;
     605           0 :                         count++;
     606             : 
     607             :                         /* Clean up */
     608           0 :                         talloc_free(gpo);
     609             :                 }
     610             : 
     611             :                 /* If inheritance is blocked, then we should only add enforced gPLinks
     612             :                  * higher up */
     613           0 :                 gpoptions = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
     614           0 :                 if (gpoptions == GPO_BLOCK_INHERITANCE) {
     615           0 :                         inherit = 0;
     616             :                 }
     617           0 :                 dn = ldb_dn_get_parent(mem_ctx, dn);
     618             :         }
     619             : 
     620           0 :         talloc_free(mem_ctx);
     621             : 
     622           0 :         *ret = gpos;
     623           0 :         return NT_STATUS_OK;
     624             : }
     625             : 
     626           0 : NTSTATUS gp_set_gplink(struct gp_context *gp_ctx, const char *dn_str, struct gp_link *gplink)
     627             : {
     628           0 :         TALLOC_CTX *mem_ctx;
     629           0 :         struct ldb_result *result;
     630           0 :         struct ldb_dn *dn;
     631           0 :         struct ldb_message *msg;
     632           0 :         const char *attrs[] = { "gPLink", NULL };
     633           0 :         const char *gplink_str;
     634           0 :         int rv;
     635           0 :         char *start;
     636             : 
     637             :         /* Create a forked memory context, as a base for everything here */
     638           0 :         mem_ctx = talloc_new(gp_ctx);
     639           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     640             : 
     641           0 :         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     642             : 
     643           0 :         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
     644           0 :         if (rv != LDB_SUCCESS) {
     645           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     646           0 :                 talloc_free(mem_ctx);
     647           0 :                 return NT_STATUS_UNSUCCESSFUL;
     648             :         }
     649             : 
     650           0 :         if (result->count != 1) {
     651           0 :                 talloc_free(mem_ctx);
     652           0 :                 return NT_STATUS_NOT_FOUND;
     653             :         }
     654             : 
     655           0 :         gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
     656             : 
     657             :         /* If this GPO link already exists, alter the options, else add it */
     658           0 :         if ((start = strcasestr(gplink_str, gplink->dn)) != NULL) {
     659           0 :                 start += strlen(gplink->dn);
     660           0 :                 *start = '\0';
     661           0 :                 start++;
     662           0 :                 while (*start != ']' && *start != '\0') {
     663           0 :                         start++;
     664             :                 }
     665           0 :                 gplink_str = talloc_asprintf(mem_ctx, "%s;%d%s", gplink_str, gplink->options, start);
     666           0 :                 if (gplink_str == NULL) {
     667           0 :                         TALLOC_FREE(mem_ctx);
     668           0 :                         return NT_STATUS_NO_MEMORY;
     669             :                 }
     670             : 
     671             :         } else {
     672             :                 /* Prepend the new GPO link to the string. This list is backwards in priority. */
     673           0 :                 gplink_str = talloc_asprintf(mem_ctx, "[LDAP://%s;%d]%s", gplink->dn, gplink->options, gplink_str);
     674           0 :                 if (gplink_str == NULL) {
     675           0 :                         TALLOC_FREE(mem_ctx);
     676           0 :                         return NT_STATUS_NO_MEMORY;
     677             :                 }
     678             :         }
     679             : 
     680             : 
     681             : 
     682           0 :         msg = ldb_msg_new(mem_ctx);
     683           0 :         if (msg == NULL) {
     684           0 :                 TALLOC_FREE(mem_ctx);
     685           0 :                 return NT_STATUS_NO_MEMORY;
     686             :         }
     687             : 
     688           0 :         msg->dn = dn;
     689             : 
     690           0 :         rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
     691           0 :         if (rv != LDB_SUCCESS) {
     692           0 :                 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
     693           0 :                 talloc_free(mem_ctx);
     694           0 :                 return NT_STATUS_UNSUCCESSFUL;
     695             :         }
     696           0 :         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
     697             : 
     698           0 :         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
     699           0 :         if (rv != LDB_SUCCESS) {
     700           0 :                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
     701           0 :                 talloc_free(mem_ctx);
     702           0 :                 return NT_STATUS_UNSUCCESSFUL;
     703             :         }
     704             : 
     705           0 :         talloc_free(mem_ctx);
     706           0 :         return NT_STATUS_OK;
     707             : }
     708             : 
     709           0 : NTSTATUS gp_del_gplink(struct gp_context *gp_ctx, const char *dn_str, const char *gplink_dn)
     710             : {
     711           0 :         TALLOC_CTX *mem_ctx;
     712           0 :         struct ldb_result *result;
     713           0 :         struct ldb_dn *dn;
     714           0 :         struct ldb_message *msg;
     715           0 :         const char *attrs[] = { "gPLink", NULL };
     716           0 :         const char *gplink_str, *search_string;
     717           0 :         int rv;
     718           0 :         char *p;
     719             : 
     720             :         /* Create a forked memory context, as a base for everything here */
     721           0 :         mem_ctx = talloc_new(gp_ctx);
     722           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     723             : 
     724           0 :         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     725             : 
     726           0 :         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
     727           0 :         if (rv != LDB_SUCCESS) {
     728           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     729           0 :                 talloc_free(mem_ctx);
     730           0 :                 return NT_STATUS_UNSUCCESSFUL;
     731             :         }
     732             : 
     733           0 :         if (result->count != 1) {
     734           0 :                 talloc_free(mem_ctx);
     735           0 :                 return NT_STATUS_NOT_FOUND;
     736             :         }
     737             : 
     738           0 :         gplink_str = ldb_msg_find_attr_as_string(result->msgs[0], "gPLink", "");
     739             : 
     740             :         /* If this GPO link already exists, alter the options, else add it */
     741           0 :         search_string = talloc_asprintf(mem_ctx, "[LDAP://%s]", gplink_dn);
     742           0 :         if (search_string == NULL) {
     743           0 :                 TALLOC_FREE(mem_ctx);
     744           0 :                 return NT_STATUS_NO_MEMORY;
     745             :         }
     746             : 
     747           0 :         p = strcasestr(gplink_str, search_string);
     748           0 :         if (p == NULL) {
     749           0 :                 talloc_free(mem_ctx);
     750           0 :                 return NT_STATUS_NOT_FOUND;
     751             :         }
     752             : 
     753           0 :         *p = '\0';
     754           0 :         p++;
     755           0 :         while (*p != ']' && *p != '\0') {
     756           0 :                 p++;
     757             :         }
     758           0 :         p++;
     759           0 :         gplink_str = talloc_asprintf(mem_ctx, "%s%s", gplink_str, p);
     760           0 :         if (gplink_str == NULL) {
     761           0 :                 TALLOC_FREE(mem_ctx);
     762           0 :                 return NT_STATUS_NO_MEMORY;
     763             :         }
     764             : 
     765             : 
     766           0 :         msg = ldb_msg_new(mem_ctx);
     767           0 :         if (msg == NULL) {
     768           0 :                 TALLOC_FREE(mem_ctx);
     769           0 :                 return NT_STATUS_NO_MEMORY;
     770             :         }
     771             : 
     772           0 :         msg->dn = dn;
     773             : 
     774           0 :         if (strcmp(gplink_str, "") == 0) {
     775           0 :                 rv = ldb_msg_add_empty(msg, "gPLink", LDB_FLAG_MOD_DELETE, NULL);
     776           0 :                 if (rv != LDB_SUCCESS) {
     777           0 :                         DEBUG(0, ("LDB message add empty element failed: %s\n", ldb_strerror(rv)));
     778           0 :                         talloc_free(mem_ctx);
     779           0 :                         return NT_STATUS_UNSUCCESSFUL;
     780             :                 }
     781             :         } else {
     782           0 :                 rv = ldb_msg_add_string(msg, "gPLink", gplink_str);
     783           0 :                 if (rv != LDB_SUCCESS) {
     784           0 :                         DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
     785           0 :                         talloc_free(mem_ctx);
     786           0 :                         return NT_STATUS_UNSUCCESSFUL;
     787             :                 }
     788           0 :                 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
     789             :         }
     790           0 :         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
     791           0 :         if (rv != LDB_SUCCESS) {
     792           0 :                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
     793           0 :                 talloc_free(mem_ctx);
     794           0 :                 return NT_STATUS_UNSUCCESSFUL;
     795             :         }
     796             : 
     797           0 :         talloc_free(mem_ctx);
     798           0 :         return NT_STATUS_OK;
     799             : }
     800             : 
     801           0 : NTSTATUS gp_get_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance *inheritance)
     802             : {
     803           0 :         TALLOC_CTX *mem_ctx;
     804           0 :         struct ldb_result *result;
     805           0 :         struct ldb_dn *dn;
     806           0 :         const char *attrs[] = { "gPOptions", NULL };
     807           0 :         int rv;
     808             : 
     809             :         /* Create a forked memory context, as a base for everything here */
     810           0 :         mem_ctx = talloc_new(gp_ctx);
     811           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     812             : 
     813           0 :         dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     814             : 
     815           0 :         rv = ldb_search(gp_ctx->ldb_ctx, mem_ctx, &result, dn, LDB_SCOPE_BASE, attrs, "(objectclass=*)");
     816           0 :         if (rv != LDB_SUCCESS) {
     817           0 :                 DEBUG(0, ("LDB search failed: %s\n%s\n", ldb_strerror(rv), ldb_errstring(gp_ctx->ldb_ctx)));
     818           0 :                 talloc_free(mem_ctx);
     819           0 :                 return NT_STATUS_UNSUCCESSFUL;
     820             :         }
     821             : 
     822           0 :         if (result->count != 1) {
     823           0 :                 talloc_free(mem_ctx);
     824           0 :                 return NT_STATUS_NOT_FOUND;
     825             :         }
     826             : 
     827           0 :         *inheritance = ldb_msg_find_attr_as_uint(result->msgs[0], "gPOptions", 0);
     828             : 
     829           0 :         talloc_free(mem_ctx);
     830           0 :         return NT_STATUS_OK;
     831             : }
     832             : 
     833           0 : NTSTATUS gp_set_inheritance(struct gp_context *gp_ctx, const char *dn_str, enum gpo_inheritance inheritance)
     834             : {
     835           0 :         char *inheritance_string;
     836           0 :         struct ldb_message *msg;
     837           0 :         int rv;
     838             : 
     839           0 :         msg = ldb_msg_new(gp_ctx);
     840           0 :         NT_STATUS_HAVE_NO_MEMORY(msg);
     841             : 
     842           0 :         msg->dn = ldb_dn_new(msg, gp_ctx->ldb_ctx, dn_str);
     843             : 
     844           0 :         inheritance_string = talloc_asprintf(msg, "%d", inheritance);
     845           0 :         if (inheritance_string == NULL) {
     846           0 :                 TALLOC_FREE(msg);
     847           0 :                 return NT_STATUS_NO_MEMORY;
     848             :         }
     849             : 
     850           0 :         rv = ldb_msg_add_string(msg, "gPOptions", inheritance_string);
     851           0 :         if (rv != LDB_SUCCESS) {
     852           0 :                 DEBUG(0, ("LDB message add string failed: %s\n", ldb_strerror(rv)));
     853           0 :                 talloc_free(msg);
     854           0 :                 return NT_STATUS_UNSUCCESSFUL;
     855             :         }
     856           0 :         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
     857             : 
     858           0 :         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
     859           0 :         if (rv != LDB_SUCCESS) {
     860           0 :                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
     861           0 :                 talloc_free(msg);
     862           0 :                 return NT_STATUS_UNSUCCESSFUL;
     863             :         }
     864             : 
     865           0 :         talloc_free(msg);
     866           0 :         return NT_STATUS_OK;
     867             : }
     868             : 
     869           0 : NTSTATUS gp_create_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
     870             : {
     871           0 :         struct ldb_message *msg;
     872           0 :         TALLOC_CTX *mem_ctx;
     873           0 :         int rv;
     874           0 :         char *dn_str, *flags_str, *version_str;
     875           0 :         struct ldb_dn *child_dn, *gpo_dn;
     876             : 
     877           0 :         mem_ctx = talloc_new(gp_ctx);
     878           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
     879             : 
     880             :         /* CN={GUID} */
     881           0 :         msg = ldb_msg_new(mem_ctx);
     882           0 :         if (msg == NULL) {
     883           0 :                 TALLOC_FREE(mem_ctx);
     884           0 :                 return NT_STATUS_NO_MEMORY;
     885             :         }
     886             : 
     887           0 :         msg->dn = ldb_get_default_basedn(gp_ctx->ldb_ctx);
     888           0 :         dn_str = talloc_asprintf(mem_ctx, "CN=%s,CN=Policies,CN=System", gpo->name);
     889           0 :         if (dn_str == NULL) {
     890           0 :                 TALLOC_FREE(mem_ctx);
     891           0 :                 return NT_STATUS_NO_MEMORY;
     892             :         }
     893             : 
     894           0 :         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
     895           0 :         rv = ldb_dn_add_child(msg->dn, child_dn);
     896           0 :         if (!rv) goto ldb_msg_add_error;
     897             : 
     898           0 :         flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
     899           0 :         if (flags_str == NULL) {
     900           0 :                 TALLOC_FREE(mem_ctx);
     901           0 :                 return NT_STATUS_NO_MEMORY;
     902             :         }
     903             : 
     904           0 :         version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
     905           0 :         if (version_str == NULL) {
     906           0 :                 TALLOC_FREE(mem_ctx);
     907           0 :                 return NT_STATUS_NO_MEMORY;
     908             :         }
     909             : 
     910           0 :         rv = ldb_msg_add_string(msg, "objectClass", "top");
     911           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     912           0 :         rv = ldb_msg_add_string(msg, "objectClass", "container");
     913           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     914           0 :         rv = ldb_msg_add_string(msg, "objectClass", "groupPolicyContainer");
     915           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     916           0 :         rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
     917           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     918           0 :         rv = ldb_msg_add_string(msg, "name", gpo->name);
     919           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     920           0 :         rv = ldb_msg_add_string(msg, "CN", gpo->name);
     921           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     922           0 :         rv = ldb_msg_add_string(msg, "gPCFileSysPath", gpo->file_sys_path);
     923           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     924           0 :         rv = ldb_msg_add_string(msg, "flags", flags_str);
     925           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     926           0 :         rv = ldb_msg_add_string(msg, "versionNumber", version_str);
     927           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     928           0 :         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
     929           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     930           0 :         rv = ldb_msg_add_string(msg, "gpCFunctionalityVersion", "2");
     931           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     932             : 
     933           0 :         rv = ldb_add(gp_ctx->ldb_ctx, msg);
     934           0 :         if (rv != LDB_SUCCESS) {
     935           0 :                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
     936           0 :                 talloc_free(mem_ctx);
     937           0 :                 return NT_STATUS_UNSUCCESSFUL;
     938             :         }
     939             : 
     940           0 :         gpo_dn = msg->dn;
     941             : 
     942             :         /* CN=User */
     943           0 :         msg = ldb_msg_new(mem_ctx);
     944           0 :         if (msg == NULL) {
     945           0 :                 TALLOC_FREE(mem_ctx);
     946           0 :                 return NT_STATUS_NO_MEMORY;
     947             :         }
     948             : 
     949           0 :         msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
     950           0 :         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=User");
     951           0 :         rv = ldb_dn_add_child(msg->dn, child_dn);
     952           0 :         if (!rv) goto ldb_msg_add_error;
     953             : 
     954           0 :         rv = ldb_msg_add_string(msg, "objectClass", "top");
     955           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     956           0 :         rv = ldb_msg_add_string(msg, "objectClass", "container");
     957           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     958           0 :         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
     959           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     960           0 :         rv = ldb_msg_add_string(msg, "CN", "User");
     961           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     962           0 :         rv = ldb_msg_add_string(msg, "name", "User");
     963           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     964             : 
     965           0 :         rv = ldb_add(gp_ctx->ldb_ctx, msg);
     966           0 :         if (rv != LDB_SUCCESS) {
     967           0 :                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
     968           0 :                 talloc_free(mem_ctx);
     969           0 :                 return NT_STATUS_UNSUCCESSFUL;
     970             :         }
     971             : 
     972             :         /* CN=Machine */
     973           0 :         msg = ldb_msg_new(mem_ctx);
     974           0 :         if (msg == NULL) {
     975           0 :                 TALLOC_FREE(mem_ctx);
     976           0 :                 return NT_STATUS_NO_MEMORY;
     977             :         }
     978             : 
     979           0 :         msg->dn = ldb_dn_copy(mem_ctx, gpo_dn);
     980           0 :         child_dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, "CN=Machine");
     981           0 :         rv = ldb_dn_add_child(msg->dn, child_dn);
     982           0 :         if (!rv) goto ldb_msg_add_error;
     983             : 
     984           0 :         rv = ldb_msg_add_string(msg, "objectClass", "top");
     985           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     986           0 :         rv = ldb_msg_add_string(msg, "objectClass", "container");
     987           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     988           0 :         rv = ldb_msg_add_string(msg, "showInAdvancedViewOnly", "TRUE");
     989           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     990           0 :         rv = ldb_msg_add_string(msg, "CN", "Machine");
     991           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     992           0 :         rv = ldb_msg_add_string(msg, "name", "Machine");
     993           0 :         if (rv != LDB_SUCCESS) goto ldb_msg_add_error;
     994             : 
     995           0 :         rv = ldb_add(gp_ctx->ldb_ctx, msg);
     996           0 :         if (rv != LDB_SUCCESS) {
     997           0 :                 DEBUG(0, ("LDB add error: %s\n", ldb_errstring(gp_ctx->ldb_ctx)));
     998           0 :                 talloc_free(mem_ctx);
     999           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1000             :         }
    1001             : 
    1002           0 :         gpo->dn = talloc_strdup(gpo, ldb_dn_get_linearized(gpo_dn));
    1003           0 :         if (gpo->dn == NULL) {
    1004           0 :                 TALLOC_FREE(mem_ctx);
    1005           0 :                 return NT_STATUS_NO_MEMORY;
    1006             :         }
    1007             : 
    1008           0 :         talloc_free(mem_ctx);
    1009           0 :         return NT_STATUS_OK;
    1010             : 
    1011           0 :         ldb_msg_add_error:
    1012           0 :         DEBUG(0, ("LDB Error adding element to ldb message\n"));
    1013           0 :         talloc_free(mem_ctx);
    1014           0 :         return NT_STATUS_UNSUCCESSFUL;
    1015             : }
    1016             : 
    1017           0 : NTSTATUS gp_set_ads_acl (struct gp_context *gp_ctx, const char *dn_str, const struct security_descriptor *sd)
    1018             : {
    1019           0 :         TALLOC_CTX *mem_ctx;
    1020           0 :         DATA_BLOB data;
    1021           0 :         enum ndr_err_code ndr_err;
    1022           0 :         struct ldb_message *msg;
    1023           0 :         int rv;
    1024             : 
    1025             :         /* Create a forked memory context to clean up easily */
    1026           0 :         mem_ctx = talloc_new(gp_ctx);
    1027           0 :         NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
    1028             : 
    1029             :         /* Push the security descriptor through the NDR library */
    1030           0 :         ndr_err = ndr_push_struct_blob(&data,
    1031             :                         mem_ctx,
    1032             :                         sd,
    1033             :                         (ndr_push_flags_fn_t)ndr_push_security_descriptor);
    1034           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1035           0 :                 return ndr_map_error2ntstatus(ndr_err);
    1036             :         }
    1037             : 
    1038             : 
    1039             :         /* Create a LDB message */
    1040           0 :         msg = ldb_msg_new(mem_ctx);
    1041           0 :         if (msg == NULL) {
    1042           0 :                 TALLOC_FREE(mem_ctx);
    1043           0 :                 return NT_STATUS_NO_MEMORY;
    1044             :         }
    1045             : 
    1046           0 :         msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, dn_str);
    1047             : 
    1048           0 :         rv = ldb_msg_add_value(msg, "nTSecurityDescriptor", &data, NULL);
    1049           0 :         if (rv != LDB_SUCCESS) {
    1050           0 :                 DEBUG(0, ("LDB message add element failed for adding nTSecurityDescriptor: %s\n", ldb_strerror(rv)));
    1051           0 :                 talloc_free(mem_ctx);
    1052           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1053             :         }
    1054           0 :         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
    1055             : 
    1056           0 :         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
    1057           0 :         if (rv != LDB_SUCCESS) {
    1058           0 :                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
    1059           0 :                 talloc_free(mem_ctx);
    1060           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1061             :         }
    1062             : 
    1063           0 :         talloc_free(mem_ctx);
    1064           0 :         return NT_STATUS_OK;
    1065             : }
    1066             : 
    1067             : /* This function sets flags, version and displayName on a GPO */
    1068           0 : NTSTATUS gp_set_ldap_gpo(struct gp_context *gp_ctx, struct gp_object *gpo)
    1069             : {
    1070           0 :         int rv;
    1071           0 :         TALLOC_CTX *mem_ctx;
    1072           0 :         struct ldb_message *msg;
    1073           0 :         char *version_str, *flags_str;
    1074             : 
    1075           0 :         mem_ctx = talloc_new(gp_ctx);
    1076             : 
    1077           0 :         msg = ldb_msg_new(mem_ctx);
    1078           0 :         if (msg == NULL) {
    1079           0 :                 TALLOC_FREE(mem_ctx);
    1080           0 :                 return NT_STATUS_NO_MEMORY;
    1081             :         }
    1082             : 
    1083           0 :         msg->dn = ldb_dn_new(mem_ctx, gp_ctx->ldb_ctx, gpo->dn);
    1084             : 
    1085           0 :         version_str = talloc_asprintf(mem_ctx, "%d", gpo->version);
    1086           0 :         if (msg == NULL) {
    1087           0 :                 TALLOC_FREE(mem_ctx);
    1088           0 :                 return NT_STATUS_NO_MEMORY;
    1089             :         }
    1090             : 
    1091           0 :         flags_str = talloc_asprintf(mem_ctx, "%d", gpo->flags);
    1092           0 :         if (msg == NULL) {
    1093           0 :                 TALLOC_FREE(mem_ctx);
    1094           0 :                 return NT_STATUS_NO_MEMORY;
    1095             :         }
    1096             : 
    1097           0 :         rv = ldb_msg_add_string(msg, "flags", flags_str);
    1098           0 :         if (rv != LDB_SUCCESS) {
    1099           0 :                 DEBUG(0, ("LDB message add string failed for flags: %s\n", ldb_strerror(rv)));
    1100           0 :                 talloc_free(mem_ctx);
    1101           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1102             :         }
    1103           0 :         msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
    1104             : 
    1105           0 :         rv = ldb_msg_add_string(msg, "version", version_str);
    1106           0 :         if (rv != LDB_SUCCESS) {
    1107           0 :                 DEBUG(0, ("LDB message add string failed for version: %s\n", ldb_strerror(rv)));
    1108           0 :                 talloc_free(mem_ctx);
    1109           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1110             :         }
    1111           0 :         msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
    1112             : 
    1113           0 :         rv = ldb_msg_add_string(msg, "displayName", gpo->display_name);
    1114           0 :         if (rv != LDB_SUCCESS) {
    1115           0 :                 DEBUG(0, ("LDB message add string failed for displayName: %s\n", ldb_strerror(rv)));
    1116           0 :                 talloc_free(mem_ctx);
    1117           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1118             :         }
    1119           0 :         msg->elements[2].flags = LDB_FLAG_MOD_REPLACE;
    1120             : 
    1121           0 :         rv = ldb_modify(gp_ctx->ldb_ctx, msg);
    1122           0 :         if (rv != LDB_SUCCESS) {
    1123           0 :                 DEBUG(0, ("LDB modify failed: %s\n", ldb_strerror(rv)));
    1124           0 :                 talloc_free(mem_ctx);
    1125           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1126             :         }
    1127             : 
    1128           0 :         talloc_free(mem_ctx);
    1129           0 :         return NT_STATUS_OK;
    1130             : }

Generated by: LCOV version 1.14