LCOV - code coverage report
Current view: top level - source4/dsdb/common - util_samr.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 175 290 60.3 %
Date: 2021-09-23 10:06:22 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Helpers to add users and groups to the DB
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2004
       7             :    Copyright (C) Volker Lendecke 2004
       8             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2010
       9             :    Copyright (C) Matthias Dieter Wallnöfer 2009
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "includes.h"
      26             : #include "dsdb/samdb/samdb.h"
      27             : #include "dsdb/common/util.h"
      28             : #include "../libds/common/flags.h"
      29             : #include "libcli/security/security.h"
      30             : 
      31             : #include "libds/common/flag_mapping.h"
      32             : 
      33             : /* Add a user, SAMR style, including the correct transaction
      34             :  * semantics.  Used by the SAMR server and by pdb_samba4 */
      35        1465 : NTSTATUS dsdb_add_user(struct ldb_context *ldb,
      36             :                        TALLOC_CTX *mem_ctx,
      37             :                        const char *account_name,
      38             :                        uint32_t acct_flags,
      39             :                        const struct dom_sid *forced_sid,
      40             :                        struct dom_sid **sid,
      41             :                        struct ldb_dn **dn)
      42             : {
      43             :         const char *name;
      44             :         struct ldb_message *msg;
      45             :         int ret;
      46        1465 :         const char *container, *obj_class=NULL;
      47             :         char *cn_name;
      48             :         size_t cn_name_len;
      49             : 
      50        1465 :         const char *attrs[] = {
      51             :                 "objectSid",
      52             :                 "userAccountControl",
      53             :                 NULL
      54             :         };
      55             : 
      56             :         uint32_t user_account_control;
      57             :         struct ldb_dn *account_dn;
      58             :         struct dom_sid *account_sid;
      59             : 
      60        1465 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      61        1465 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
      62             : 
      63             :         /*
      64             :          * Start a transaction, so we can query and do a subsequent atomic
      65             :          * modify
      66             :          */
      67             : 
      68        1465 :         ret = ldb_transaction_start(ldb);
      69        1465 :         if (ret != LDB_SUCCESS) {
      70           0 :                 DEBUG(0,("Failed to start a transaction for user creation: %s\n",
      71             :                          ldb_errstring(ldb)));
      72           0 :                 talloc_free(tmp_ctx);
      73           0 :                 return NT_STATUS_LOCK_NOT_GRANTED;
      74             :         }
      75             : 
      76             :         /* check if the user already exists */
      77        1465 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
      78             :                                    "sAMAccountName",
      79             :                                    "(&(sAMAccountName=%s)(objectclass=user))",
      80             :                                    ldb_binary_encode_string(tmp_ctx, account_name));
      81        1465 :         if (name != NULL) {
      82          10 :                 ldb_transaction_cancel(ldb);
      83          10 :                 talloc_free(tmp_ctx);
      84          10 :                 return NT_STATUS_USER_EXISTS;
      85             :         }
      86             : 
      87        1455 :         cn_name = talloc_strdup(tmp_ctx, account_name);
      88        1455 :         if (!cn_name) {
      89           0 :                 ldb_transaction_cancel(ldb);
      90           0 :                 talloc_free(tmp_ctx);
      91           0 :                 return NT_STATUS_NO_MEMORY;
      92             :         }
      93             : 
      94        1455 :         cn_name_len = strlen(cn_name);
      95        1455 :         if (cn_name_len < 1) {
      96           0 :                 ldb_transaction_cancel(ldb);
      97           0 :                 talloc_free(tmp_ctx);
      98           0 :                 return NT_STATUS_INVALID_PARAMETER;
      99             :         }
     100             : 
     101        1455 :         msg = ldb_msg_new(tmp_ctx);
     102        1455 :         if (msg == NULL) {
     103           0 :                 ldb_transaction_cancel(ldb);
     104           0 :                 talloc_free(tmp_ctx);
     105           0 :                 return NT_STATUS_NO_MEMORY;
     106             :         }
     107             : 
     108             :         /* This must be one of these values *only* */
     109        1455 :         if (acct_flags == ACB_NORMAL) {
     110         831 :                 container = "CN=Users";
     111         831 :                 obj_class = "user";
     112         831 :                 user_account_control = UF_NORMAL_ACCOUNT;
     113         618 :         } else if (acct_flags == ACB_WSTRUST) {
     114         283 :                 if (cn_name[cn_name_len - 1] != '$') {
     115           0 :                         ldb_transaction_cancel(ldb);
     116           0 :                         return NT_STATUS_FOOBAR;
     117             :                 }
     118         283 :                 cn_name[cn_name_len - 1] = '\0';
     119         283 :                 container = "CN=Computers";
     120         283 :                 obj_class = "computer";
     121         283 :                 user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
     122             : 
     123         335 :         } else if (acct_flags == ACB_SVRTRUST) {
     124         255 :                 if (cn_name[cn_name_len - 1] != '$') {
     125           0 :                         ldb_transaction_cancel(ldb);
     126           0 :                         return NT_STATUS_FOOBAR;
     127             :                 }
     128         255 :                 cn_name[cn_name_len - 1] = '\0';
     129         255 :                 container = "OU=Domain Controllers";
     130         255 :                 obj_class = "computer";
     131         255 :                 user_account_control = UF_SERVER_TRUST_ACCOUNT;
     132          80 :         } else if (acct_flags == ACB_DOMTRUST) {
     133           0 :                 DEBUG(3, ("Invalid account flags specified:  cannot create domain trusts via this interface (must use LSA CreateTrustedDomain calls\n"));
     134           0 :                 ldb_transaction_cancel(ldb);
     135           0 :                 talloc_free(tmp_ctx);
     136           0 :                 return NT_STATUS_INVALID_PARAMETER;
     137             :         } else {
     138          80 :                 DEBUG(3, ("Invalid account flags specified 0x%08X, must be exactly one of \n"
     139             :                           "ACB_NORMAL (0x%08X) ACB_WSTRUST (0x%08X) or ACB_SVRTRUST (0x%08X)\n",
     140             :                           acct_flags,
     141             :                           ACB_NORMAL, ACB_WSTRUST, ACB_SVRTRUST));
     142          80 :                 ldb_transaction_cancel(ldb);
     143          80 :                 talloc_free(tmp_ctx);
     144          80 :                 return NT_STATUS_INVALID_PARAMETER;
     145             :         }
     146             : 
     147        1375 :         user_account_control |= UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD;
     148             : 
     149             :         /* add core elements to the ldb_message for the user */
     150        1375 :         msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb));
     151        1375 :         if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
     152           0 :                 ldb_transaction_cancel(ldb);
     153           0 :                 talloc_free(tmp_ctx);
     154           0 :                 return NT_STATUS_FOOBAR;
     155             :         }
     156             : 
     157        1375 :         ret = ldb_msg_add_string(msg, "sAMAccountName", account_name);
     158        1375 :         if (ret != LDB_SUCCESS) {
     159           0 :                 goto failed;
     160             :         }
     161        1375 :         ret = ldb_msg_add_string(msg, "objectClass", obj_class);
     162        1375 :         if (ret != LDB_SUCCESS) {
     163           0 :                 goto failed;
     164             :         }
     165        1375 :         ret = samdb_msg_add_uint(ldb, tmp_ctx, msg,
     166             :                                  "userAccountControl",
     167             :                                  user_account_control);
     168        1375 :         if (ret != LDB_SUCCESS) {
     169           0 :                 goto failed;
     170             :         }
     171             : 
     172             :         /* This is only here for migrations using pdb_samba4, the
     173             :          * caller and the samldb are responsible for ensuring it makes
     174             :          * sense */
     175        1375 :         if (forced_sid) {
     176           7 :                 ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid);
     177           7 :                 if (ret != LDB_SUCCESS) {
     178           0 :                         ldb_transaction_cancel(ldb);
     179           0 :                         talloc_free(tmp_ctx);
     180           0 :                         return NT_STATUS_INTERNAL_ERROR;
     181             :                 }
     182             :         }
     183             : 
     184             :         /* create the user */
     185        1375 :         ret = ldb_add(ldb, msg);
     186        1375 :         switch (ret) {
     187        1292 :         case LDB_SUCCESS:
     188        1292 :                 break;
     189           0 :         case LDB_ERR_ENTRY_ALREADY_EXISTS:
     190           0 :                 ldb_transaction_cancel(ldb);
     191           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     192             :                          ldb_dn_get_linearized(msg->dn),
     193             :                          ldb_errstring(ldb)));
     194           0 :                 talloc_free(tmp_ctx);
     195           1 :                 return NT_STATUS_USER_EXISTS;
     196           5 :         case LDB_ERR_UNWILLING_TO_PERFORM:
     197             :         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     198           5 :                 ldb_transaction_cancel(ldb);
     199           5 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     200             :                          ldb_dn_get_linearized(msg->dn),
     201             :                          ldb_errstring(ldb)));
     202           5 :                 talloc_free(tmp_ctx);
     203           5 :                 return NT_STATUS_ACCESS_DENIED;
     204           0 :         default:
     205           0 :                 ldb_transaction_cancel(ldb);
     206           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     207             :                          ldb_dn_get_linearized(msg->dn),
     208             :                          ldb_errstring(ldb)));
     209           0 :                 talloc_free(tmp_ctx);
     210           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     211             :         }
     212             : 
     213        1370 :         account_dn = msg->dn;
     214             : 
     215             :         /* retrieve the sid and account control bits for the user just created */
     216        1370 :         ret = dsdb_search_one(ldb, tmp_ctx, &msg,
     217             :                               account_dn, LDB_SCOPE_BASE, attrs, 0, NULL);
     218             : 
     219        1370 :         if (ret != LDB_SUCCESS) {
     220           0 :                 ldb_transaction_cancel(ldb);
     221           0 :                 DEBUG(0,("Can't locate the account we just created %s: %s\n",
     222             :                          ldb_dn_get_linearized(account_dn), ldb_errstring(ldb)));
     223           0 :                 talloc_free(tmp_ctx);
     224           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     225             :         }
     226        1370 :         account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
     227        1370 :         if (account_sid == NULL) {
     228           0 :                 ldb_transaction_cancel(ldb);
     229           0 :                 DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n",
     230             :                          ldb_dn_get_linearized(msg->dn)));
     231           0 :                 talloc_free(tmp_ctx);
     232           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     233             :         }
     234             : 
     235        1370 :         ret = ldb_transaction_commit(ldb);
     236        1370 :         if (ret != LDB_SUCCESS) {
     237           0 :                 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
     238             :                          ldb_dn_get_linearized(msg->dn),
     239             :                          ldb_errstring(ldb)));
     240           0 :                 talloc_free(tmp_ctx);
     241           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     242             :         }
     243        1370 :         *dn = talloc_steal(mem_ctx, account_dn);
     244        1370 :         if (sid) {
     245        1363 :                 *sid = talloc_steal(mem_ctx, account_sid);
     246             :         }
     247        1370 :         talloc_free(tmp_ctx);
     248        1370 :         return NT_STATUS_OK;
     249             : 
     250           0 :   failed:
     251           0 :         ldb_transaction_cancel(ldb);
     252           0 :         talloc_free(tmp_ctx);
     253           0 :         return NT_STATUS_INTERNAL_ERROR;
     254             : }
     255             : 
     256             : /*
     257             :   called by samr_CreateDomainGroup and pdb_samba4
     258             : */
     259         831 : NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb,
     260             :                                TALLOC_CTX *mem_ctx,
     261             :                                const char *groupname,
     262             :                                struct dom_sid **sid,
     263             :                                struct ldb_dn **dn)
     264             : {
     265             :         const char *name;
     266             :         struct ldb_message *msg;
     267             :         struct dom_sid *group_sid;
     268             :         int ret;
     269             : 
     270         831 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     271         831 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     272             : 
     273             :         /* check if the group already exists */
     274         831 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
     275             :                                    "sAMAccountName",
     276             :                                    "(&(sAMAccountName=%s)(objectclass=group))",
     277             :                                    ldb_binary_encode_string(tmp_ctx, groupname));
     278         831 :         if (name != NULL) {
     279           1 :                 return NT_STATUS_GROUP_EXISTS;
     280             :         }
     281             : 
     282         830 :         msg = ldb_msg_new(tmp_ctx);
     283         830 :         if (msg == NULL) {
     284           0 :                 return NT_STATUS_NO_MEMORY;
     285             :         }
     286             : 
     287             :         /* add core elements to the ldb_message for the user */
     288         830 :         msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb));
     289         830 :         ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
     290         830 :         if (!msg->dn) {
     291           0 :                 talloc_free(tmp_ctx);
     292           0 :                 return NT_STATUS_NO_MEMORY;
     293             :         }
     294         830 :         ldb_msg_add_string(msg, "sAMAccountName", groupname);
     295         830 :         ldb_msg_add_string(msg, "objectClass", "group");
     296             : 
     297             :         /* create the group */
     298         830 :         ret = ldb_add(ldb, msg);
     299         830 :         switch (ret) {
     300         830 :         case  LDB_SUCCESS:
     301         830 :                 break;
     302           0 :         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
     303           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     304             :                          ldb_dn_get_linearized(msg->dn),
     305             :                          ldb_errstring(ldb)));
     306           0 :                 talloc_free(tmp_ctx);
     307           0 :                 return NT_STATUS_GROUP_EXISTS;
     308           0 :         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     309           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     310             :                          ldb_dn_get_linearized(msg->dn),
     311             :                          ldb_errstring(ldb)));
     312           0 :                 talloc_free(tmp_ctx);
     313           0 :                 return NT_STATUS_ACCESS_DENIED;
     314           0 :         default:
     315           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     316             :                          ldb_dn_get_linearized(msg->dn),
     317             :                          ldb_errstring(ldb)));
     318           0 :                 talloc_free(tmp_ctx);
     319           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     320             :         }
     321             : 
     322             :         /* retrieve the sid for the group just created */
     323         830 :         group_sid = samdb_search_dom_sid(ldb, tmp_ctx,
     324             :                                          msg->dn, "objectSid", NULL);
     325         830 :         if (group_sid == NULL) {
     326           0 :                 return NT_STATUS_UNSUCCESSFUL;
     327             :         }
     328             : 
     329         830 :         *dn = talloc_steal(mem_ctx, msg->dn);
     330         830 :         *sid = talloc_steal(mem_ctx, group_sid);
     331         830 :         talloc_free(tmp_ctx);
     332         830 :         return NT_STATUS_OK;
     333             : }
     334             : 
     335         755 : NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
     336             :                                TALLOC_CTX *mem_ctx,
     337             :                                const char *alias_name,
     338             :                                struct dom_sid **sid,
     339             :                                struct ldb_dn **dn)
     340             : {
     341             :         const char *name;
     342             :         struct ldb_message *msg;
     343             :         struct dom_sid *alias_sid;
     344             :         int ret;
     345             : 
     346         755 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     347         755 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     348             : 
     349         755 :         if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
     350           0 :                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
     351           0 :                 return NT_STATUS_INTERNAL_ERROR;
     352             :         }
     353             : 
     354             :         /* Check if alias already exists */
     355         755 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
     356             :                                    "sAMAccountName",
     357             :                                    "(sAMAccountName=%s)(objectclass=group))",
     358             :                                    ldb_binary_encode_string(mem_ctx, alias_name));
     359             : 
     360         755 :         if (name != NULL) {
     361           0 :                 talloc_free(tmp_ctx);
     362           0 :                 ldb_transaction_cancel(ldb);
     363           0 :                 return NT_STATUS_ALIAS_EXISTS;
     364             :         }
     365             : 
     366         755 :         msg = ldb_msg_new(tmp_ctx);
     367         755 :         if (msg == NULL) {
     368           0 :                 talloc_free(tmp_ctx);
     369           0 :                 ldb_transaction_cancel(ldb);
     370           0 :                 return NT_STATUS_NO_MEMORY;
     371             :         }
     372             : 
     373             :         /* add core elements to the ldb_message for the alias */
     374         755 :         msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb));
     375         755 :         ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
     376         755 :         if (!msg->dn) {
     377           0 :                 talloc_free(tmp_ctx);
     378           0 :                 ldb_transaction_cancel(ldb);
     379           0 :                 return NT_STATUS_NO_MEMORY;
     380             :         }
     381             : 
     382         755 :         ldb_msg_add_string(msg, "sAMAccountName", alias_name);
     383         755 :         ldb_msg_add_string(msg, "objectClass", "group");
     384         755 :         samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
     385             : 
     386             :         /* create the alias */
     387         755 :         ret = ldb_add(ldb, msg);
     388         755 :         switch (ret) {
     389         755 :         case LDB_SUCCESS:
     390         755 :                 break;
     391           0 :         case LDB_ERR_ENTRY_ALREADY_EXISTS:
     392           0 :                 talloc_free(tmp_ctx);
     393           0 :                 ldb_transaction_cancel(ldb);
     394           0 :                 return NT_STATUS_ALIAS_EXISTS;
     395           0 :         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     396           0 :                 talloc_free(tmp_ctx);
     397           0 :                 ldb_transaction_cancel(ldb);
     398           0 :                 return NT_STATUS_ACCESS_DENIED;
     399           0 :         default:
     400           0 :                 DEBUG(0,("Failed to create alias record %s: %s\n",
     401             :                          ldb_dn_get_linearized(msg->dn),
     402             :                          ldb_errstring(ldb)));
     403           0 :                 talloc_free(tmp_ctx);
     404           0 :                 ldb_transaction_cancel(ldb);
     405           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     406             :         }
     407             : 
     408             :         /* retrieve the sid for the alias just created */
     409         755 :         alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
     410             :                                          msg->dn, "objectSid", NULL);
     411             : 
     412         755 :         if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
     413           0 :                 DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
     414             :                           ldb_errstring(ldb)));
     415           0 :                 return NT_STATUS_INTERNAL_ERROR;
     416             :         }
     417             : 
     418         755 :         *dn = talloc_steal(mem_ctx, msg->dn);
     419         755 :         *sid = talloc_steal(mem_ctx, alias_sid);
     420         755 :         talloc_free(tmp_ctx);
     421             : 
     422             : 
     423         755 :         return NT_STATUS_OK;
     424             : }
     425             : 
     426             : /* Return the members of this group (which may be a domain group or an alias) */
     427         635 : NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
     428             :                              TALLOC_CTX *mem_ctx,
     429             :                              struct ldb_dn *dn,
     430             :                              struct dom_sid **members_out,
     431             :                              unsigned int *pnum_members)
     432             : {
     433             :         struct ldb_message *msg;
     434             :         unsigned int i, j;
     435             :         int ret;
     436             :         struct dom_sid *members;
     437             :         struct ldb_message_element *member_el;
     438         635 :         const char *attrs[] = { "member", NULL };
     439             :         NTSTATUS status;
     440         635 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     441         635 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     442             : 
     443         635 :         ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
     444             :                               DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
     445         635 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     446           0 :                 talloc_free(tmp_ctx);
     447           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     448             :         }
     449         635 :         if (ret != LDB_SUCCESS) {
     450           0 :                 DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n",
     451             :                           ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
     452           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     453             :         }
     454             : 
     455         635 :         member_el = ldb_msg_find_element(msg, "member");
     456         635 :         if (!member_el) {
     457         472 :                 *members_out = NULL;
     458         472 :                 *pnum_members = 0;
     459         472 :                 talloc_free(tmp_ctx);
     460         472 :                 return NT_STATUS_OK;
     461             :         }
     462             : 
     463         163 :         members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values);
     464         163 :         if (members == NULL) {
     465           0 :                 return NT_STATUS_NO_MEMORY;
     466             :         }
     467             : 
     468         163 :         j = 0;
     469         386 :         for (i=0; i <member_el->num_values; i++) {
     470         223 :                 struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb,
     471         223 :                                                                &member_el->values[i]);
     472         223 :                 if (!member_dn || !ldb_dn_validate(member_dn)) {
     473           0 :                         DEBUG(1, ("Could not parse %*.*s as a DN\n",
     474             :                                   (int)member_el->values[i].length,
     475             :                                   (int)member_el->values[i].length,
     476             :                                   (const char *)member_el->values[i].data));
     477           0 :                         talloc_free(tmp_ctx);
     478           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     479             :                 }
     480             : 
     481         223 :                 status = dsdb_get_extended_dn_sid(member_dn, &members[j],
     482             :                                                   "SID");
     483         223 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     484             :                         /* If we fail finding a SID then this is no error since
     485             :                          * it could be a non SAM object - e.g. a contact */
     486           0 :                         continue;
     487         223 :                 } else if (!NT_STATUS_IS_OK(status)) {
     488           0 :                         DEBUG(1, ("When parsing DN '%s' we failed to parse it's SID component, so we cannot fetch the membership: %s\n",
     489             :                                   ldb_dn_get_extended_linearized(tmp_ctx, member_dn, 1),
     490             :                                   nt_errstr(status)));
     491           0 :                         talloc_free(tmp_ctx);
     492           0 :                         return status;
     493             :                 }
     494             : 
     495         223 :                 ++j;
     496             :         }
     497             : 
     498         163 :         *members_out = members;
     499         163 :         *pnum_members = j;
     500         163 :         talloc_free(tmp_ctx);
     501         163 :         return NT_STATUS_OK;
     502             : }
     503             : 
     504        5825 : NTSTATUS dsdb_lookup_rids(struct ldb_context *ldb,
     505             :                           TALLOC_CTX *mem_ctx,
     506             :                           const struct dom_sid *domain_sid,
     507             :                           unsigned int num_rids,
     508             :                           uint32_t *rids,
     509             :                           const char **names,
     510             :                           enum lsa_SidType *lsa_attrs)
     511             : {
     512        5825 :         const char *attrs[] = { "sAMAccountType", "sAMAccountName", NULL };
     513             :         unsigned int i, num_mapped;
     514             : 
     515        5825 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     516        5825 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     517             : 
     518        5555 :         num_mapped = 0;
     519             : 
     520       12139 :         for (i=0; i<num_rids; i++) {
     521             :                 struct ldb_message *msg;
     522             :                 struct ldb_dn *dn;
     523             :                 uint32_t attr;
     524             :                 int rc;
     525             : 
     526        6584 :                 lsa_attrs[i] = SID_NAME_UNKNOWN;
     527             : 
     528        6584 :                 dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<SID=%s>",
     529             :                                     dom_sid_string(tmp_ctx,
     530        6584 :                                                    dom_sid_add_rid(tmp_ctx, domain_sid,
     531        6584 :                                                                    rids[i])));
     532        6584 :                 if (dn == NULL) {
     533           0 :                         talloc_free(tmp_ctx);
     534           0 :                         return NT_STATUS_NO_MEMORY;
     535             :                 }
     536        6584 :                 rc = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "samAccountName=*");
     537        6584 :                 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
     538           2 :                         continue;
     539        6583 :                 } else if (rc != LDB_SUCCESS) {
     540           0 :                         talloc_free(tmp_ctx);
     541           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     542             :                 }
     543             : 
     544        6583 :                 names[i] = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
     545        6583 :                 if (names[i] == NULL) {
     546           0 :                         DEBUG(10, ("no samAccountName\n"));
     547           0 :                         continue;
     548             :                 }
     549        6583 :                 talloc_steal(names, names[i]);
     550        6583 :                 attr = ldb_msg_find_attr_as_uint(msg, "samAccountType", 0);
     551        6583 :                 lsa_attrs[i] = ds_atype_map(attr);
     552        6583 :                 if (lsa_attrs[i] == SID_NAME_UNKNOWN) {
     553           0 :                         continue;
     554             :                 }
     555        6583 :                 num_mapped += 1;
     556             :         }
     557        5825 :         talloc_free(tmp_ctx);
     558             : 
     559        5825 :         if (num_mapped == 0) {
     560           0 :                 return NT_STATUS_NONE_MAPPED;
     561             :         }
     562        5825 :         if (num_mapped < num_rids) {
     563           1 :                 return STATUS_SOME_UNMAPPED;
     564             :         }
     565        5824 :         return NT_STATUS_OK;
     566             : }
     567             : 

Generated by: LCOV version 1.13