LCOV - code coverage report
Current view: top level - source4/dsdb/common - util_samr.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 198 336 58.9 %
Date: 2024-04-21 15:09:00 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        1160 : 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          78 :         const char *name;
      44          78 :         struct ldb_message *msg;
      45          78 :         int ret;
      46        1160 :         const char *container, *obj_class=NULL;
      47          78 :         char *cn_name;
      48          78 :         size_t cn_name_len;
      49             : 
      50        1160 :         const char *attrs[] = {
      51             :                 "objectSid",
      52             :                 "userAccountControl",
      53             :                 NULL
      54             :         };
      55             : 
      56          78 :         uint32_t user_account_control;
      57          78 :         struct ldb_dn *account_dn;
      58          78 :         struct dom_sid *account_sid;
      59             : 
      60        1160 :         const char *account_name_encoded = NULL;
      61             : 
      62        1160 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
      63        1160 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
      64             : 
      65        1160 :         account_name_encoded = ldb_binary_encode_string(tmp_ctx, account_name);
      66        1160 :         if (account_name_encoded == NULL) {
      67           0 :                 talloc_free(tmp_ctx);
      68           0 :                 return NT_STATUS_NO_MEMORY;
      69             :         }
      70             : 
      71             :         /*
      72             :          * Start a transaction, so we can query and do a subsequent atomic
      73             :          * modify
      74             :          */
      75             : 
      76        1160 :         ret = ldb_transaction_start(ldb);
      77        1160 :         if (ret != LDB_SUCCESS) {
      78           0 :                 DEBUG(0,("Failed to start a transaction for user creation: %s\n",
      79             :                          ldb_errstring(ldb)));
      80           0 :                 talloc_free(tmp_ctx);
      81           0 :                 return NT_STATUS_LOCK_NOT_GRANTED;
      82             :         }
      83             : 
      84             :         /* check if the user already exists */
      85        1160 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
      86             :                                    "sAMAccountName",
      87             :                                    "(&(sAMAccountName=%s)(objectclass=user))",
      88             :                                    account_name_encoded);
      89        1160 :         if (name != NULL) {
      90          10 :                 ldb_transaction_cancel(ldb);
      91          10 :                 talloc_free(tmp_ctx);
      92          10 :                 return NT_STATUS_USER_EXISTS;
      93             :         }
      94             : 
      95        1150 :         cn_name = talloc_strdup(tmp_ctx, account_name);
      96        1150 :         if (!cn_name) {
      97           0 :                 ldb_transaction_cancel(ldb);
      98           0 :                 talloc_free(tmp_ctx);
      99           0 :                 return NT_STATUS_NO_MEMORY;
     100             :         }
     101             : 
     102        1150 :         cn_name_len = strlen(cn_name);
     103        1150 :         if (cn_name_len < 1) {
     104           0 :                 ldb_transaction_cancel(ldb);
     105           0 :                 talloc_free(tmp_ctx);
     106           0 :                 return NT_STATUS_INVALID_PARAMETER;
     107             :         }
     108             : 
     109        1150 :         msg = ldb_msg_new(tmp_ctx);
     110        1150 :         if (msg == NULL) {
     111           0 :                 ldb_transaction_cancel(ldb);
     112           0 :                 talloc_free(tmp_ctx);
     113           0 :                 return NT_STATUS_NO_MEMORY;
     114             :         }
     115             : 
     116             :         /* This must be one of these values *only* */
     117        1150 :         if (acct_flags == ACB_NORMAL) {
     118         517 :                 container = "CN=Users";
     119         517 :                 obj_class = "user";
     120         517 :                 user_account_control = UF_NORMAL_ACCOUNT;
     121         627 :         } else if (acct_flags == ACB_WSTRUST) {
     122         278 :                 if (cn_name[cn_name_len - 1] != '$') {
     123           0 :                         ldb_transaction_cancel(ldb);
     124           0 :                         return NT_STATUS_FOOBAR;
     125             :                 }
     126         278 :                 cn_name[cn_name_len - 1] = '\0';
     127         278 :                 container = "CN=Computers";
     128         278 :                 obj_class = "computer";
     129         278 :                 user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
     130             : 
     131         349 :         } else if (acct_flags == ACB_SVRTRUST) {
     132         249 :                 if (cn_name[cn_name_len - 1] != '$') {
     133           0 :                         ldb_transaction_cancel(ldb);
     134           0 :                         return NT_STATUS_FOOBAR;
     135             :                 }
     136         249 :                 cn_name[cn_name_len - 1] = '\0';
     137         249 :                 container = "OU=Domain Controllers";
     138         249 :                 obj_class = "computer";
     139         249 :                 user_account_control = UF_SERVER_TRUST_ACCOUNT;
     140         100 :         } else if (acct_flags == ACB_DOMTRUST) {
     141           0 :                 DEBUG(3, ("Invalid account flags specified:  cannot create domain trusts via this interface (must use LSA CreateTrustedDomain calls\n"));
     142           0 :                 ldb_transaction_cancel(ldb);
     143           0 :                 talloc_free(tmp_ctx);
     144           0 :                 return NT_STATUS_INVALID_PARAMETER;
     145             :         } else {
     146         100 :                 DEBUG(3, ("Invalid account flags specified 0x%08X, must be exactly one of \n"
     147             :                           "ACB_NORMAL (0x%08X) ACB_WSTRUST (0x%08X) or ACB_SVRTRUST (0x%08X)\n",
     148             :                           acct_flags,
     149             :                           ACB_NORMAL, ACB_WSTRUST, ACB_SVRTRUST));
     150         100 :                 ldb_transaction_cancel(ldb);
     151         100 :                 talloc_free(tmp_ctx);
     152         100 :                 return NT_STATUS_INVALID_PARAMETER;
     153             :         }
     154             : 
     155        1050 :         user_account_control |= UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD;
     156             : 
     157             :         /* add core elements to the ldb_message for the user */
     158        1050 :         msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb));
     159        1050 :         if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
     160           0 :                 ldb_transaction_cancel(ldb);
     161           0 :                 talloc_free(tmp_ctx);
     162           0 :                 return NT_STATUS_FOOBAR;
     163             :         }
     164             : 
     165        1050 :         ret = ldb_msg_add_string(msg, "sAMAccountName", account_name);
     166        1050 :         if (ret != LDB_SUCCESS) {
     167           0 :                 goto failed;
     168             :         }
     169        1050 :         ret = ldb_msg_add_string(msg, "objectClass", obj_class);
     170        1050 :         if (ret != LDB_SUCCESS) {
     171           0 :                 goto failed;
     172             :         }
     173        1050 :         ret = samdb_msg_add_uint(ldb, tmp_ctx, msg,
     174             :                                  "userAccountControl",
     175             :                                  user_account_control);
     176        1050 :         if (ret != LDB_SUCCESS) {
     177           0 :                 goto failed;
     178             :         }
     179             : 
     180             :         /* This is only here for migrations using pdb_samba4, the
     181             :          * caller and the samldb are responsible for ensuring it makes
     182             :          * sense */
     183        1050 :         if (forced_sid) {
     184           7 :                 ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid);
     185           7 :                 if (ret != LDB_SUCCESS) {
     186           0 :                         ldb_transaction_cancel(ldb);
     187           0 :                         talloc_free(tmp_ctx);
     188           0 :                         return NT_STATUS_INTERNAL_ERROR;
     189             :                 }
     190             :         }
     191             : 
     192             :         /* create the user */
     193        1050 :         ret = ldb_add(ldb, msg);
     194        1050 :         switch (ret) {
     195         969 :         case LDB_SUCCESS:
     196        1047 :                 break;
     197           0 :         case LDB_ERR_ENTRY_ALREADY_EXISTS:
     198           0 :                 ldb_transaction_cancel(ldb);
     199           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     200             :                          ldb_dn_get_linearized(msg->dn),
     201             :                          ldb_errstring(ldb)));
     202           0 :                 talloc_free(tmp_ctx);
     203           3 :                 return NT_STATUS_USER_EXISTS;
     204           3 :         case LDB_ERR_UNWILLING_TO_PERFORM:
     205             :         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     206           3 :                 ldb_transaction_cancel(ldb);
     207           3 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     208             :                          ldb_dn_get_linearized(msg->dn),
     209             :                          ldb_errstring(ldb)));
     210           3 :                 talloc_free(tmp_ctx);
     211           3 :                 return NT_STATUS_ACCESS_DENIED;
     212           0 :         default:
     213           0 :                 ldb_transaction_cancel(ldb);
     214           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
     215             :                          ldb_dn_get_linearized(msg->dn),
     216             :                          ldb_errstring(ldb)));
     217           0 :                 talloc_free(tmp_ctx);
     218           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     219             :         }
     220             : 
     221        1047 :         account_dn = msg->dn;
     222             : 
     223             :         /* retrieve the sid and account control bits for the user just created */
     224        1047 :         ret = dsdb_search_one(ldb, tmp_ctx, &msg,
     225             :                               account_dn, LDB_SCOPE_BASE, attrs, 0, NULL);
     226             : 
     227        1047 :         if (ret != LDB_SUCCESS) {
     228           0 :                 ldb_transaction_cancel(ldb);
     229           0 :                 DEBUG(0,("Can't locate the account we just created %s: %s\n",
     230             :                          ldb_dn_get_linearized(account_dn), ldb_errstring(ldb)));
     231           0 :                 talloc_free(tmp_ctx);
     232           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     233             :         }
     234        1047 :         account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
     235        1047 :         if (account_sid == NULL) {
     236           0 :                 ldb_transaction_cancel(ldb);
     237           0 :                 DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n",
     238             :                          ldb_dn_get_linearized(msg->dn)));
     239           0 :                 talloc_free(tmp_ctx);
     240           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     241             :         }
     242             : 
     243        1047 :         ret = ldb_transaction_commit(ldb);
     244        1047 :         if (ret != LDB_SUCCESS) {
     245           0 :                 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
     246             :                          ldb_dn_get_linearized(msg->dn),
     247             :                          ldb_errstring(ldb)));
     248           0 :                 talloc_free(tmp_ctx);
     249           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     250             :         }
     251        1047 :         *dn = talloc_steal(mem_ctx, account_dn);
     252        1047 :         if (sid) {
     253        1040 :                 *sid = talloc_steal(mem_ctx, account_sid);
     254             :         }
     255        1047 :         talloc_free(tmp_ctx);
     256        1047 :         return NT_STATUS_OK;
     257             : 
     258           0 :   failed:
     259           0 :         ldb_transaction_cancel(ldb);
     260           0 :         talloc_free(tmp_ctx);
     261           0 :         return NT_STATUS_INTERNAL_ERROR;
     262             : }
     263             : 
     264             : /*
     265             :   called by samr_CreateDomainGroup and pdb_samba4
     266             : */
     267         529 : NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb,
     268             :                                TALLOC_CTX *mem_ctx,
     269             :                                const char *groupname,
     270             :                                struct dom_sid **sid,
     271             :                                struct ldb_dn **dn)
     272             : {
     273           0 :         const char *name;
     274           0 :         struct ldb_message *msg;
     275           0 :         struct dom_sid *group_sid;
     276         529 :         const char *groupname_encoded = NULL;
     277           0 :         int ret;
     278             : 
     279         529 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     280         529 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     281             : 
     282         529 :         groupname_encoded = ldb_binary_encode_string(tmp_ctx, groupname);
     283         529 :         if (groupname_encoded == NULL) {
     284           0 :                 talloc_free(tmp_ctx);
     285           0 :                 return NT_STATUS_NO_MEMORY;
     286             :         }
     287             : 
     288             :         /* check if the group already exists */
     289         529 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
     290             :                                    "sAMAccountName",
     291             :                                    "(&(sAMAccountName=%s)(objectclass=group))",
     292             :                                    groupname_encoded);
     293         529 :         if (name != NULL) {
     294           1 :                 talloc_free(tmp_ctx);
     295           1 :                 return NT_STATUS_GROUP_EXISTS;
     296             :         }
     297             : 
     298         528 :         msg = ldb_msg_new(tmp_ctx);
     299         528 :         if (msg == NULL) {
     300           0 :                 talloc_free(tmp_ctx);
     301           0 :                 return NT_STATUS_NO_MEMORY;
     302             :         }
     303             : 
     304             :         /* add core elements to the ldb_message for the user */
     305         528 :         msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb));
     306         528 :         ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
     307         528 :         if (!msg->dn) {
     308           0 :                 talloc_free(tmp_ctx);
     309           0 :                 return NT_STATUS_NO_MEMORY;
     310             :         }
     311         528 :         ldb_msg_add_string(msg, "sAMAccountName", groupname);
     312         528 :         ldb_msg_add_string(msg, "objectClass", "group");
     313             : 
     314             :         /* create the group */
     315         528 :         ret = ldb_add(ldb, msg);
     316         528 :         switch (ret) {
     317         528 :         case  LDB_SUCCESS:
     318         528 :                 break;
     319           0 :         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
     320           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     321             :                          ldb_dn_get_linearized(msg->dn),
     322             :                          ldb_errstring(ldb)));
     323           0 :                 talloc_free(tmp_ctx);
     324           0 :                 return NT_STATUS_GROUP_EXISTS;
     325           0 :         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     326           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     327             :                          ldb_dn_get_linearized(msg->dn),
     328             :                          ldb_errstring(ldb)));
     329           0 :                 talloc_free(tmp_ctx);
     330           0 :                 return NT_STATUS_ACCESS_DENIED;
     331           0 :         default:
     332           0 :                 DEBUG(0,("Failed to create group record %s: %s\n",
     333             :                          ldb_dn_get_linearized(msg->dn),
     334             :                          ldb_errstring(ldb)));
     335           0 :                 talloc_free(tmp_ctx);
     336           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     337             :         }
     338             : 
     339             :         /* retrieve the sid for the group just created */
     340         528 :         group_sid = samdb_search_dom_sid(ldb, tmp_ctx,
     341             :                                          msg->dn, "objectSid", NULL);
     342         528 :         if (group_sid == NULL) {
     343           0 :                 talloc_free(tmp_ctx);
     344           0 :                 return NT_STATUS_UNSUCCESSFUL;
     345             :         }
     346             : 
     347         528 :         *dn = talloc_steal(mem_ctx, msg->dn);
     348         528 :         *sid = talloc_steal(mem_ctx, group_sid);
     349         528 :         talloc_free(tmp_ctx);
     350         528 :         return NT_STATUS_OK;
     351             : }
     352             : 
     353         453 : NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
     354             :                                TALLOC_CTX *mem_ctx,
     355             :                                const char *alias_name,
     356             :                                struct dom_sid **sid,
     357             :                                struct ldb_dn **dn)
     358             : {
     359           0 :         const char *name;
     360           0 :         struct ldb_message *msg;
     361           0 :         struct dom_sid *alias_sid;
     362         453 :         const char *alias_name_encoded = NULL;
     363           0 :         int ret;
     364             : 
     365         453 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     366         453 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     367             : 
     368         453 :         alias_name_encoded = ldb_binary_encode_string(tmp_ctx, alias_name);
     369         453 :         if (alias_name_encoded == NULL) {
     370           0 :                 return NT_STATUS_NO_MEMORY;
     371             :         }
     372             : 
     373         453 :         if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
     374           0 :                 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
     375           0 :                 talloc_free(tmp_ctx);
     376           0 :                 return NT_STATUS_INTERNAL_ERROR;
     377             :         }
     378             : 
     379             :         /* Check if alias already exists */
     380         453 :         name = samdb_search_string(ldb, tmp_ctx, NULL,
     381             :                                    "sAMAccountName",
     382             :                                    "(sAMAccountName=%s)(objectclass=group))",
     383             :                                    alias_name_encoded);
     384             : 
     385         453 :         if (name != NULL) {
     386           0 :                 talloc_free(tmp_ctx);
     387           0 :                 ldb_transaction_cancel(ldb);
     388           0 :                 return NT_STATUS_ALIAS_EXISTS;
     389             :         }
     390             : 
     391         453 :         msg = ldb_msg_new(tmp_ctx);
     392         453 :         if (msg == NULL) {
     393           0 :                 talloc_free(tmp_ctx);
     394           0 :                 ldb_transaction_cancel(ldb);
     395           0 :                 return NT_STATUS_NO_MEMORY;
     396             :         }
     397             : 
     398             :         /* add core elements to the ldb_message for the alias */
     399         453 :         msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb));
     400         453 :         ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
     401         453 :         if (!msg->dn) {
     402           0 :                 talloc_free(tmp_ctx);
     403           0 :                 ldb_transaction_cancel(ldb);
     404           0 :                 return NT_STATUS_NO_MEMORY;
     405             :         }
     406             : 
     407         453 :         ldb_msg_add_string(msg, "sAMAccountName", alias_name);
     408         453 :         ldb_msg_add_string(msg, "objectClass", "group");
     409         453 :         samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
     410             : 
     411             :         /* create the alias */
     412         453 :         ret = ldb_add(ldb, msg);
     413         453 :         switch (ret) {
     414         453 :         case LDB_SUCCESS:
     415         453 :                 break;
     416           0 :         case LDB_ERR_ENTRY_ALREADY_EXISTS:
     417           0 :                 talloc_free(tmp_ctx);
     418           0 :                 ldb_transaction_cancel(ldb);
     419           0 :                 return NT_STATUS_ALIAS_EXISTS;
     420           0 :         case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
     421           0 :                 talloc_free(tmp_ctx);
     422           0 :                 ldb_transaction_cancel(ldb);
     423           0 :                 return NT_STATUS_ACCESS_DENIED;
     424           0 :         default:
     425           0 :                 DEBUG(0,("Failed to create alias record %s: %s\n",
     426             :                          ldb_dn_get_linearized(msg->dn),
     427             :                          ldb_errstring(ldb)));
     428           0 :                 talloc_free(tmp_ctx);
     429           0 :                 ldb_transaction_cancel(ldb);
     430           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     431             :         }
     432             : 
     433             :         /* retrieve the sid for the alias just created */
     434         453 :         alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
     435             :                                          msg->dn, "objectSid", NULL);
     436             : 
     437         453 :         if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
     438           0 :                 DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
     439             :                           ldb_errstring(ldb)));
     440           0 :                 talloc_free(tmp_ctx);
     441           0 :                 return NT_STATUS_INTERNAL_ERROR;
     442             :         }
     443             : 
     444         453 :         *dn = talloc_steal(mem_ctx, msg->dn);
     445         453 :         *sid = talloc_steal(mem_ctx, alias_sid);
     446         453 :         talloc_free(tmp_ctx);
     447             : 
     448             : 
     449         453 :         return NT_STATUS_OK;
     450             : }
     451             : 
     452             : /* Return the members of this group (which may be a domain group or an alias) */
     453         243 : NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
     454             :                              TALLOC_CTX *mem_ctx,
     455             :                              struct ldb_dn *dn,
     456             :                              struct dom_sid **members_out,
     457             :                              unsigned int *pnum_members)
     458             : {
     459           0 :         struct ldb_message *msg;
     460           0 :         unsigned int i, j;
     461           0 :         int ret;
     462           0 :         struct dom_sid *members;
     463           0 :         struct ldb_message_element *member_el;
     464         243 :         const char *attrs[] = { "member", NULL };
     465           0 :         NTSTATUS status;
     466         243 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     467         243 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     468             : 
     469         243 :         ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
     470             :                               DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
     471         243 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     472           0 :                 talloc_free(tmp_ctx);
     473           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     474             :         }
     475         243 :         if (ret != LDB_SUCCESS) {
     476           0 :                 DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n",
     477             :                           ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
     478           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     479             :         }
     480             : 
     481         243 :         member_el = ldb_msg_find_element(msg, "member");
     482         243 :         if (!member_el) {
     483         110 :                 *members_out = NULL;
     484         110 :                 *pnum_members = 0;
     485         110 :                 talloc_free(tmp_ctx);
     486         110 :                 return NT_STATUS_OK;
     487             :         }
     488             : 
     489         133 :         members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values);
     490         133 :         if (members == NULL) {
     491           0 :                 return NT_STATUS_NO_MEMORY;
     492             :         }
     493             : 
     494         133 :         j = 0;
     495         302 :         for (i=0; i <member_el->num_values; i++) {
     496         169 :                 struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb,
     497         169 :                                                                &member_el->values[i]);
     498         169 :                 if (!member_dn || !ldb_dn_validate(member_dn)) {
     499           0 :                         DEBUG(1, ("Could not parse %*.*s as a DN\n",
     500             :                                   (int)member_el->values[i].length,
     501             :                                   (int)member_el->values[i].length,
     502             :                                   (const char *)member_el->values[i].data));
     503           0 :                         talloc_free(tmp_ctx);
     504           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     505             :                 }
     506             : 
     507         169 :                 status = dsdb_get_extended_dn_sid(member_dn, &members[j],
     508             :                                                   "SID");
     509         169 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     510             :                         /* If we fail finding a SID then this is no error since
     511             :                          * it could be a non SAM object - e.g. a contact */
     512           0 :                         continue;
     513         169 :                 } else if (!NT_STATUS_IS_OK(status)) {
     514           0 :                         DEBUG(1, ("When parsing DN '%s' we failed to parse it's SID component, so we cannot fetch the membership: %s\n",
     515             :                                   ldb_dn_get_extended_linearized(tmp_ctx, member_dn, 1),
     516             :                                   nt_errstr(status)));
     517           0 :                         talloc_free(tmp_ctx);
     518           0 :                         return status;
     519             :                 }
     520             : 
     521         169 :                 ++j;
     522             :         }
     523             : 
     524         133 :         *members_out = members;
     525         133 :         *pnum_members = j;
     526         133 :         talloc_free(tmp_ctx);
     527         133 :         return NT_STATUS_OK;
     528             : }
     529             : 
     530        4924 : NTSTATUS dsdb_lookup_rids(struct ldb_context *ldb,
     531             :                           TALLOC_CTX *mem_ctx,
     532             :                           const struct dom_sid *domain_sid,
     533             :                           unsigned int num_rids,
     534             :                           uint32_t *rids,
     535             :                           const char **names,
     536             :                           enum lsa_SidType *lsa_attrs)
     537             : {
     538        4924 :         const char *attrs[] = { "sAMAccountType", "sAMAccountName", NULL };
     539         270 :         unsigned int i, num_mapped;
     540             : 
     541        4924 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     542        4924 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     543             : 
     544        4654 :         num_mapped = 0;
     545             : 
     546       12465 :         for (i=0; i<num_rids; i++) {
     547         270 :                 struct ldb_message *msg;
     548         270 :                 struct ldb_dn *dn;
     549         270 :                 uint32_t attr;
     550         270 :                 int rc;
     551             : 
     552        7541 :                 lsa_attrs[i] = SID_NAME_UNKNOWN;
     553             : 
     554        7541 :                 dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<SID=%s>",
     555             :                                     dom_sid_string(tmp_ctx,
     556        7541 :                                                    dom_sid_add_rid(tmp_ctx, domain_sid,
     557        7541 :                                                                    rids[i])));
     558        7541 :                 if (dn == NULL) {
     559           0 :                         talloc_free(tmp_ctx);
     560           0 :                         return NT_STATUS_NO_MEMORY;
     561             :                 }
     562        7541 :                 rc = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "samAccountName=*");
     563        7541 :                 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
     564           1 :                         continue;
     565        7540 :                 } else if (rc != LDB_SUCCESS) {
     566           0 :                         talloc_free(tmp_ctx);
     567           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     568             :                 }
     569             : 
     570        7540 :                 names[i] = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
     571        7540 :                 if (names[i] == NULL) {
     572           0 :                         DEBUG(10, ("no samAccountName\n"));
     573           0 :                         continue;
     574             :                 }
     575        7540 :                 talloc_steal(names, names[i]);
     576        7540 :                 attr = ldb_msg_find_attr_as_uint(msg, "samAccountType", 0);
     577        7540 :                 lsa_attrs[i] = ds_atype_map(attr);
     578        7540 :                 if (lsa_attrs[i] == SID_NAME_UNKNOWN) {
     579           0 :                         continue;
     580             :                 }
     581        7540 :                 num_mapped += 1;
     582             :         }
     583        4924 :         talloc_free(tmp_ctx);
     584             : 
     585        4924 :         if (num_mapped == 0) {
     586           0 :                 return NT_STATUS_NONE_MAPPED;
     587             :         }
     588        4924 :         if (num_mapped < num_rids) {
     589           1 :                 return STATUS_SOME_UNMAPPED;
     590             :         }
     591        4923 :         return NT_STATUS_OK;
     592             : }
     593             : 

Generated by: LCOV version 1.14