LCOV - code coverage report
Current view: top level - source3/passdb - pdb_ldap.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 6 3407 0.2 %
Date: 2024-05-31 13:13:24 Functions: 1 89 1.1 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    LDAP protocol helper functions for SAMBA
       4             :    Copyright (C) Jean François Micouleau       1998
       5             :    Copyright (C) Gerald Carter                  2001-2003
       6             :    Copyright (C) Shahms King                    2001
       7             :    Copyright (C) Andrew Bartlett                2002-2003
       8             :    Copyright (C) Stefan (metze) Metzmacher      2002-2003
       9             :    Copyright (C) Simo Sorce                     2006
      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             : 
      26             : /* TODO:
      27             : *  persistent connections: if using NSS LDAP, many connections are made
      28             : *      however, using only one within Samba would be nice
      29             : *
      30             : *  Clean up SSL stuff, compile on OpenLDAP 1.x, 2.x, and Netscape SDK
      31             : *
      32             : *  Other LDAP based login attributes: accountExpires, etc.
      33             : *  (should be the domain of Samba proper, but the sam_password/struct samu
      34             : *  structures don't have fields for some of these attributes)
      35             : *
      36             : *  SSL is done, but can't get the certificate based authentication to work
      37             : *  against on my test platform (Linux 2.4, OpenLDAP 2.x)
      38             : */
      39             : 
      40             : /* NOTE: this will NOT work against an Active Directory server
      41             : *  due to the fact that the two password fields cannot be retrieved
      42             : *  from a server; recommend using security = domain in this situation
      43             : *  and/or winbind
      44             : */
      45             : 
      46             : #include "includes.h"
      47             : #include "passdb.h"
      48             : #include "../libcli/auth/libcli_auth.h"
      49             : #include "secrets.h"
      50             : #include "idmap_cache.h"
      51             : #include "../libcli/security/security.h"
      52             : #include "../lib/util/util_pw.h"
      53             : #include "lib/winbind_util.h"
      54             : #include "librpc/gen_ndr/idmap.h"
      55             : #include "lib/param/loadparm.h"
      56             : #include "lib/util_sid_passdb.h"
      57             : #include "lib/util/smb_strtox.h"
      58             : #include "lib/util/string_wrappers.h"
      59             : #include "source3/lib/substitute.h"
      60             : 
      61             : #undef DBGC_CLASS
      62             : #define DBGC_CLASS DBGC_PASSDB
      63             : 
      64             : #include <lber.h>
      65             : #include <ldap.h>
      66             : 
      67             : 
      68             : #include "smbldap.h"
      69             : #include "passdb/pdb_ldap.h"
      70             : #include "passdb/pdb_nds.h"
      71             : #include "passdb/pdb_ldap_util.h"
      72             : #include "passdb/pdb_ldap_schema.h"
      73             : 
      74             : /**********************************************************************
      75             :  Simple helper function to make stuff better readable
      76             :  **********************************************************************/
      77             : 
      78           0 : LDAP *priv2ld(struct ldapsam_privates *priv)
      79             : {
      80           0 :         return smbldap_get_ldap(priv->smbldap_state);
      81             : }
      82             : 
      83             : /**********************************************************************
      84             :  Get the attribute name given a user schema version.
      85             :  **********************************************************************/
      86             : 
      87           0 : static const char* get_userattr_key2string( int schema_ver, int key )
      88             : {
      89           0 :         switch ( schema_ver ) {
      90           0 :                 case SCHEMAVER_SAMBASAMACCOUNT:
      91           0 :                         return get_attr_key2string( attrib_map_v30, key );
      92             : 
      93           0 :                 default:
      94           0 :                         DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
      95           0 :                         break;
      96             :         }
      97           0 :         return NULL;
      98             : }
      99             : 
     100             : /**********************************************************************
     101             :  Return the list of attribute names given a user schema version.
     102             : **********************************************************************/
     103             : 
     104           0 : const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
     105             : {
     106           0 :         switch ( schema_ver ) {
     107           0 :                 case SCHEMAVER_SAMBASAMACCOUNT:
     108           0 :                         return get_attr_list( mem_ctx, attrib_map_v30 );
     109           0 :                 default:
     110           0 :                         DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
     111           0 :                         break;
     112             :         }
     113             : 
     114           0 :         return NULL;
     115             : }
     116             : 
     117             : /**************************************************************************
     118             :  Return the list of attribute names to delete given a user schema version.
     119             : **************************************************************************/
     120             : 
     121           0 : static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
     122             :                                               int schema_ver )
     123             : {
     124           0 :         switch ( schema_ver ) {
     125           0 :                 case SCHEMAVER_SAMBASAMACCOUNT:
     126           0 :                         return get_attr_list( mem_ctx,
     127             :                                               attrib_map_to_delete_v30 );
     128           0 :                 default:
     129           0 :                         DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
     130           0 :                         break;
     131             :         }
     132             : 
     133           0 :         return NULL;
     134             : }
     135             : 
     136             : 
     137             : /*******************************************************************
     138             :  Generate the LDAP search filter for the objectclass based on the
     139             :  version of the schema we are using.
     140             : ******************************************************************/
     141             : 
     142           0 : static const char* get_objclass_filter( int schema_ver )
     143             : {
     144           0 :         fstring objclass_filter;
     145           0 :         char *result;
     146             : 
     147           0 :         switch( schema_ver ) {
     148           0 :                 case SCHEMAVER_SAMBASAMACCOUNT:
     149           0 :                         fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
     150           0 :                         break;
     151           0 :                 default:
     152           0 :                         DEBUG(0,("get_objclass_filter: Invalid schema version specified!\n"));
     153           0 :                         objclass_filter[0] = '\0';
     154           0 :                         break;
     155             :         }
     156             : 
     157           0 :         result = talloc_strdup(talloc_tos(), objclass_filter);
     158           0 :         SMB_ASSERT(result != NULL);
     159           0 :         return result;
     160             : }
     161             : 
     162             : /*****************************************************************
     163             :  Scan a sequence number off OpenLDAP's syncrepl contextCSN
     164             : ******************************************************************/
     165             : 
     166           0 : static NTSTATUS ldapsam_get_seq_num(struct pdb_methods *my_methods, time_t *seq_num)
     167             : {
     168           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
     169           0 :         NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
     170           0 :         LDAPMessage *msg = NULL;
     171           0 :         LDAPMessage *entry = NULL;
     172           0 :         TALLOC_CTX *mem_ctx;
     173           0 :         char **values = NULL;
     174           0 :         int rc, num_result, num_values, rid;
     175           0 :         char *suffix = NULL;
     176           0 :         char *tok;
     177           0 :         const char *p;
     178           0 :         const char **attrs;
     179             : 
     180             :         /* Unfortunately there is no proper way to detect syncrepl-support in
     181             :          * smbldap_connect_system(). The syncrepl OIDs are submitted for publication
     182             :          * but do not show up in the root-DSE yet. Neither we can query the
     183             :          * subschema-context for the syncProviderSubentry or syncConsumerSubentry
     184             :          * objectclass. Currently we require lp_ldap_suffix() to show up as
     185             :          * namingContext.  -  Guenther
     186             :          */
     187             : 
     188           0 :         if (!lp_parm_bool(-1, "ldapsam", "syncrepl_seqnum", False)) {
     189           0 :                 return ntstatus;
     190             :         }
     191             : 
     192           0 :         if (!seq_num) {
     193           0 :                 DEBUG(3,("ldapsam_get_seq_num: no sequence_number\n"));
     194           0 :                 return ntstatus;
     195             :         }
     196             : 
     197           0 :         if (!smbldap_has_naming_context(
     198             :                     smbldap_get_ldap(ldap_state->smbldap_state),
     199             :                     lp_ldap_suffix())) {
     200           0 :                 DEBUG(3,("ldapsam_get_seq_num: DIT not configured to hold %s "
     201             :                          "as top-level namingContext\n", lp_ldap_suffix()));
     202           0 :                 return ntstatus;
     203             :         }
     204             : 
     205           0 :         mem_ctx = talloc_init("ldapsam_get_seq_num");
     206             : 
     207           0 :         if (mem_ctx == NULL)
     208           0 :                 return NT_STATUS_NO_MEMORY;
     209             : 
     210           0 :         if ((attrs = talloc_array(mem_ctx, const char *, 2)) == NULL) {
     211           0 :                 ntstatus = NT_STATUS_NO_MEMORY;
     212           0 :                 goto done;
     213             :         }
     214             : 
     215             :         /* if we got a syncrepl-rid (up to three digits long) we speak with a consumer */
     216           0 :         rid = lp_parm_int(-1, "ldapsam", "syncrepl_rid", -1);
     217           0 :         if (rid > 0) {
     218             : 
     219             :                 /* consumer syncreplCookie: */
     220             :                 /* csn=20050126161620Z#0000001#00#00000 */
     221           0 :                 attrs[0] = talloc_strdup(mem_ctx, "syncreplCookie");
     222           0 :                 attrs[1] = NULL;
     223           0 :                 suffix = talloc_asprintf(mem_ctx,
     224             :                                 "cn=syncrepl%d,%s", rid, lp_ldap_suffix());
     225           0 :                 if (!suffix) {
     226           0 :                         ntstatus = NT_STATUS_NO_MEMORY;
     227           0 :                         goto done;
     228             :                 }
     229             :         } else {
     230             : 
     231             :                 /* provider contextCSN */
     232             :                 /* 20050126161620Z#000009#00#000000 */
     233           0 :                 attrs[0] = talloc_strdup(mem_ctx, "contextCSN");
     234           0 :                 attrs[1] = NULL;
     235           0 :                 suffix = talloc_asprintf(mem_ctx,
     236             :                                 "cn=ldapsync,%s", lp_ldap_suffix());
     237             : 
     238           0 :                 if (!suffix) {
     239           0 :                         ntstatus = NT_STATUS_NO_MEMORY;
     240           0 :                         goto done;
     241             :                 }
     242             :         }
     243             : 
     244           0 :         rc = smbldap_search(ldap_state->smbldap_state, suffix,
     245             :                             LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, &msg);
     246             : 
     247           0 :         if (rc != LDAP_SUCCESS) {
     248           0 :                 goto done;
     249             :         }
     250             : 
     251           0 :         num_result = ldap_count_entries(
     252             :                 smbldap_get_ldap(ldap_state->smbldap_state), msg);
     253           0 :         if (num_result != 1) {
     254           0 :                 DEBUG(3,("ldapsam_get_seq_num: Expected one entry, got %d\n", num_result));
     255           0 :                 goto done;
     256             :         }
     257             : 
     258           0 :         entry = ldap_first_entry(
     259             :                 smbldap_get_ldap(ldap_state->smbldap_state), msg);
     260           0 :         if (entry == NULL) {
     261           0 :                 DEBUG(3,("ldapsam_get_seq_num: Could not retrieve entry\n"));
     262           0 :                 goto done;
     263             :         }
     264             : 
     265           0 :         values = ldap_get_values(
     266             :                 smbldap_get_ldap(ldap_state->smbldap_state), entry, attrs[0]);
     267           0 :         if (values == NULL) {
     268           0 :                 DEBUG(3,("ldapsam_get_seq_num: no values\n"));
     269           0 :                 goto done;
     270             :         }
     271             : 
     272           0 :         num_values = ldap_count_values(values);
     273           0 :         if (num_values == 0) {
     274           0 :                 DEBUG(3,("ldapsam_get_seq_num: not a single value\n"));
     275           0 :                 goto done;
     276             :         }
     277             : 
     278           0 :         p = values[0];
     279           0 :         if (!next_token_talloc(mem_ctx, &p, &tok, "#")) {
     280           0 :                 DEBUG(0,("ldapsam_get_seq_num: failed to parse sequence number\n"));
     281           0 :                 goto done;
     282             :         }
     283             : 
     284           0 :         p = tok;
     285           0 :         if (!strncmp(p, "csn=", strlen("csn=")))
     286           0 :                 p += strlen("csn=");
     287             : 
     288           0 :         DEBUG(10,("ldapsam_get_seq_num: got %s: %s\n", attrs[0], p));
     289             : 
     290           0 :         *seq_num = generalized_to_unix_time(p);
     291             : 
     292             :         /* very basic sanity check */
     293           0 :         if (*seq_num <= 0) {
     294           0 :                 DEBUG(3,("ldapsam_get_seq_num: invalid sequence number: %d\n",
     295             :                         (int)*seq_num));
     296           0 :                 goto done;
     297             :         }
     298             : 
     299           0 :         ntstatus = NT_STATUS_OK;
     300             : 
     301           0 :  done:
     302           0 :         if (values != NULL)
     303           0 :                 ldap_value_free(values);
     304           0 :         if (msg != NULL)
     305           0 :                 ldap_msgfree(msg);
     306           0 :         if (mem_ctx)
     307           0 :                 talloc_destroy(mem_ctx);
     308             : 
     309           0 :         return ntstatus;
     310             : }
     311             : 
     312             : /*******************************************************************
     313             :  Run the search by name.
     314             : ******************************************************************/
     315             : 
     316           0 : int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
     317             :                                           const char *user,
     318             :                                           LDAPMessage ** result,
     319             :                                           const char **attr)
     320             : {
     321           0 :         char *filter = NULL;
     322           0 :         char *escape_user = escape_ldap_string(talloc_tos(), user);
     323           0 :         int ret = -1;
     324             : 
     325           0 :         if (!escape_user) {
     326           0 :                 return LDAP_NO_MEMORY;
     327             :         }
     328             : 
     329             :         /*
     330             :          * in the filter expression, replace %u with the real name
     331             :          * so in ldap filter, %u MUST exist :-)
     332             :          */
     333           0 :         filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
     334             :                 get_objclass_filter(ldap_state->schema_ver));
     335           0 :         if (!filter) {
     336           0 :                 TALLOC_FREE(escape_user);
     337           0 :                 return LDAP_NO_MEMORY;
     338             :         }
     339             :         /*
     340             :          * have to use this here because $ is filtered out
     341             :          * in string_sub
     342             :          */
     343             : 
     344           0 :         filter = talloc_all_string_sub(talloc_tos(),
     345             :                                 filter, "%u", escape_user);
     346           0 :         TALLOC_FREE(escape_user);
     347           0 :         if (!filter) {
     348           0 :                 return LDAP_NO_MEMORY;
     349             :         }
     350             : 
     351           0 :         ret = smbldap_search_suffix(ldap_state->smbldap_state,
     352             :                         filter, attr, result);
     353           0 :         TALLOC_FREE(filter);
     354           0 :         return ret;
     355             : }
     356             : 
     357             : /*******************************************************************
     358             :  Run the search by SID.
     359             : ******************************************************************/
     360             : 
     361           0 : static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
     362             :                                  const struct dom_sid *sid, LDAPMessage ** result,
     363             :                                  const char **attr)
     364             : {
     365           0 :         char *filter = NULL;
     366           0 :         int rc;
     367           0 :         struct dom_sid_buf sid_string;
     368             : 
     369           0 :         filter = talloc_asprintf(talloc_tos(), "(&(%s=%s)%s)",
     370             :                 get_userattr_key2string(ldap_state->schema_ver,
     371             :                         LDAP_ATTR_USER_SID),
     372             :                 dom_sid_str_buf(sid, &sid_string),
     373             :                 get_objclass_filter(ldap_state->schema_ver));
     374           0 :         if (!filter) {
     375           0 :                 return LDAP_NO_MEMORY;
     376             :         }
     377             : 
     378           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state,
     379             :                         filter, attr, result);
     380             : 
     381           0 :         TALLOC_FREE(filter);
     382           0 :         return rc;
     383             : }
     384             : 
     385             : /*******************************************************************
     386             :  Delete complete object or objectclass and attrs from
     387             :  object found in search_result depending on lp_ldap_delete_dn
     388             : ******************************************************************/
     389             : 
     390           0 : static int ldapsam_delete_entry(struct ldapsam_privates *priv,
     391             :                                 TALLOC_CTX *mem_ctx,
     392             :                                 LDAPMessage *entry,
     393             :                                 const char *objectclass,
     394             :                                 const char **attrs)
     395             : {
     396           0 :         LDAPMod **mods = NULL;
     397           0 :         char *name;
     398           0 :         const char *dn;
     399           0 :         BerElement *ptr = NULL;
     400             : 
     401           0 :         dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry);
     402           0 :         if (dn == NULL) {
     403           0 :                 return LDAP_NO_MEMORY;
     404             :         }
     405             : 
     406           0 :         if (lp_ldap_delete_dn()) {
     407           0 :                 return smbldap_delete(priv->smbldap_state, dn);
     408             :         }
     409             : 
     410             :         /* Ok, delete only the SAM attributes */
     411             : 
     412           0 :         for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
     413           0 :              name != NULL;
     414           0 :              name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
     415             :                 const char **attrib;
     416             : 
     417             :                 /* We are only allowed to delete the attributes that
     418             :                    really exist. */
     419             : 
     420           0 :                 for (attrib = attrs; *attrib != NULL; attrib++) {
     421           0 :                         if (strequal(*attrib, name)) {
     422           0 :                                 DEBUG(10, ("ldapsam_delete_entry: deleting "
     423             :                                            "attribute %s\n", name));
     424           0 :                                 smbldap_set_mod(&mods, LDAP_MOD_DELETE, name,
     425             :                                                 NULL);
     426             :                         }
     427             :                 }
     428           0 :                 ldap_memfree(name);
     429             :         }
     430             : 
     431           0 :         if (ptr != NULL) {
     432           0 :                 ber_free(ptr, 0);
     433             :         }
     434             : 
     435           0 :         smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
     436           0 :         smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
     437             : 
     438           0 :         return smbldap_modify(priv->smbldap_state, dn, mods);
     439             : }
     440             : 
     441           0 : static time_t ldapsam_get_entry_timestamp( struct ldapsam_privates *ldap_state, LDAPMessage * entry)
     442             : {
     443           0 :         char *temp;
     444           0 :         struct tm tm = {};
     445             : 
     446           0 :         temp = smbldap_talloc_single_attribute(
     447             :                 smbldap_get_ldap(ldap_state->smbldap_state), entry,
     448             :                 get_userattr_key2string(ldap_state->schema_ver,
     449             :                                         LDAP_ATTR_MOD_TIMESTAMP),
     450             :                         talloc_tos());
     451           0 :         if (!temp) {
     452           0 :                 return (time_t) 0;
     453             :         }
     454             : 
     455           0 :         if ( !strptime(temp, "%Y%m%d%H%M%SZ", &tm)) {
     456           0 :                 DEBUG(2,("ldapsam_get_entry_timestamp: strptime failed on: %s\n",
     457             :                         (char*)temp));
     458           0 :                 TALLOC_FREE(temp);
     459           0 :                 return (time_t) 0;
     460             :         }
     461           0 :         TALLOC_FREE(temp);
     462           0 :         tzset();
     463           0 :         return timegm(&tm);
     464             : }
     465             : 
     466             : /**********************************************************************
     467             :  Initialize struct samu from an LDAP query.
     468             :  (Based on init_sam_from_buffer in pdb_tdb.c)
     469             : *********************************************************************/
     470             : 
     471           0 : static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
     472             :                                 struct samu * sampass,
     473             :                                 LDAPMessage * entry)
     474             : {
     475           0 :         time_t  logon_time,
     476             :                         logoff_time,
     477             :                         kickoff_time,
     478             :                         pass_last_set_time,
     479             :                         pass_can_change_time,
     480             :                         ldap_entry_time,
     481             :                         bad_password_time;
     482           0 :         char *username = NULL,
     483           0 :                         *domain = NULL,
     484           0 :                         *nt_username = NULL,
     485           0 :                         *fullname = NULL,
     486           0 :                         *homedir = NULL,
     487           0 :                         *dir_drive = NULL,
     488           0 :                         *logon_script = NULL,
     489           0 :                         *profile_path = NULL,
     490           0 :                         *acct_desc = NULL,
     491           0 :                         *workstations = NULL,
     492           0 :                         *munged_dial = NULL;
     493           0 :         uint32_t                user_rid;
     494           0 :         uint8_t         smblmpwd[LM_HASH_LEN],
     495             :                         smbntpwd[NT_HASH_LEN];
     496           0 :         bool            use_samba_attrs = True;
     497           0 :         uint16_t                logon_divs;
     498           0 :         uint16_t                bad_password_count = 0,
     499           0 :                         logon_count = 0;
     500           0 :         uint32_t hours_len;
     501           0 :         uint8_t         hours[MAX_HOURS_LEN];
     502           0 :         char *temp = NULL;
     503           0 :         struct login_cache cache_entry;
     504           0 :         uint32_t                pwHistLen;
     505           0 :         bool expand_explicit = lp_passdb_expand_explicit();
     506           0 :         bool ret = false;
     507           0 :         TALLOC_CTX *ctx = talloc_init("init_sam_from_ldap");
     508             : 
     509           0 :         if (!ctx) {
     510           0 :                 return false;
     511             :         }
     512           0 :         if (sampass == NULL || ldap_state == NULL || entry == NULL) {
     513           0 :                 DEBUG(0, ("init_sam_from_ldap: NULL parameters found!\n"));
     514           0 :                 goto fn_exit;
     515             :         }
     516             : 
     517           0 :         if (priv2ld(ldap_state) == NULL) {
     518           0 :                 DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->"
     519             :                           "ldap_struct is NULL!\n"));
     520           0 :                 goto fn_exit;
     521             :         }
     522             : 
     523           0 :         if (!(username = smbldap_talloc_first_attribute(priv2ld(ldap_state),
     524             :                                         entry,
     525             :                                         "uid",
     526             :                                         ctx))) {
     527           0 :                 DEBUG(1, ("init_sam_from_ldap: No uid attribute found for "
     528             :                           "this user!\n"));
     529           0 :                 goto fn_exit;
     530             :         }
     531             : 
     532           0 :         DEBUG(2, ("init_sam_from_ldap: Entry found for user: %s\n", username));
     533             : 
     534           0 :         nt_username = talloc_strdup(ctx, username);
     535           0 :         if (!nt_username) {
     536           0 :                 goto fn_exit;
     537             :         }
     538             : 
     539           0 :         domain = talloc_strdup(ctx, ldap_state->domain_name);
     540           0 :         if (!domain) {
     541           0 :                 goto fn_exit;
     542             :         }
     543             : 
     544           0 :         pdb_set_username(sampass, username, PDB_SET);
     545             : 
     546           0 :         pdb_set_domain(sampass, domain, PDB_DEFAULT);
     547           0 :         pdb_set_nt_username(sampass, nt_username, PDB_SET);
     548             : 
     549             :         /* deal with different attributes between the schema first */
     550             : 
     551           0 :         if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ) {
     552           0 :                 if ((temp = smbldap_talloc_single_attribute(
     553             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     554             :                                 entry,
     555             :                                 get_userattr_key2string(ldap_state->schema_ver,
     556             :                                         LDAP_ATTR_USER_SID),
     557             :                                 ctx))!=NULL) {
     558           0 :                         pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
     559             :                 }
     560             :         } else {
     561           0 :                 if ((temp = smbldap_talloc_single_attribute(
     562             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     563             :                                 entry,
     564             :                                 get_userattr_key2string(ldap_state->schema_ver,
     565             :                                         LDAP_ATTR_USER_RID),
     566             :                                 ctx))!=NULL) {
     567           0 :                         user_rid = (uint32_t)atol(temp);
     568           0 :                         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
     569             :                 }
     570             :         }
     571             : 
     572           0 :         if (IS_SAM_DEFAULT(sampass, PDB_USERSID)) {
     573           0 :                 DEBUG(1, ("init_sam_from_ldap: no %s or %s attribute found for this user %s\n",
     574             :                         get_userattr_key2string(ldap_state->schema_ver,
     575             :                                 LDAP_ATTR_USER_SID),
     576             :                         get_userattr_key2string(ldap_state->schema_ver,
     577             :                                 LDAP_ATTR_USER_RID),
     578             :                         username));
     579           0 :                 return False;
     580             :         }
     581             : 
     582           0 :         temp = smbldap_talloc_single_attribute(
     583             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     584             :                         entry,
     585             :                         get_userattr_key2string(ldap_state->schema_ver,
     586             :                                 LDAP_ATTR_PWD_LAST_SET),
     587             :                         ctx);
     588           0 :         if (temp) {
     589           0 :                 pass_last_set_time = (time_t) atol(temp);
     590           0 :                 pdb_set_pass_last_set_time(sampass,
     591             :                                 pass_last_set_time, PDB_SET);
     592             :         }
     593             : 
     594           0 :         temp = smbldap_talloc_single_attribute(
     595             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     596             :                         entry,
     597             :                         get_userattr_key2string(ldap_state->schema_ver,
     598             :                                 LDAP_ATTR_LOGON_TIME),
     599             :                         ctx);
     600           0 :         if (temp) {
     601           0 :                 logon_time = (time_t) atol(temp);
     602           0 :                 pdb_set_logon_time(sampass, logon_time, PDB_SET);
     603             :         }
     604             : 
     605           0 :         temp = smbldap_talloc_single_attribute(
     606             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     607             :                         entry,
     608             :                         get_userattr_key2string(ldap_state->schema_ver,
     609             :                                 LDAP_ATTR_LOGOFF_TIME),
     610             :                         ctx);
     611           0 :         if (temp) {
     612           0 :                 logoff_time = (time_t) atol(temp);
     613           0 :                 pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
     614             :         }
     615             : 
     616           0 :         temp = smbldap_talloc_single_attribute(
     617             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     618             :                         entry,
     619             :                         get_userattr_key2string(ldap_state->schema_ver,
     620             :                                 LDAP_ATTR_KICKOFF_TIME),
     621             :                         ctx);
     622           0 :         if (temp) {
     623           0 :                 kickoff_time = (time_t) atol(temp);
     624           0 :                 pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
     625             :         }
     626             : 
     627           0 :         temp = smbldap_talloc_single_attribute(
     628             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     629             :                         entry,
     630             :                         get_userattr_key2string(ldap_state->schema_ver,
     631             :                                 LDAP_ATTR_PWD_CAN_CHANGE),
     632             :                         ctx);
     633           0 :         if (temp) {
     634           0 :                 pass_can_change_time = (time_t) atol(temp);
     635           0 :                 pdb_set_pass_can_change_time(sampass,
     636             :                                 pass_can_change_time, PDB_SET);
     637             :         }
     638             : 
     639             :         /* recommend that 'gecos' and 'displayName' should refer to the same
     640             :          * attribute OID.  userFullName depreciated, only used by Samba
     641             :          * primary rules of LDAP: don't make a new attribute when one is already defined
     642             :          * that fits your needs; using cn then displayName rather than 'userFullName'
     643             :          */
     644             : 
     645           0 :         fullname = smbldap_talloc_single_attribute(
     646             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     647             :                         entry,
     648             :                         get_userattr_key2string(ldap_state->schema_ver,
     649             :                                 LDAP_ATTR_DISPLAY_NAME),
     650             :                         ctx);
     651           0 :         if (fullname) {
     652           0 :                 pdb_set_fullname(sampass, fullname, PDB_SET);
     653             :         } else {
     654           0 :                 fullname = smbldap_talloc_single_attribute(
     655             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     656             :                                 entry,
     657             :                                 get_userattr_key2string(ldap_state->schema_ver,
     658             :                                         LDAP_ATTR_CN),
     659             :                                 ctx);
     660           0 :                 if (fullname) {
     661           0 :                         pdb_set_fullname(sampass, fullname, PDB_SET);
     662             :                 }
     663             :         }
     664             : 
     665           0 :         dir_drive = smbldap_talloc_single_attribute(
     666             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     667             :                         entry,
     668             :                         get_userattr_key2string(ldap_state->schema_ver,
     669             :                                 LDAP_ATTR_HOME_DRIVE),
     670             :                         ctx);
     671           0 :         if (dir_drive) {
     672           0 :                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
     673             :         } else {
     674           0 :                 pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
     675             :         }
     676             : 
     677           0 :         homedir = smbldap_talloc_single_attribute(
     678             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     679             :                         entry,
     680             :                         get_userattr_key2string(ldap_state->schema_ver,
     681             :                                 LDAP_ATTR_HOME_PATH),
     682             :                         ctx);
     683           0 :         if (homedir) {
     684           0 :                 if (expand_explicit) {
     685           0 :                         homedir = talloc_sub_basic(ctx,
     686             :                                                 username,
     687             :                                                 domain,
     688             :                                                 homedir);
     689           0 :                         if (!homedir) {
     690           0 :                                 goto fn_exit;
     691             :                         }
     692             :                 }
     693           0 :                 pdb_set_homedir(sampass, homedir, PDB_SET);
     694             :         } else {
     695           0 :                 pdb_set_homedir(sampass,
     696           0 :                         talloc_sub_basic(ctx, username, domain,
     697             :                                          lp_logon_home()),
     698             :                         PDB_DEFAULT);
     699             :         }
     700             : 
     701           0 :         logon_script = smbldap_talloc_single_attribute(
     702             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     703             :                         entry,
     704             :                         get_userattr_key2string(ldap_state->schema_ver,
     705             :                                 LDAP_ATTR_LOGON_SCRIPT),
     706             :                         ctx);
     707           0 :         if (logon_script) {
     708           0 :                 if (expand_explicit) {
     709           0 :                         logon_script = talloc_sub_basic(ctx,
     710             :                                                 username,
     711             :                                                 domain,
     712             :                                                 logon_script);
     713           0 :                         if (!logon_script) {
     714           0 :                                 goto fn_exit;
     715             :                         }
     716             :                 }
     717           0 :                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
     718             :         } else {
     719           0 :                 pdb_set_logon_script(sampass,
     720           0 :                         talloc_sub_basic(ctx, username, domain,
     721             :                                          lp_logon_script()),
     722             :                         PDB_DEFAULT );
     723             :         }
     724             : 
     725           0 :         profile_path = smbldap_talloc_single_attribute(
     726             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     727             :                         entry,
     728             :                         get_userattr_key2string(ldap_state->schema_ver,
     729             :                                 LDAP_ATTR_PROFILE_PATH),
     730             :                         ctx);
     731           0 :         if (profile_path) {
     732           0 :                 if (expand_explicit) {
     733           0 :                         profile_path = talloc_sub_basic(ctx,
     734             :                                                 username,
     735             :                                                 domain,
     736             :                                                 profile_path);
     737           0 :                         if (!profile_path) {
     738           0 :                                 goto fn_exit;
     739             :                         }
     740             :                 }
     741           0 :                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
     742             :         } else {
     743           0 :                 pdb_set_profile_path(sampass,
     744           0 :                         talloc_sub_basic(ctx, username, domain,
     745             :                                           lp_logon_path()),
     746             :                         PDB_DEFAULT );
     747             :         }
     748             : 
     749           0 :         acct_desc = smbldap_talloc_single_attribute(
     750             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     751             :                         entry,
     752             :                         get_userattr_key2string(ldap_state->schema_ver,
     753             :                                 LDAP_ATTR_DESC),
     754             :                         ctx);
     755           0 :         if (acct_desc) {
     756           0 :                 pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
     757             :         }
     758             : 
     759           0 :         workstations = smbldap_talloc_single_attribute(
     760             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     761             :                         entry,
     762             :                         get_userattr_key2string(ldap_state->schema_ver,
     763             :                                 LDAP_ATTR_USER_WKS),
     764             :                         ctx);
     765           0 :         if (workstations) {
     766           0 :                 pdb_set_workstations(sampass, workstations, PDB_SET);
     767             :         }
     768             : 
     769           0 :         munged_dial = smbldap_talloc_single_attribute(
     770             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     771             :                         entry,
     772             :                         get_userattr_key2string(ldap_state->schema_ver,
     773             :                                 LDAP_ATTR_MUNGED_DIAL),
     774             :                         ctx);
     775           0 :         if (munged_dial) {
     776           0 :                 pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
     777             :         }
     778             : 
     779             :         /* FIXME: hours stuff should be cleaner */
     780             : 
     781           0 :         logon_divs = 168;
     782           0 :         hours_len = 21;
     783           0 :         memset(hours, 0xff, hours_len);
     784             : 
     785           0 :         if (ldap_state->is_nds_ldap) {
     786           0 :                 char *user_dn;
     787           0 :                 size_t pwd_len;
     788           0 :                 char clear_text_pw[512];
     789             : 
     790             :                 /* Make call to Novell eDirectory ldap extension to get clear text password.
     791             :                         NOTE: This will only work if we have an SSL connection to eDirectory. */
     792           0 :                 user_dn = smbldap_talloc_dn(
     793             :                         ctx, smbldap_get_ldap(ldap_state->smbldap_state),
     794             :                         entry);
     795           0 :                 if (user_dn != NULL) {
     796           0 :                         DEBUG(3, ("init_sam_from_ldap: smbldap_talloc_dn(ctx, %s) returned '%s'\n", username, user_dn));
     797             : 
     798           0 :                         pwd_len = sizeof(clear_text_pw);
     799           0 :                         if (pdb_nds_get_password(ldap_state->smbldap_state, user_dn, &pwd_len, clear_text_pw) == LDAP_SUCCESS) {
     800           0 :                                 nt_lm_owf_gen(clear_text_pw, smbntpwd, smblmpwd);
     801           0 :                                 if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
     802           0 :                                         TALLOC_FREE(user_dn);
     803           0 :                                         return False;
     804             :                                 }
     805           0 :                                 ZERO_STRUCT(smblmpwd);
     806           0 :                                 if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
     807           0 :                                         TALLOC_FREE(user_dn);
     808           0 :                                         return False;
     809             :                                 }
     810           0 :                                 ZERO_STRUCT(smbntpwd);
     811           0 :                                 use_samba_attrs = False;
     812             :                         }
     813             : 
     814           0 :                         TALLOC_FREE(user_dn);
     815             : 
     816             :                 } else {
     817           0 :                         DEBUG(0, ("init_sam_from_ldap: failed to get user_dn for '%s'\n", username));
     818             :                 }
     819             :         }
     820             : 
     821           0 :         if (use_samba_attrs) {
     822           0 :                 temp = smbldap_talloc_single_attribute(
     823             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     824             :                                 entry,
     825             :                                 get_userattr_key2string(ldap_state->schema_ver,
     826             :                                         LDAP_ATTR_LMPW),
     827             :                                 ctx);
     828           0 :                 if (temp) {
     829           0 :                         pdb_gethexpwd(temp, smblmpwd);
     830           0 :                         memset((char *)temp, '\0', strlen(temp)+1);
     831           0 :                         if (!pdb_set_lanman_passwd(sampass, smblmpwd, PDB_SET)) {
     832           0 :                                 goto fn_exit;
     833             :                         }
     834           0 :                         ZERO_STRUCT(smblmpwd);
     835             :                 }
     836             : 
     837           0 :                 temp = smbldap_talloc_single_attribute(
     838             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     839             :                                 entry,
     840             :                                 get_userattr_key2string(ldap_state->schema_ver,
     841             :                                         LDAP_ATTR_NTPW),
     842             :                                 ctx);
     843           0 :                 if (temp) {
     844           0 :                         pdb_gethexpwd(temp, smbntpwd);
     845           0 :                         memset((char *)temp, '\0', strlen(temp)+1);
     846           0 :                         if (!pdb_set_nt_passwd(sampass, smbntpwd, PDB_SET)) {
     847           0 :                                 goto fn_exit;
     848             :                         }
     849           0 :                         ZERO_STRUCT(smbntpwd);
     850             :                 }
     851             :         }
     852             : 
     853           0 :         pwHistLen = 0;
     854             : 
     855           0 :         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
     856           0 :         if (pwHistLen > 0){
     857           0 :                 uint8_t *pwhist = NULL;
     858           0 :                 int i;
     859           0 :                 char *history_string = talloc_array(ctx, char,
     860             :                                                 MAX_PW_HISTORY_LEN*64);
     861             : 
     862           0 :                 if (!history_string) {
     863           0 :                         goto fn_exit;
     864             :                 }
     865             : 
     866           0 :                 pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
     867             : 
     868           0 :                 pwhist = talloc_zero_array(ctx, uint8_t,
     869             :                                            pwHistLen * PW_HISTORY_ENTRY_LEN);
     870           0 :                 if (pwhist == NULL) {
     871           0 :                         DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
     872           0 :                         goto fn_exit;
     873             :                 }
     874             : 
     875           0 :                 if (smbldap_get_single_attribute(
     876             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
     877             :                                 entry,
     878             :                                 get_userattr_key2string(ldap_state->schema_ver,
     879             :                                         LDAP_ATTR_PWD_HISTORY),
     880             :                                 history_string,
     881             :                                 MAX_PW_HISTORY_LEN*64)) {
     882           0 :                         bool hex_failed = false;
     883           0 :                         for (i = 0; i < pwHistLen; i++){
     884             :                                 /* Get the 16 byte salt. */
     885           0 :                                 if (!pdb_gethexpwd(&history_string[i*64],
     886           0 :                                         &pwhist[i*PW_HISTORY_ENTRY_LEN])) {
     887           0 :                                         hex_failed = true;
     888           0 :                                         break;
     889             :                                 }
     890             :                                 /* Get the 16 byte MD5 hash of salt+passwd. */
     891           0 :                                 if (!pdb_gethexpwd(&history_string[(i*64)+32],
     892           0 :                                         &pwhist[(i*PW_HISTORY_ENTRY_LEN)+
     893             :                                                 PW_HISTORY_SALT_LEN])) {
     894           0 :                                         hex_failed = True;
     895           0 :                                         break;
     896             :                                 }
     897             :                         }
     898           0 :                         if (hex_failed) {
     899           0 :                                 DEBUG(2,("init_sam_from_ldap: Failed to get password history for user %s\n",
     900             :                                         username));
     901           0 :                                 memset(pwhist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
     902             :                         }
     903             :                 }
     904           0 :                 if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
     905           0 :                         goto fn_exit;
     906             :                 }
     907             :         }
     908             : 
     909           0 :         temp = smbldap_talloc_single_attribute(
     910             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     911             :                         entry,
     912             :                         get_userattr_key2string(ldap_state->schema_ver,
     913             :                                 LDAP_ATTR_ACB_INFO),
     914             :                         ctx);
     915           0 :         if (temp) {
     916           0 :                 uint32_t acct_ctrl = 0;
     917           0 :                 acct_ctrl = pdb_decode_acct_ctrl(temp);
     918             : 
     919           0 :                 if (acct_ctrl == 0) {
     920           0 :                         acct_ctrl |= ACB_NORMAL;
     921             :                 }
     922             : 
     923           0 :                 pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
     924             :         }
     925             : 
     926           0 :         pdb_set_hours_len(sampass, hours_len, PDB_SET);
     927           0 :         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
     928             : 
     929           0 :         temp = smbldap_talloc_single_attribute(
     930             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     931             :                         entry,
     932             :                         get_userattr_key2string(ldap_state->schema_ver,
     933             :                                 LDAP_ATTR_BAD_PASSWORD_COUNT),
     934             :                         ctx);
     935           0 :         if (temp) {
     936           0 :                 bad_password_count = (uint32_t) atol(temp);
     937           0 :                 pdb_set_bad_password_count(sampass,
     938             :                                 bad_password_count, PDB_SET);
     939             :         }
     940             : 
     941           0 :         temp = smbldap_talloc_single_attribute(
     942             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     943             :                         entry,
     944             :                         get_userattr_key2string(ldap_state->schema_ver,
     945             :                                 LDAP_ATTR_BAD_PASSWORD_TIME),
     946             :                         ctx);
     947           0 :         if (temp) {
     948           0 :                 bad_password_time = (time_t) atol(temp);
     949           0 :                 pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
     950             :         }
     951             : 
     952             : 
     953           0 :         temp = smbldap_talloc_single_attribute(
     954             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     955             :                         entry,
     956             :                         get_userattr_key2string(ldap_state->schema_ver,
     957             :                                 LDAP_ATTR_LOGON_COUNT),
     958             :                         ctx);
     959           0 :         if (temp) {
     960           0 :                 logon_count = (uint32_t) atol(temp);
     961           0 :                 pdb_set_logon_count(sampass, logon_count, PDB_SET);
     962             :         }
     963             : 
     964             :         /* pdb_set_unknown_6(sampass, unknown6, PDB_SET); */
     965             : 
     966           0 :         temp = smbldap_talloc_single_attribute(
     967             :                         smbldap_get_ldap(ldap_state->smbldap_state),
     968             :                         entry,
     969             :                         get_userattr_key2string(ldap_state->schema_ver,
     970             :                                 LDAP_ATTR_LOGON_HOURS),
     971             :                         ctx);
     972           0 :         if (temp) {
     973           0 :                 pdb_gethexhours(temp, hours);
     974           0 :                 memset((char *)temp, '\0', strlen(temp) +1);
     975           0 :                 pdb_set_hours(sampass, hours, hours_len, PDB_SET);
     976           0 :                 ZERO_STRUCT(hours);
     977             :         }
     978             : 
     979           0 :         if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
     980           0 :                 struct passwd unix_pw;
     981           0 :                 bool have_uid = false;
     982           0 :                 bool have_gid = false;
     983           0 :                 struct dom_sid mapped_gsid;
     984           0 :                 const struct dom_sid *primary_gsid;
     985           0 :                 struct unixid id;
     986           0 :                 int error = 0;
     987             : 
     988           0 :                 ZERO_STRUCT(unix_pw);
     989             : 
     990           0 :                 unix_pw.pw_name = username;
     991           0 :                 unix_pw.pw_passwd = discard_const_p(char, "x");
     992             : 
     993           0 :                 temp = smbldap_talloc_single_attribute(
     994             :                                 priv2ld(ldap_state),
     995             :                                 entry,
     996             :                                 "uidNumber",
     997             :                                 ctx);
     998           0 :                 if (temp) {
     999             :                         /* We've got a uid, feed the cache */
    1000           0 :                         unix_pw.pw_uid = smb_strtoul(temp,
    1001             :                                                      NULL,
    1002             :                                                      10,
    1003             :                                                      &error,
    1004             :                                                      SMB_STR_STANDARD);
    1005           0 :                         if (error != 0) {
    1006           0 :                                 DBG_ERR("Failed to convert UID\n");
    1007           0 :                                 goto fn_exit;
    1008             :                         }
    1009           0 :                         have_uid = true;
    1010             :                 }
    1011           0 :                 temp = smbldap_talloc_single_attribute(
    1012             :                                 priv2ld(ldap_state),
    1013             :                                 entry,
    1014             :                                 "gidNumber",
    1015             :                                 ctx);
    1016           0 :                 if (temp) {
    1017             :                         /* We've got a uid, feed the cache */
    1018           0 :                         unix_pw.pw_gid = smb_strtoul(temp,
    1019             :                                                      NULL,
    1020             :                                                      10,
    1021             :                                                      &error,
    1022             :                                                      SMB_STR_STANDARD);
    1023           0 :                         if (error != 0) {
    1024           0 :                                 DBG_ERR("Failed to convert GID\n");
    1025           0 :                                 goto fn_exit;
    1026             :                         }
    1027           0 :                         have_gid = true;
    1028             :                 }
    1029           0 :                 unix_pw.pw_gecos = smbldap_talloc_single_attribute(
    1030             :                                 priv2ld(ldap_state),
    1031             :                                 entry,
    1032             :                                 "gecos",
    1033             :                                 ctx);
    1034           0 :                 if (unix_pw.pw_gecos == NULL) {
    1035           0 :                         unix_pw.pw_gecos = fullname;
    1036             :                 }
    1037           0 :                 unix_pw.pw_dir = smbldap_talloc_single_attribute(
    1038             :                                 priv2ld(ldap_state),
    1039             :                                 entry,
    1040             :                                 "homeDirectory",
    1041             :                                 ctx);
    1042           0 :                 if (unix_pw.pw_dir == NULL) {
    1043           0 :                         unix_pw.pw_dir = discard_const_p(char, "");
    1044             :                 }
    1045           0 :                 unix_pw.pw_shell = smbldap_talloc_single_attribute(
    1046             :                                 priv2ld(ldap_state),
    1047             :                                 entry,
    1048             :                                 "loginShell",
    1049             :                                 ctx);
    1050           0 :                 if (unix_pw.pw_shell == NULL) {
    1051           0 :                         unix_pw.pw_shell = discard_const_p(char, "");
    1052             :                 }
    1053             : 
    1054           0 :                 if (have_uid && have_gid) {
    1055           0 :                         sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);
    1056             :                 } else {
    1057           0 :                         sampass->unix_pw = Get_Pwnam_alloc(sampass, unix_pw.pw_name);
    1058             :                 }
    1059             : 
    1060           0 :                 if (sampass->unix_pw == NULL) {
    1061           0 :                         DEBUG(0,("init_sam_from_ldap: Failed to find Unix account for %s\n",
    1062             :                                  pdb_get_username(sampass)));
    1063           0 :                         goto fn_exit;
    1064             :                 }
    1065             : 
    1066           0 :                 id.id = sampass->unix_pw->pw_uid;
    1067           0 :                 id.type = ID_TYPE_UID;
    1068             : 
    1069           0 :                 idmap_cache_set_sid2unixid(pdb_get_user_sid(sampass), &id);
    1070             : 
    1071           0 :                 gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid);
    1072           0 :                 primary_gsid = pdb_get_group_sid(sampass);
    1073           0 :                 if (primary_gsid && dom_sid_equal(primary_gsid, &mapped_gsid)) {
    1074           0 :                         id.id = sampass->unix_pw->pw_gid;
    1075           0 :                         id.type = ID_TYPE_GID;
    1076             : 
    1077           0 :                         idmap_cache_set_sid2unixid(primary_gsid, &id);
    1078             :                 }
    1079             :         }
    1080             : 
    1081             :         /* check the timestamp of the cache vs ldap entry */
    1082           0 :         if (!(ldap_entry_time = ldapsam_get_entry_timestamp(ldap_state,
    1083             :                                                             entry))) {
    1084           0 :                 ret = true;
    1085           0 :                 goto fn_exit;
    1086             :         }
    1087             : 
    1088             :         /* see if we have newer updates */
    1089           0 :         if (!login_cache_read(sampass, &cache_entry)) {
    1090           0 :                 DEBUG (9, ("No cache entry, bad count = %u, bad time = %u\n",
    1091             :                            (unsigned int)pdb_get_bad_password_count(sampass),
    1092             :                            (unsigned int)pdb_get_bad_password_time(sampass)));
    1093           0 :                 ret = true;
    1094           0 :                 goto fn_exit;
    1095             :         }
    1096             : 
    1097           0 :         DEBUG(7, ("ldap time is %u, cache time is %u, bad time = %u\n",
    1098             :                   (unsigned int)ldap_entry_time,
    1099             :                   (unsigned int)cache_entry.entry_timestamp,
    1100             :                   (unsigned int)cache_entry.bad_password_time));
    1101             : 
    1102           0 :         if (ldap_entry_time > cache_entry.entry_timestamp) {
    1103             :                 /* cache is older than directory , so
    1104             :                    we need to delete the entry but allow the
    1105             :                    fields to be written out */
    1106           0 :                 login_cache_delentry(sampass);
    1107             :         } else {
    1108             :                 /* read cache in */
    1109           0 :                 pdb_set_acct_ctrl(sampass,
    1110           0 :                                   pdb_get_acct_ctrl(sampass) |
    1111           0 :                                   (cache_entry.acct_ctrl & ACB_AUTOLOCK),
    1112             :                                   PDB_SET);
    1113           0 :                 pdb_set_bad_password_count(sampass,
    1114           0 :                                            cache_entry.bad_password_count,
    1115             :                                            PDB_SET);
    1116           0 :                 pdb_set_bad_password_time(sampass,
    1117             :                                           cache_entry.bad_password_time,
    1118             :                                           PDB_SET);
    1119             :         }
    1120             : 
    1121           0 :         ret = true;
    1122             : 
    1123           0 :   fn_exit:
    1124             : 
    1125           0 :         TALLOC_FREE(ctx);
    1126           0 :         return ret;
    1127             : }
    1128             : 
    1129             : /**********************************************************************
    1130             :  Initialize the ldap db from a struct samu. Called on update.
    1131             :  (Based on init_buffer_from_sam in pdb_tdb.c)
    1132             : *********************************************************************/
    1133             : 
    1134           0 : static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
    1135             :                                 LDAPMessage *existing,
    1136             :                                 LDAPMod *** mods, struct samu * sampass,
    1137             :                                 bool (*need_update)(const struct samu *,
    1138             :                                                     enum pdb_elements))
    1139             : {
    1140           0 :         char *temp = NULL;
    1141             : 
    1142           0 :         if (mods == NULL || sampass == NULL) {
    1143           0 :                 DEBUG(0, ("init_ldap_from_sam: NULL parameters found!\n"));
    1144           0 :                 return False;
    1145             :         }
    1146             : 
    1147           0 :         *mods = NULL;
    1148             : 
    1149             :         /*
    1150             :          * took out adding "objectclass: sambaAccount"
    1151             :          * do this on a per-mod basis
    1152             :          */
    1153           0 :         if (need_update(sampass, PDB_USERNAME)) {
    1154           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1155             :                                  existing, mods,
    1156             :                                  "uid", pdb_get_username(sampass));
    1157           0 :                 if (ldap_state->is_nds_ldap) {
    1158           0 :                         smbldap_make_mod(
    1159             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1160             :                                 existing, mods,
    1161             :                                 "cn", pdb_get_username(sampass));
    1162           0 :                         smbldap_make_mod(
    1163             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1164             :                                 existing, mods,
    1165             :                                 "sn", pdb_get_username(sampass));
    1166             :                 }
    1167             :         }
    1168             : 
    1169           0 :         DEBUG(2, ("init_ldap_from_sam: Setting entry for user: %s\n", pdb_get_username(sampass)));
    1170             : 
    1171             :         /* only update the RID if we actually need to */
    1172           0 :         if (need_update(sampass, PDB_USERSID)) {
    1173           0 :                 struct dom_sid_buf sid_str;
    1174           0 :                 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
    1175             : 
    1176           0 :                 switch ( ldap_state->schema_ver ) {
    1177           0 :                         case SCHEMAVER_SAMBASAMACCOUNT:
    1178           0 :                                 smbldap_make_mod(
    1179             :                                         smbldap_get_ldap(
    1180             :                                                 ldap_state->smbldap_state),
    1181             :                                         existing, mods,
    1182             :                                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
    1183           0 :                                         dom_sid_str_buf(user_sid, &sid_str));
    1184           0 :                                 break;
    1185             : 
    1186           0 :                         default:
    1187           0 :                                 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
    1188           0 :                                 break;
    1189             :                 }
    1190             :         }
    1191             : 
    1192             :         /* we don't need to store the primary group RID - so leaving it
    1193             :            'free' to hang off the unix primary group makes life easier */
    1194             : 
    1195           0 :         if (need_update(sampass, PDB_GROUPSID)) {
    1196           0 :                 struct dom_sid_buf sid_str;
    1197           0 :                 const struct dom_sid *group_sid = pdb_get_group_sid(sampass);
    1198             : 
    1199           0 :                 switch ( ldap_state->schema_ver ) {
    1200           0 :                         case SCHEMAVER_SAMBASAMACCOUNT:
    1201           0 :                                 smbldap_make_mod(
    1202             :                                         smbldap_get_ldap(
    1203             :                                                 ldap_state->smbldap_state),
    1204             :                                         existing, mods,
    1205             :                                         get_userattr_key2string(ldap_state->schema_ver,
    1206             :                                         LDAP_ATTR_PRIMARY_GROUP_SID),
    1207           0 :                                         dom_sid_str_buf(group_sid, &sid_str));
    1208           0 :                                 break;
    1209             : 
    1210           0 :                         default:
    1211           0 :                                 DEBUG(0,("init_ldap_from_sam: unknown schema version specified\n"));
    1212           0 :                                 break;
    1213             :                 }
    1214             : 
    1215             :         }
    1216             : 
    1217             :         /* displayName, cn, and gecos should all be the same
    1218             :          *  most easily accomplished by giving them the same OID
    1219             :          *  gecos isn't set here b/c it should be handled by the
    1220             :          *  add-user script
    1221             :          *  We change displayName only and fall back to cn if
    1222             :          *  it does not exist.
    1223             :          */
    1224             : 
    1225           0 :         if (need_update(sampass, PDB_FULLNAME))
    1226           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1227             :                                  existing, mods,
    1228             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
    1229             :                         pdb_get_fullname(sampass));
    1230             : 
    1231           0 :         if (need_update(sampass, PDB_ACCTDESC))
    1232           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1233             :                                  existing, mods,
    1234             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
    1235             :                         pdb_get_acct_desc(sampass));
    1236             : 
    1237           0 :         if (need_update(sampass, PDB_WORKSTATIONS))
    1238           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1239             :                                  existing, mods,
    1240             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
    1241             :                         pdb_get_workstations(sampass));
    1242             : 
    1243           0 :         if (need_update(sampass, PDB_MUNGEDDIAL))
    1244           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1245             :                                  existing, mods,
    1246             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL),
    1247             :                         pdb_get_munged_dial(sampass));
    1248             : 
    1249           0 :         if (need_update(sampass, PDB_SMBHOME))
    1250           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1251             :                                  existing, mods,
    1252             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
    1253             :                         pdb_get_homedir(sampass));
    1254             : 
    1255           0 :         if (need_update(sampass, PDB_DRIVE))
    1256           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1257             :                                  existing, mods,
    1258             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
    1259             :                         pdb_get_dir_drive(sampass));
    1260             : 
    1261           0 :         if (need_update(sampass, PDB_LOGONSCRIPT))
    1262           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1263             :                                  existing, mods,
    1264             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
    1265             :                         pdb_get_logon_script(sampass));
    1266             : 
    1267           0 :         if (need_update(sampass, PDB_PROFILE))
    1268           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1269             :                                  existing, mods,
    1270             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
    1271             :                         pdb_get_profile_path(sampass));
    1272             : 
    1273           0 :         if (asprintf(&temp, "%li", (long int)pdb_get_logon_time(sampass)) < 0) {
    1274           0 :                 return false;
    1275             :         }
    1276           0 :         if (need_update(sampass, PDB_LOGONTIME))
    1277           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1278             :                                  existing, mods,
    1279             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
    1280           0 :         SAFE_FREE(temp);
    1281             : 
    1282           0 :         if (asprintf(&temp, "%li", (long int)pdb_get_logoff_time(sampass)) < 0) {
    1283           0 :                 return false;
    1284             :         }
    1285           0 :         if (need_update(sampass, PDB_LOGOFFTIME))
    1286           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1287             :                                  existing, mods,
    1288             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
    1289           0 :         SAFE_FREE(temp);
    1290             : 
    1291           0 :         if (asprintf(&temp, "%li", (long int)pdb_get_kickoff_time(sampass)) < 0) {
    1292           0 :                 return false;
    1293             :         }
    1294           0 :         if (need_update(sampass, PDB_KICKOFFTIME))
    1295           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1296             :                                  existing, mods,
    1297             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
    1298           0 :         SAFE_FREE(temp);
    1299             : 
    1300           0 :         if (asprintf(&temp, "%li", (long int)pdb_get_pass_can_change_time_noncalc(sampass)) < 0) {
    1301           0 :                 return false;
    1302             :         }
    1303           0 :         if (need_update(sampass, PDB_CANCHANGETIME))
    1304           0 :                 smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state),
    1305             :                                  existing, mods,
    1306             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
    1307           0 :         SAFE_FREE(temp);
    1308             : 
    1309           0 :         if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
    1310           0 :                         || (lp_ldap_passwd_sync()!=LDAP_PASSWD_SYNC_ONLY)) {
    1311             : 
    1312           0 :                 if (need_update(sampass, PDB_LMPASSWD)) {
    1313           0 :                         const uchar *lm_pw = pdb_get_lanman_passwd(sampass);
    1314           0 :                         if (lm_pw) {
    1315           0 :                                 char pwstr[34];
    1316           0 :                                 pdb_sethexpwd(pwstr, lm_pw,
    1317             :                                               pdb_get_acct_ctrl(sampass));
    1318           0 :                                 smbldap_make_mod(
    1319             :                                         smbldap_get_ldap(
    1320             :                                                 ldap_state->smbldap_state),
    1321             :                                         existing, mods,
    1322             :                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
    1323             :                                                  pwstr);
    1324             :                         } else {
    1325           0 :                                 smbldap_make_mod(
    1326             :                                         smbldap_get_ldap(
    1327             :                                                 ldap_state->smbldap_state),
    1328             :                                         existing, mods,
    1329             :                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
    1330             :                                                  NULL);
    1331             :                         }
    1332             :                 }
    1333           0 :                 if (need_update(sampass, PDB_NTPASSWD)) {
    1334           0 :                         const uchar *nt_pw = pdb_get_nt_passwd(sampass);
    1335           0 :                         if (nt_pw) {
    1336           0 :                                 char pwstr[34];
    1337           0 :                                 pdb_sethexpwd(pwstr, nt_pw,
    1338             :                                               pdb_get_acct_ctrl(sampass));
    1339           0 :                                 smbldap_make_mod(
    1340             :                                         smbldap_get_ldap(
    1341             :                                                 ldap_state->smbldap_state),
    1342             :                                         existing, mods,
    1343             :                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
    1344             :                                                  pwstr);
    1345             :                         } else {
    1346           0 :                                 smbldap_make_mod(
    1347             :                                         smbldap_get_ldap(
    1348             :                                                 ldap_state->smbldap_state),
    1349             :                                         existing, mods,
    1350             :                                                  get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
    1351             :                                                  NULL);
    1352             :                         }
    1353             :                 }
    1354             : 
    1355           0 :                 if (need_update(sampass, PDB_PWHISTORY)) {
    1356           0 :                         char *pwstr = NULL;
    1357           0 :                         uint32_t pwHistLen = 0;
    1358           0 :                         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
    1359             : 
    1360           0 :                         pwstr = SMB_MALLOC_ARRAY(char, 1024);
    1361           0 :                         if (!pwstr) {
    1362           0 :                                 return false;
    1363             :                         }
    1364           0 :                         if (pwHistLen == 0) {
    1365             :                                 /* Remove any password history from the LDAP store. */
    1366           0 :                                 memset(pwstr, '0', 64); /* NOTE !!!! '0' *NOT '\0' */
    1367           0 :                                 pwstr[64] = '\0';
    1368             :                         } else {
    1369           0 :                                 int i;
    1370           0 :                                 uint32_t currHistLen = 0;
    1371           0 :                                 const uint8_t *pwhist = pdb_get_pw_history(sampass, &currHistLen);
    1372           0 :                                 if (pwhist != NULL) {
    1373             :                                         /* We can only store (1024-1/64 password history entries. */
    1374           0 :                                         pwHistLen = MIN(pwHistLen, ((1024-1)/64));
    1375           0 :                                         for (i=0; i< pwHistLen && i < currHistLen; i++) {
    1376             :                                                 /* Store the salt. */
    1377           0 :                                                 pdb_sethexpwd(&pwstr[i*64], &pwhist[i*PW_HISTORY_ENTRY_LEN], 0);
    1378             :                                                 /* Followed by the md5 hash of salt + md4 hash */
    1379           0 :                                                 pdb_sethexpwd(&pwstr[(i*64)+32],
    1380           0 :                                                         &pwhist[(i*PW_HISTORY_ENTRY_LEN)+PW_HISTORY_SALT_LEN], 0);
    1381           0 :                                                 DEBUG(100, ("pwstr=%s\n", pwstr));
    1382             :                                         }
    1383             :                                 }
    1384             :                         }
    1385           0 :                         smbldap_make_mod(
    1386             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1387             :                                 existing, mods,
    1388             :                                          get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
    1389             :                                          pwstr);
    1390           0 :                         SAFE_FREE(pwstr);
    1391             :                 }
    1392             : 
    1393           0 :                 if (need_update(sampass, PDB_PASSLASTSET)) {
    1394           0 :                         if (asprintf(&temp, "%li",
    1395           0 :                                 (long int)pdb_get_pass_last_set_time(sampass)) < 0) {
    1396           0 :                                 return false;
    1397             :                         }
    1398           0 :                         smbldap_make_mod(
    1399             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1400             :                                 existing, mods,
    1401             :                                 get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
    1402             :                                 temp);
    1403           0 :                         SAFE_FREE(temp);
    1404             :                 }
    1405             :         }
    1406             : 
    1407           0 :         if (need_update(sampass, PDB_HOURS)) {
    1408           0 :                 const uint8_t *hours = pdb_get_hours(sampass);
    1409           0 :                 if (hours) {
    1410           0 :                         char hourstr[44];
    1411           0 :                         pdb_sethexhours(hourstr, hours);
    1412           0 :                         smbldap_make_mod(
    1413             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1414             :                                 existing,
    1415             :                                 mods,
    1416             :                                 get_userattr_key2string(ldap_state->schema_ver,
    1417             :                                                 LDAP_ATTR_LOGON_HOURS),
    1418             :                                 hourstr);
    1419             :                 }
    1420             :         }
    1421             : 
    1422           0 :         if (need_update(sampass, PDB_ACCTCTRL))
    1423           0 :                 smbldap_make_mod(
    1424             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    1425             :                         existing, mods,
    1426             :                         get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
    1427           0 :                         pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
    1428             : 
    1429             :         /* password lockout cache:
    1430             :            - If we are now autolocking or clearing, we write to ldap
    1431             :            - If we are clearing, we delete the cache entry
    1432             :            - If the count is > 0, we update the cache
    1433             : 
    1434             :            This even means when autolocking, we cache, just in case the
    1435             :            update doesn't work, and we have to cache the autolock flag */
    1436             : 
    1437           0 :         if (need_update(sampass, PDB_BAD_PASSWORD_COUNT))  /* &&
    1438             :             need_update(sampass, PDB_BAD_PASSWORD_TIME)) */ {
    1439           0 :                 uint16_t badcount = pdb_get_bad_password_count(sampass);
    1440           0 :                 time_t badtime = pdb_get_bad_password_time(sampass);
    1441           0 :                 uint32_t pol;
    1442           0 :                 pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
    1443             : 
    1444           0 :                 DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
    1445             :                         (unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
    1446             : 
    1447           0 :                 if ((badcount >= pol) || (badcount == 0)) {
    1448           0 :                         DEBUG(7, ("making mods to update ldap, count=%u, time=%u\n",
    1449             :                                 (unsigned int)badcount, (unsigned int)badtime));
    1450           0 :                         if (asprintf(&temp, "%li", (long)badcount) < 0) {
    1451           0 :                                 return false;
    1452             :                         }
    1453           0 :                         smbldap_make_mod(
    1454             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1455             :                                 existing, mods,
    1456             :                                 get_userattr_key2string(
    1457             :                                         ldap_state->schema_ver,
    1458             :                                         LDAP_ATTR_BAD_PASSWORD_COUNT),
    1459             :                                 temp);
    1460           0 :                         SAFE_FREE(temp);
    1461             : 
    1462           0 :                         if (asprintf(&temp, "%li", (long int)badtime) < 0) {
    1463           0 :                                 return false;
    1464             :                         }
    1465           0 :                         smbldap_make_mod(
    1466             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1467             :                                 existing, mods,
    1468             :                                 get_userattr_key2string(
    1469             :                                         ldap_state->schema_ver,
    1470             :                                         LDAP_ATTR_BAD_PASSWORD_TIME),
    1471             :                                 temp);
    1472           0 :                         SAFE_FREE(temp);
    1473             :                 }
    1474           0 :                 if (badcount == 0) {
    1475           0 :                         DEBUG(7, ("bad password count is reset, deleting login cache entry for %s\n", pdb_get_nt_username(sampass)));
    1476           0 :                         login_cache_delentry(sampass);
    1477             :                 } else {
    1478           0 :                         struct login_cache cache_entry;
    1479             : 
    1480           0 :                         cache_entry.entry_timestamp = time(NULL);
    1481           0 :                         cache_entry.acct_ctrl = pdb_get_acct_ctrl(sampass);
    1482           0 :                         cache_entry.bad_password_count = badcount;
    1483           0 :                         cache_entry.bad_password_time = badtime;
    1484             : 
    1485           0 :                         DEBUG(7, ("Updating bad password count and time in login cache\n"));
    1486           0 :                         login_cache_write(sampass, &cache_entry);
    1487             :                 }
    1488             :         }
    1489             : 
    1490           0 :         return True;
    1491             : }
    1492             : 
    1493             : /**********************************************************************
    1494             :  End enumeration of the LDAP password list.
    1495             : *********************************************************************/
    1496             : 
    1497           0 : static void ldapsam_endsampwent(struct pdb_methods *my_methods)
    1498             : {
    1499           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    1500           0 :         if (ldap_state->result) {
    1501           0 :                 ldap_msgfree(ldap_state->result);
    1502           0 :                 ldap_state->result = NULL;
    1503             :         }
    1504           0 : }
    1505             : 
    1506           0 : static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
    1507             :                         const char *new_attr)
    1508             : {
    1509           0 :         int i;
    1510             : 
    1511           0 :         if (new_attr == NULL) {
    1512           0 :                 return;
    1513             :         }
    1514             : 
    1515           0 :         for (i=0; (*attr_list)[i] != NULL; i++) {
    1516           0 :                 ;
    1517             :         }
    1518             : 
    1519           0 :         (*attr_list) = talloc_realloc(mem_ctx, (*attr_list),
    1520             :                                             const char *,  i+2);
    1521           0 :         SMB_ASSERT((*attr_list) != NULL);
    1522           0 :         (*attr_list)[i] = talloc_strdup((*attr_list), new_attr);
    1523           0 :         (*attr_list)[i+1] = NULL;
    1524             : }
    1525             : 
    1526           0 : static void ldapsam_add_unix_attributes(TALLOC_CTX *mem_ctx,
    1527             :                                         const char ***attr_list)
    1528             : {
    1529           0 :         append_attr(mem_ctx, attr_list, "uidNumber");
    1530           0 :         append_attr(mem_ctx, attr_list, "gidNumber");
    1531           0 :         append_attr(mem_ctx, attr_list, "homeDirectory");
    1532           0 :         append_attr(mem_ctx, attr_list, "loginShell");
    1533           0 :         append_attr(mem_ctx, attr_list, "gecos");
    1534           0 : }
    1535             : 
    1536             : /**********************************************************************
    1537             : Get struct samu entry from LDAP by username.
    1538             : *********************************************************************/
    1539             : 
    1540           0 : static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu *user, const char *sname)
    1541             : {
    1542           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    1543           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    1544           0 :         LDAPMessage *result = NULL;
    1545           0 :         LDAPMessage *entry = NULL;
    1546           0 :         int count;
    1547           0 :         const char ** attr_list;
    1548           0 :         int rc;
    1549             : 
    1550           0 :         attr_list = get_userattr_list( user, ldap_state->schema_ver );
    1551           0 :         append_attr(user, &attr_list,
    1552             :                     get_userattr_key2string(ldap_state->schema_ver,
    1553             :                                             LDAP_ATTR_MOD_TIMESTAMP));
    1554           0 :         ldapsam_add_unix_attributes(user, &attr_list);
    1555           0 :         rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result,
    1556             :                                            attr_list);
    1557           0 :         TALLOC_FREE( attr_list );
    1558             : 
    1559           0 :         if ( rc != LDAP_SUCCESS )
    1560           0 :                 return NT_STATUS_NO_SUCH_USER;
    1561             : 
    1562           0 :         count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    1563             :                                    result);
    1564             : 
    1565           0 :         if (count < 1) {
    1566           0 :                 DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
    1567           0 :                 ldap_msgfree(result);
    1568           0 :                 return NT_STATUS_NO_SUCH_USER;
    1569           0 :         } else if (count > 1) {
    1570           0 :                 DEBUG(1, ("ldapsam_getsampwnam: Duplicate entries for this user [%s] Failing. count=%d\n", sname, count));
    1571           0 :                 ldap_msgfree(result);
    1572           0 :                 return NT_STATUS_NO_SUCH_USER;
    1573             :         }
    1574             : 
    1575           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    1576             :                                  result);
    1577           0 :         if (entry) {
    1578           0 :                 if (!init_sam_from_ldap(ldap_state, user, entry)) {
    1579           0 :                         DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
    1580           0 :                         ldap_msgfree(result);
    1581           0 :                         return NT_STATUS_NO_SUCH_USER;
    1582             :                 }
    1583           0 :                 pdb_set_backend_private_data(user, result, NULL,
    1584             :                                              my_methods, PDB_CHANGED);
    1585           0 :                 smbldap_talloc_autofree_ldapmsg(user, result);
    1586           0 :                 ret = NT_STATUS_OK;
    1587             :         } else {
    1588           0 :                 ldap_msgfree(result);
    1589             :         }
    1590           0 :         return ret;
    1591             : }
    1592             : 
    1593           0 : static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
    1594             :                                    const struct dom_sid *sid, LDAPMessage **result)
    1595             : {
    1596           0 :         int rc = -1;
    1597           0 :         const char ** attr_list;
    1598             : 
    1599           0 :         switch ( ldap_state->schema_ver ) {
    1600           0 :                 case SCHEMAVER_SAMBASAMACCOUNT: {
    1601           0 :                         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
    1602           0 :                         if (tmp_ctx == NULL) {
    1603           0 :                                 return LDAP_NO_MEMORY;
    1604             :                         }
    1605             : 
    1606           0 :                         attr_list = get_userattr_list(tmp_ctx,
    1607             :                                                       ldap_state->schema_ver);
    1608           0 :                         append_attr(tmp_ctx, &attr_list,
    1609             :                                     get_userattr_key2string(
    1610             :                                             ldap_state->schema_ver,
    1611             :                                             LDAP_ATTR_MOD_TIMESTAMP));
    1612           0 :                         ldapsam_add_unix_attributes(tmp_ctx, &attr_list);
    1613           0 :                         rc = ldapsam_search_suffix_by_sid(ldap_state, sid,
    1614             :                                                           result, attr_list);
    1615           0 :                         TALLOC_FREE(tmp_ctx);
    1616             : 
    1617           0 :                         if ( rc != LDAP_SUCCESS )
    1618           0 :                                 return rc;
    1619           0 :                         break;
    1620             :                 }
    1621             : 
    1622           0 :                 default:
    1623           0 :                         DEBUG(0,("Invalid schema version specified\n"));
    1624           0 :                         break;
    1625             :         }
    1626           0 :         return rc;
    1627             : }
    1628             : 
    1629             : /**********************************************************************
    1630             :  Get struct samu entry from LDAP by SID.
    1631             : *********************************************************************/
    1632             : 
    1633           0 : static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu * user, const struct dom_sid *sid)
    1634             : {
    1635           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    1636           0 :         LDAPMessage *result = NULL;
    1637           0 :         LDAPMessage *entry = NULL;
    1638           0 :         int count;
    1639           0 :         int rc;
    1640             : 
    1641           0 :         rc = ldapsam_get_ldap_user_by_sid(ldap_state,
    1642             :                                           sid, &result);
    1643           0 :         if (rc != LDAP_SUCCESS)
    1644           0 :                 return NT_STATUS_NO_SUCH_USER;
    1645             : 
    1646           0 :         count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    1647             :                                    result);
    1648             : 
    1649           0 :         if (count < 1) {
    1650           0 :                 struct dom_sid_buf buf;
    1651           0 :                 DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
    1652             :                           "count=%d\n",
    1653             :                           dom_sid_str_buf(sid, &buf),
    1654             :                           count));
    1655           0 :                 ldap_msgfree(result);
    1656           0 :                 return NT_STATUS_NO_SUCH_USER;
    1657           0 :         }  else if (count > 1) {
    1658           0 :                 struct dom_sid_buf buf;
    1659           0 :                 DEBUG(1, ("ldapsam_getsampwsid: More than one user with SID "
    1660             :                           "[%s]. Failing. count=%d\n",
    1661             :                           dom_sid_str_buf(sid, &buf),
    1662             :                           count));
    1663           0 :                 ldap_msgfree(result);
    1664           0 :                 return NT_STATUS_NO_SUCH_USER;
    1665             :         }
    1666             : 
    1667           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    1668             :                                  result);
    1669           0 :         if (!entry) {
    1670           0 :                 ldap_msgfree(result);
    1671           0 :                 return NT_STATUS_NO_SUCH_USER;
    1672             :         }
    1673             : 
    1674           0 :         if (!init_sam_from_ldap(ldap_state, user, entry)) {
    1675           0 :                 DEBUG(1,("ldapsam_getsampwsid: init_sam_from_ldap failed!\n"));
    1676           0 :                 ldap_msgfree(result);
    1677           0 :                 return NT_STATUS_NO_SUCH_USER;
    1678             :         }
    1679             : 
    1680           0 :         pdb_set_backend_private_data(user, result, NULL,
    1681             :                                      my_methods, PDB_CHANGED);
    1682           0 :         smbldap_talloc_autofree_ldapmsg(user, result);
    1683           0 :         return NT_STATUS_OK;
    1684             : }
    1685             : 
    1686             : /********************************************************************
    1687             :  Do the actual modification - also change a plaintext password if
    1688             :  it it set.
    1689             : **********************************************************************/
    1690             : 
    1691           0 : static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
    1692             :                                      struct samu *newpwd, char *dn,
    1693             :                                      LDAPMod **mods, int ldap_op,
    1694             :                                      bool (*need_update)(const struct samu *, enum pdb_elements))
    1695             : {
    1696           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    1697           0 :         int rc;
    1698             : 
    1699           0 :         if (!newpwd || !dn) {
    1700           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1701             :         }
    1702             : 
    1703           0 :         if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
    1704           0 :                         (lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
    1705           0 :                         need_update(newpwd, PDB_PLAINTEXT_PW) &&
    1706           0 :                         (pdb_get_plaintext_passwd(newpwd)!=NULL)) {
    1707           0 :                 BerElement *ber;
    1708           0 :                 struct berval *bv;
    1709           0 :                 char *retoid = NULL;
    1710           0 :                 struct berval *retdata = NULL;
    1711           0 :                 char *utf8_password;
    1712           0 :                 char *utf8_dn;
    1713           0 :                 size_t converted_size;
    1714           0 :                 int ret;
    1715             : 
    1716           0 :                 if (!ldap_state->is_nds_ldap) {
    1717             : 
    1718           0 :                         if (!smbldap_has_extension(
    1719             :                                     smbldap_get_ldap(
    1720             :                                             ldap_state->smbldap_state),
    1721             :                                     LDAP_EXOP_MODIFY_PASSWD)) {
    1722           0 :                                 DEBUG(2, ("ldap password change requested, but LDAP "
    1723             :                                           "server does not support it -- ignoring\n"));
    1724           0 :                                 return NT_STATUS_OK;
    1725             :                         }
    1726             :                 }
    1727             : 
    1728           0 :                 if (!push_utf8_talloc(talloc_tos(), &utf8_password,
    1729             :                                         pdb_get_plaintext_passwd(newpwd),
    1730             :                                         &converted_size))
    1731             :                 {
    1732           0 :                         return NT_STATUS_NO_MEMORY;
    1733             :                 }
    1734             : 
    1735           0 :                 if (!push_utf8_talloc(talloc_tos(), &utf8_dn, dn, &converted_size)) {
    1736           0 :                         TALLOC_FREE(utf8_password);
    1737           0 :                         return NT_STATUS_NO_MEMORY;
    1738             :                 }
    1739             : 
    1740           0 :                 if ((ber = ber_alloc_t(LBER_USE_DER))==NULL) {
    1741           0 :                         DEBUG(0,("ber_alloc_t returns NULL\n"));
    1742           0 :                         TALLOC_FREE(utf8_password);
    1743           0 :                         TALLOC_FREE(utf8_dn);
    1744           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1745             :                 }
    1746             : 
    1747           0 :                 if ((ber_printf (ber, "{") < 0) ||
    1748           0 :                     (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
    1749             :                                  utf8_dn) < 0)) {
    1750           0 :                         DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
    1751             :                                  "value <0\n"));
    1752           0 :                         ber_free(ber,1);
    1753           0 :                         TALLOC_FREE(utf8_dn);
    1754           0 :                         TALLOC_FREE(utf8_password);
    1755           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1756             :                 }
    1757             : 
    1758           0 :                 if ((utf8_password != NULL) && (*utf8_password != '\0')) {
    1759           0 :                         ret = ber_printf(ber, "ts}",
    1760             :                                          LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
    1761             :                                          utf8_password);
    1762             :                 } else {
    1763           0 :                         ret = ber_printf(ber, "}");
    1764             :                 }
    1765             : 
    1766           0 :                 if (ret < 0) {
    1767           0 :                         DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
    1768             :                                  "value <0\n"));
    1769           0 :                         ber_free(ber,1);
    1770           0 :                         TALLOC_FREE(utf8_dn);
    1771           0 :                         TALLOC_FREE(utf8_password);
    1772           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1773             :                 }
    1774             : 
    1775           0 :                 if ((rc = ber_flatten (ber, &bv))<0) {
    1776           0 :                         DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
    1777           0 :                         ber_free(ber,1);
    1778           0 :                         TALLOC_FREE(utf8_dn);
    1779           0 :                         TALLOC_FREE(utf8_password);
    1780           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1781             :                 }
    1782             : 
    1783           0 :                 TALLOC_FREE(utf8_dn);
    1784           0 :                 TALLOC_FREE(utf8_password);
    1785           0 :                 ber_free(ber, 1);
    1786             : 
    1787           0 :                 if (!ldap_state->is_nds_ldap) {
    1788           0 :                         rc = smbldap_extended_operation(ldap_state->smbldap_state,
    1789             :                                                         LDAP_EXOP_MODIFY_PASSWD,
    1790             :                                                         bv, NULL, NULL, &retoid,
    1791             :                                                         &retdata);
    1792             :                 } else {
    1793           0 :                         rc = pdb_nds_set_password(ldap_state->smbldap_state, dn,
    1794             :                                                         pdb_get_plaintext_passwd(newpwd));
    1795             :                 }
    1796           0 :                 if (rc != LDAP_SUCCESS) {
    1797           0 :                         char *ld_error = NULL;
    1798             : 
    1799           0 :                         if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
    1800           0 :                                 DEBUG(3, ("Could not set userPassword "
    1801             :                                           "attribute due to an objectClass "
    1802             :                                           "violation -- ignoring\n"));
    1803           0 :                                 ber_bvfree(bv);
    1804           0 :                                 return NT_STATUS_OK;
    1805             :                         }
    1806             : 
    1807           0 :                         ldap_get_option(
    1808             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    1809             :                                 LDAP_OPT_ERROR_STRING,
    1810             :                                         &ld_error);
    1811           0 :                         DEBUG(0,("ldapsam_modify_entry: LDAP Password could not be changed for user %s: %s\n\t%s\n",
    1812             :                                 pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
    1813           0 :                         SAFE_FREE(ld_error);
    1814           0 :                         ber_bvfree(bv);
    1815             : #if defined(LDAP_CONSTRAINT_VIOLATION)
    1816           0 :                         if (rc == LDAP_CONSTRAINT_VIOLATION)
    1817           0 :                                 return NT_STATUS_PASSWORD_RESTRICTION;
    1818             : #endif
    1819           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1820             :                 } else {
    1821           0 :                         DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
    1822             : #ifdef DEBUG_PASSWORD
    1823           0 :                         DEBUG(100,("ldapsam_modify_entry: LDAP Password changed to %s\n",pdb_get_plaintext_passwd(newpwd)));
    1824             : #endif
    1825           0 :                         if (retdata)
    1826           0 :                                 ber_bvfree(retdata);
    1827           0 :                         if (retoid)
    1828           0 :                                 ldap_memfree(retoid);
    1829             :                 }
    1830           0 :                 ber_bvfree(bv);
    1831             :         }
    1832             : 
    1833           0 :         if (!mods) {
    1834           0 :                 DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
    1835             :                 /* may be password change below however */
    1836             :         } else {
    1837           0 :                 switch(ldap_op) {
    1838           0 :                         case LDAP_MOD_ADD:
    1839           0 :                                 if (ldap_state->is_nds_ldap) {
    1840           0 :                                         smbldap_set_mod(&mods, LDAP_MOD_ADD,
    1841             :                                                         "objectclass",
    1842             :                                                         "inetOrgPerson");
    1843             :                                 } else {
    1844           0 :                                         smbldap_set_mod(&mods, LDAP_MOD_ADD,
    1845             :                                                         "objectclass",
    1846             :                                                         LDAP_OBJ_ACCOUNT);
    1847             :                                 }
    1848           0 :                                 rc = smbldap_add(ldap_state->smbldap_state,
    1849             :                                                  dn, mods);
    1850           0 :                                 break;
    1851           0 :                         case LDAP_MOD_REPLACE:
    1852           0 :                                 rc = smbldap_modify(ldap_state->smbldap_state,
    1853             :                                                     dn ,mods);
    1854           0 :                                 break;
    1855           0 :                         default:
    1856           0 :                                 DEBUG(0,("ldapsam_modify_entry: Wrong LDAP operation type: %d!\n",
    1857             :                                          ldap_op));
    1858           0 :                                 return NT_STATUS_INVALID_PARAMETER;
    1859             :                 }
    1860             : 
    1861           0 :                 if (rc!=LDAP_SUCCESS) {
    1862           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1863             :                 }
    1864             :         }
    1865             : 
    1866           0 :         return NT_STATUS_OK;
    1867             : }
    1868             : 
    1869             : /**********************************************************************
    1870             :  Delete entry from LDAP for username.
    1871             : *********************************************************************/
    1872             : 
    1873           0 : static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
    1874             :                                            struct samu * sam_acct)
    1875             : {
    1876           0 :         struct ldapsam_privates *priv =
    1877             :                 (struct ldapsam_privates *)my_methods->private_data;
    1878           0 :         const char *sname;
    1879           0 :         int rc;
    1880           0 :         LDAPMessage *msg, *entry;
    1881           0 :         NTSTATUS result = NT_STATUS_NO_MEMORY;
    1882           0 :         const char **attr_list;
    1883           0 :         TALLOC_CTX *mem_ctx;
    1884             : 
    1885           0 :         if (!sam_acct) {
    1886           0 :                 DEBUG(0, ("ldapsam_delete_sam_account: sam_acct was NULL!\n"));
    1887           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1888             :         }
    1889             : 
    1890           0 :         sname = pdb_get_username(sam_acct);
    1891             : 
    1892           0 :         DEBUG(3, ("ldapsam_delete_sam_account: Deleting user %s from "
    1893             :                   "LDAP.\n", sname));
    1894             : 
    1895           0 :         mem_ctx = talloc_new(NULL);
    1896           0 :         if (mem_ctx == NULL) {
    1897           0 :                 DEBUG(0, ("talloc_new failed\n"));
    1898           0 :                 goto done;
    1899             :         }
    1900             : 
    1901           0 :         attr_list = get_userattr_delete_list(mem_ctx, priv->schema_ver );
    1902           0 :         if (attr_list == NULL) {
    1903           0 :                 goto done;
    1904             :         }
    1905             : 
    1906           0 :         rc = ldapsam_search_suffix_by_name(priv, sname, &msg, attr_list);
    1907             : 
    1908           0 :         if ((rc != LDAP_SUCCESS) ||
    1909           0 :             (ldap_count_entries(priv2ld(priv), msg) != 1) ||
    1910           0 :             ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
    1911           0 :                 DEBUG(5, ("Could not find user %s\n", sname));
    1912           0 :                 result = NT_STATUS_NO_SUCH_USER;
    1913           0 :                 goto done;
    1914             :         }
    1915             : 
    1916           0 :         rc = ldapsam_delete_entry(
    1917             :                 priv, mem_ctx, entry,
    1918           0 :                 priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
    1919             :                 LDAP_OBJ_SAMBASAMACCOUNT : 0,
    1920             :                 attr_list);
    1921             : 
    1922           0 :         result = (rc == LDAP_SUCCESS) ?
    1923           0 :                 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
    1924             : 
    1925           0 :  done:
    1926           0 :         TALLOC_FREE(mem_ctx);
    1927           0 :         return result;
    1928             : }
    1929             : 
    1930             : /**********************************************************************
    1931             :  Update struct samu.
    1932             : *********************************************************************/
    1933             : 
    1934           0 : static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
    1935             : {
    1936           0 :         NTSTATUS ret;
    1937           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    1938           0 :         int rc = 0;
    1939           0 :         char *dn;
    1940           0 :         LDAPMessage *result = NULL;
    1941           0 :         LDAPMessage *entry = NULL;
    1942           0 :         LDAPMod **mods = NULL;
    1943           0 :         const char **attr_list;
    1944             : 
    1945           0 :         result = (LDAPMessage *)pdb_get_backend_private_data(newpwd, my_methods);
    1946           0 :         if (!result) {
    1947           0 :                 attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
    1948           0 :                 if (pdb_get_username(newpwd) == NULL) {
    1949           0 :                         return NT_STATUS_INVALID_PARAMETER;
    1950             :                 }
    1951           0 :                 rc = ldapsam_search_suffix_by_name(ldap_state, pdb_get_username(newpwd), &result, attr_list );
    1952           0 :                 TALLOC_FREE( attr_list );
    1953           0 :                 if (rc != LDAP_SUCCESS) {
    1954           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1955             :                 }
    1956           0 :                 pdb_set_backend_private_data(newpwd, result, NULL,
    1957             :                                              my_methods, PDB_CHANGED);
    1958           0 :                 smbldap_talloc_autofree_ldapmsg(newpwd, result);
    1959             :         }
    1960             : 
    1961           0 :         if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    1962             :                                result) == 0) {
    1963           0 :                 DEBUG(0, ("ldapsam_update_sam_account: No user to modify!\n"));
    1964           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1965             :         }
    1966             : 
    1967           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    1968             :                                  result);
    1969           0 :         dn = smbldap_talloc_dn(talloc_tos(),
    1970             :                                smbldap_get_ldap(ldap_state->smbldap_state),
    1971             :                                entry);
    1972           0 :         if (!dn) {
    1973           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1974             :         }
    1975             : 
    1976           0 :         DEBUG(4, ("ldapsam_update_sam_account: user %s to be modified has dn: %s\n", pdb_get_username(newpwd), dn));
    1977             : 
    1978           0 :         if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
    1979             :                                 pdb_element_is_changed)) {
    1980           0 :                 DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
    1981           0 :                 TALLOC_FREE(dn);
    1982           0 :                 if (mods != NULL)
    1983           0 :                         ldap_mods_free(mods,True);
    1984           0 :                 return NT_STATUS_UNSUCCESSFUL;
    1985             :         }
    1986             : 
    1987           0 :         if ((lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_ONLY)
    1988           0 :             && (mods == NULL)) {
    1989           0 :                 DEBUG(4,("ldapsam_update_sam_account: mods is empty: nothing to update for user: %s\n",
    1990             :                          pdb_get_username(newpwd)));
    1991           0 :                 TALLOC_FREE(dn);
    1992           0 :                 return NT_STATUS_OK;
    1993             :         }
    1994             : 
    1995           0 :         ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, pdb_element_is_changed);
    1996             : 
    1997           0 :         if (mods != NULL) {
    1998           0 :                 ldap_mods_free(mods,True);
    1999             :         }
    2000             : 
    2001           0 :         TALLOC_FREE(dn);
    2002             : 
    2003             :         /*
    2004             :          * We need to set the backend private data to NULL here. For example
    2005             :          * setuserinfo level 25 does a pdb_update_sam_account twice on the
    2006             :          * same one, and with the explicit delete / add logic for attribute
    2007             :          * values the second time we would use the wrong "old" value which
    2008             :          * does not exist in LDAP anymore. Thus the LDAP server would refuse
    2009             :          * the update.
    2010             :          * The existing LDAPMessage is still being auto-freed by the
    2011             :          * destructor.
    2012             :          */
    2013           0 :         pdb_set_backend_private_data(newpwd, NULL, NULL, my_methods,
    2014             :                                      PDB_CHANGED);
    2015             : 
    2016           0 :         if (!NT_STATUS_IS_OK(ret)) {
    2017           0 :                 return ret;
    2018             :         }
    2019             : 
    2020           0 :         DEBUG(2, ("ldapsam_update_sam_account: successfully modified uid = %s in the LDAP database\n",
    2021             :                   pdb_get_username(newpwd)));
    2022           0 :         return NT_STATUS_OK;
    2023             : }
    2024             : 
    2025             : /***************************************************************************
    2026             :  Renames a struct samu
    2027             :  - The "rename user script" has full responsibility for changing everything
    2028             : ***************************************************************************/
    2029             : 
    2030             : static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
    2031             :                                      TALLOC_CTX *tmp_ctx,
    2032             :                                      uint32_t group_rid,
    2033             :                                      uint32_t member_rid);
    2034             : 
    2035             : static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
    2036             :                                                TALLOC_CTX *mem_ctx,
    2037             :                                                struct samu *user,
    2038             :                                                struct dom_sid **pp_sids,
    2039             :                                                gid_t **pp_gids,
    2040             :                                                uint32_t *p_num_groups);
    2041             : 
    2042           0 : static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
    2043             :                                            struct samu *old_acct,
    2044             :                                            const char *newname)
    2045             : {
    2046           0 :         const struct loadparm_substitution *lp_sub =
    2047           0 :                 loadparm_s3_global_substitution();
    2048           0 :         const char *oldname;
    2049           0 :         int rc;
    2050           0 :         char *rename_script = NULL;
    2051           0 :         fstring oldname_lower, newname_lower;
    2052             : 
    2053           0 :         if (!old_acct) {
    2054           0 :                 DEBUG(0, ("ldapsam_rename_sam_account: old_acct was NULL!\n"));
    2055           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2056             :         }
    2057           0 :         if (!newname) {
    2058           0 :                 DEBUG(0, ("ldapsam_rename_sam_account: newname was NULL!\n"));
    2059           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2060             :         }
    2061             : 
    2062           0 :         oldname = pdb_get_username(old_acct);
    2063             : 
    2064             :         /* rename the posix user */
    2065           0 :         rename_script = lp_rename_user_script(talloc_tos(), lp_sub);
    2066           0 :         if (rename_script == NULL) {
    2067           0 :                 return NT_STATUS_NO_MEMORY;
    2068             :         }
    2069             : 
    2070           0 :         if (!(*rename_script)) {
    2071           0 :                 TALLOC_FREE(rename_script);
    2072           0 :                 return NT_STATUS_ACCESS_DENIED;
    2073             :         }
    2074             : 
    2075           0 :         DEBUG (3, ("ldapsam_rename_sam_account: Renaming user %s to %s.\n",
    2076             :                    oldname, newname));
    2077             : 
    2078             :         /* We have to allow the account name to end with a '$'.
    2079             :            Also, follow the semantics in _samr_create_user() and lower case the
    2080             :            posix name but preserve the case in passdb */
    2081             : 
    2082           0 :         fstrcpy( oldname_lower, oldname );
    2083           0 :         if (!strlower_m( oldname_lower )) {
    2084           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2085             :         }
    2086           0 :         fstrcpy( newname_lower, newname );
    2087           0 :         if (!strlower_m( newname_lower )) {
    2088           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2089             :         }
    2090             : 
    2091           0 :         rename_script = realloc_string_sub2(rename_script,
    2092             :                                         "%unew",
    2093             :                                         newname_lower,
    2094             :                                         true,
    2095             :                                         true);
    2096           0 :         if (!rename_script) {
    2097           0 :                 return NT_STATUS_NO_MEMORY;
    2098             :         }
    2099           0 :         rename_script = realloc_string_sub2(rename_script,
    2100             :                                         "%uold",
    2101             :                                         oldname_lower,
    2102             :                                         true,
    2103             :                                         true);
    2104           0 :         rc = smbrun(rename_script, NULL, NULL);
    2105             : 
    2106           0 :         DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
    2107             :                           rename_script, rc));
    2108             : 
    2109           0 :         TALLOC_FREE(rename_script);
    2110             : 
    2111           0 :         if (rc == 0) {
    2112           0 :                 smb_nscd_flush_user_cache();
    2113             :         }
    2114             : 
    2115           0 :         if (rc)
    2116           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2117             : 
    2118           0 :         return NT_STATUS_OK;
    2119             : }
    2120             : 
    2121             : /**********************************************************************
    2122             :  Add struct samu to LDAP.
    2123             : *********************************************************************/
    2124             : 
    2125           0 : static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct samu * newpwd)
    2126             : {
    2127           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    2128           0 :         int rc;
    2129           0 :         LDAPMessage     *result = NULL;
    2130           0 :         LDAPMessage     *entry  = NULL;
    2131           0 :         LDAPMod         **mods = NULL;
    2132           0 :         int             ldap_op = LDAP_MOD_REPLACE;
    2133           0 :         uint32_t                num_result;
    2134           0 :         const char      **attr_list;
    2135           0 :         char *escape_user = NULL;
    2136           0 :         const char      *username = pdb_get_username(newpwd);
    2137           0 :         const struct dom_sid    *sid = pdb_get_user_sid(newpwd);
    2138           0 :         char *filter = NULL;
    2139           0 :         char *dn = NULL;
    2140           0 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    2141           0 :         TALLOC_CTX *ctx = talloc_init("ldapsam_add_sam_account");
    2142             : 
    2143           0 :         if (!ctx) {
    2144           0 :                 return NT_STATUS_NO_MEMORY;
    2145             :         }
    2146             : 
    2147           0 :         if (!username || !*username) {
    2148           0 :                 DEBUG(0, ("ldapsam_add_sam_account: Cannot add user without a username!\n"));
    2149           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    2150           0 :                 goto fn_exit;
    2151             :         }
    2152             : 
    2153             :         /* free this list after the second search or in case we exit on failure */
    2154           0 :         attr_list = get_userattr_list(ctx, ldap_state->schema_ver);
    2155             : 
    2156           0 :         rc = ldapsam_search_suffix_by_name (ldap_state, username, &result, attr_list);
    2157             : 
    2158           0 :         if (rc != LDAP_SUCCESS) {
    2159           0 :                 goto fn_exit;
    2160             :         }
    2161             : 
    2162           0 :         if (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    2163             :                                result) != 0) {
    2164           0 :                 DEBUG(0,("ldapsam_add_sam_account: User '%s' already in the base, with samba attributes\n",
    2165             :                          username));
    2166           0 :                 goto fn_exit;
    2167             :         }
    2168           0 :         ldap_msgfree(result);
    2169           0 :         result = NULL;
    2170             : 
    2171           0 :         if (pdb_element_is_set_or_changed(newpwd, PDB_USERSID)) {
    2172           0 :                 rc = ldapsam_get_ldap_user_by_sid(ldap_state,
    2173             :                                                   sid, &result);
    2174           0 :                 if (rc == LDAP_SUCCESS) {
    2175           0 :                         if (ldap_count_entries(
    2176             :                                     smbldap_get_ldap(
    2177             :                                             ldap_state->smbldap_state),
    2178             :                                     result) != 0) {
    2179           0 :                                 struct dom_sid_buf buf;
    2180           0 :                                 DEBUG(0,("ldapsam_add_sam_account: SID '%s' "
    2181             :                                          "already in the base, with samba "
    2182             :                                          "attributes\n",
    2183             :                                          dom_sid_str_buf(sid, &buf)));
    2184           0 :                                 goto fn_exit;
    2185             :                         }
    2186           0 :                         ldap_msgfree(result);
    2187           0 :                         result = NULL;
    2188             :                 }
    2189             :         }
    2190             : 
    2191             :         /* does the entry already exist but without a samba attributes?
    2192             :            we need to return the samba attributes here */
    2193             : 
    2194           0 :         escape_user = escape_ldap_string(talloc_tos(), username);
    2195           0 :         filter = talloc_strdup(attr_list, "(uid=%u)");
    2196           0 :         if (!filter) {
    2197           0 :                 status = NT_STATUS_NO_MEMORY;
    2198           0 :                 goto fn_exit;
    2199             :         }
    2200           0 :         filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
    2201           0 :         TALLOC_FREE(escape_user);
    2202           0 :         if (!filter) {
    2203           0 :                 status = NT_STATUS_NO_MEMORY;
    2204           0 :                 goto fn_exit;
    2205             :         }
    2206             : 
    2207           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state,
    2208             :                                    filter, attr_list, &result);
    2209           0 :         if ( rc != LDAP_SUCCESS ) {
    2210           0 :                 goto fn_exit;
    2211             :         }
    2212             : 
    2213           0 :         num_result = ldap_count_entries(
    2214             :                 smbldap_get_ldap(ldap_state->smbldap_state), result);
    2215             : 
    2216           0 :         if (num_result > 1) {
    2217           0 :                 DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n"));
    2218           0 :                 goto fn_exit;
    2219             :         }
    2220             : 
    2221             :         /* Check if we need to update an existing entry */
    2222           0 :         if (num_result == 1) {
    2223           0 :                 DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
    2224           0 :                 ldap_op = LDAP_MOD_REPLACE;
    2225           0 :                 entry = ldap_first_entry(
    2226             :                         smbldap_get_ldap(ldap_state->smbldap_state), result);
    2227           0 :                 dn = smbldap_talloc_dn(
    2228             :                         ctx, smbldap_get_ldap(ldap_state->smbldap_state),
    2229             :                         entry);
    2230           0 :                 if (!dn) {
    2231           0 :                         status = NT_STATUS_NO_MEMORY;
    2232           0 :                         goto fn_exit;
    2233             :                 }
    2234             : 
    2235           0 :         } else if (ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT) {
    2236             : 
    2237           0 :                 struct dom_sid_buf buf;
    2238             : 
    2239             :                 /* There might be a SID for this account already - say an idmap entry */
    2240             : 
    2241           0 :                 filter = talloc_asprintf(ctx,
    2242             :                                 "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
    2243             :                                  get_userattr_key2string(ldap_state->schema_ver,
    2244             :                                          LDAP_ATTR_USER_SID),
    2245             :                                  dom_sid_str_buf(sid, &buf),
    2246             :                                  LDAP_OBJ_IDMAP_ENTRY,
    2247             :                                  LDAP_OBJ_SID_ENTRY);
    2248           0 :                 if (!filter) {
    2249           0 :                         status = NT_STATUS_NO_MEMORY;
    2250           0 :                         goto fn_exit;
    2251             :                 }
    2252             : 
    2253             :                 /* free old result before doing a new search */
    2254           0 :                 if (result != NULL) {
    2255           0 :                         ldap_msgfree(result);
    2256           0 :                         result = NULL;
    2257             :                 }
    2258           0 :                 rc = smbldap_search_suffix(ldap_state->smbldap_state,
    2259             :                                            filter, attr_list, &result);
    2260             : 
    2261           0 :                 if ( rc != LDAP_SUCCESS ) {
    2262           0 :                         goto fn_exit;
    2263             :                 }
    2264             : 
    2265           0 :                 num_result = ldap_count_entries(
    2266             :                         smbldap_get_ldap(ldap_state->smbldap_state), result);
    2267             : 
    2268           0 :                 if (num_result > 1) {
    2269           0 :                         DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n"));
    2270           0 :                         goto fn_exit;
    2271             :                 }
    2272             : 
    2273             :                 /* Check if we need to update an existing entry */
    2274           0 :                 if (num_result == 1) {
    2275             : 
    2276           0 :                         DEBUG(3,("ldapsam_add_sam_account: User exists without samba attributes: adding them\n"));
    2277           0 :                         ldap_op = LDAP_MOD_REPLACE;
    2278           0 :                         entry = ldap_first_entry (
    2279             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    2280             :                                 result);
    2281           0 :                         dn = smbldap_talloc_dn (
    2282             :                                 ctx,
    2283             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    2284             :                                 entry);
    2285           0 :                         if (!dn) {
    2286           0 :                                 status = NT_STATUS_NO_MEMORY;
    2287           0 :                                 goto fn_exit;
    2288             :                         }
    2289             :                 }
    2290             :         }
    2291             : 
    2292           0 :         if (num_result == 0) {
    2293           0 :                 char *escape_username;
    2294             :                 /* Check if we need to add an entry */
    2295           0 :                 DEBUG(3,("ldapsam_add_sam_account: Adding new user\n"));
    2296           0 :                 ldap_op = LDAP_MOD_ADD;
    2297             : 
    2298           0 :                 escape_username = escape_rdn_val_string_alloc(username);
    2299           0 :                 if (!escape_username) {
    2300           0 :                         status = NT_STATUS_NO_MEMORY;
    2301           0 :                         goto fn_exit;
    2302             :                 }
    2303             : 
    2304           0 :                 if (username[strlen(username)-1] == '$') {
    2305           0 :                         dn = talloc_asprintf(ctx,
    2306             :                                         "uid=%s,%s",
    2307             :                                         escape_username,
    2308             :                                         lp_ldap_machine_suffix(talloc_tos()));
    2309             :                 } else {
    2310           0 :                         dn = talloc_asprintf(ctx,
    2311             :                                         "uid=%s,%s",
    2312             :                                         escape_username,
    2313             :                                         lp_ldap_user_suffix(talloc_tos()));
    2314             :                 }
    2315             : 
    2316           0 :                 SAFE_FREE(escape_username);
    2317           0 :                 if (!dn) {
    2318           0 :                         status = NT_STATUS_NO_MEMORY;
    2319           0 :                         goto fn_exit;
    2320             :                 }
    2321             :         }
    2322             : 
    2323           0 :         if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
    2324             :                                 pdb_element_is_set_or_changed)) {
    2325           0 :                 DEBUG(0, ("ldapsam_add_sam_account: init_ldap_from_sam failed!\n"));
    2326           0 :                 if (mods != NULL) {
    2327           0 :                         ldap_mods_free(mods, true);
    2328             :                 }
    2329           0 :                 goto fn_exit;
    2330             :         }
    2331             : 
    2332           0 :         if (mods == NULL) {
    2333           0 :                 DEBUG(0,("ldapsam_add_sam_account: mods is empty: nothing to add for user: %s\n",pdb_get_username(newpwd)));
    2334           0 :                 goto fn_exit;
    2335             :         }
    2336           0 :         switch ( ldap_state->schema_ver ) {
    2337           0 :                 case SCHEMAVER_SAMBASAMACCOUNT:
    2338           0 :                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
    2339           0 :                         break;
    2340           0 :                 default:
    2341           0 :                         DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
    2342           0 :                         break;
    2343             :         }
    2344             : 
    2345           0 :         status = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, pdb_element_is_set_or_changed);
    2346           0 :         if (!NT_STATUS_IS_OK(status)) {
    2347           0 :                 DEBUG(0,("ldapsam_add_sam_account: failed to modify/add user with uid = %s (dn = %s)\n",
    2348             :                          pdb_get_username(newpwd),dn));
    2349           0 :                 ldap_mods_free(mods, true);
    2350           0 :                 goto fn_exit;
    2351             :         }
    2352             : 
    2353           0 :         DEBUG(2,("ldapsam_add_sam_account: added: uid == %s in the LDAP database\n", pdb_get_username(newpwd)));
    2354           0 :         ldap_mods_free(mods, true);
    2355             : 
    2356           0 :         status = NT_STATUS_OK;
    2357             : 
    2358           0 :   fn_exit:
    2359             : 
    2360           0 :         TALLOC_FREE(ctx);
    2361           0 :         if (result) {
    2362           0 :                 ldap_msgfree(result);
    2363             :         }
    2364           0 :         return status;
    2365             : }
    2366             : 
    2367             : /**********************************************************************
    2368             :  *********************************************************************/
    2369             : 
    2370           0 : static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
    2371             :                                      const char *filter,
    2372             :                                      LDAPMessage ** result)
    2373             : {
    2374           0 :         int scope = LDAP_SCOPE_SUBTREE;
    2375           0 :         int rc;
    2376           0 :         const char **attr_list;
    2377             : 
    2378           0 :         attr_list = get_attr_list(NULL, groupmap_attr_list);
    2379           0 :         rc = smbldap_search(ldap_state->smbldap_state,
    2380             :                             lp_ldap_suffix(), scope,
    2381             :                             filter, attr_list, 0, result);
    2382           0 :         TALLOC_FREE(attr_list);
    2383             : 
    2384           0 :         return rc;
    2385             : }
    2386             : 
    2387             : /**********************************************************************
    2388             :  *********************************************************************/
    2389             : 
    2390           0 : static bool init_group_from_ldap(struct ldapsam_privates *ldap_state,
    2391             :                                  GROUP_MAP *map, LDAPMessage *entry)
    2392             : {
    2393           0 :         char *temp = NULL;
    2394           0 :         TALLOC_CTX *ctx = talloc_init("init_group_from_ldap");
    2395             : 
    2396           0 :         if (ldap_state == NULL || map == NULL || entry == NULL ||
    2397           0 :             smbldap_get_ldap(ldap_state->smbldap_state) == NULL) {
    2398           0 :                 DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
    2399           0 :                 TALLOC_FREE(ctx);
    2400           0 :                 return false;
    2401             :         }
    2402             : 
    2403           0 :         temp = smbldap_talloc_single_attribute(
    2404             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    2405             :                         entry,
    2406             :                         get_attr_key2string(groupmap_attr_list,
    2407             :                                 LDAP_ATTR_GIDNUMBER),
    2408             :                         ctx);
    2409           0 :         if (!temp) {
    2410           0 :                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
    2411             :                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GIDNUMBER)));
    2412           0 :                 TALLOC_FREE(ctx);
    2413           0 :                 return false;
    2414             :         }
    2415           0 :         DEBUG(2, ("init_group_from_ldap: Entry found for group: %s\n", temp));
    2416             : 
    2417           0 :         map->gid = (gid_t)atol(temp);
    2418             : 
    2419           0 :         TALLOC_FREE(temp);
    2420           0 :         temp = smbldap_talloc_single_attribute(
    2421             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    2422             :                         entry,
    2423             :                         get_attr_key2string(groupmap_attr_list,
    2424             :                                 LDAP_ATTR_GROUP_SID),
    2425             :                         ctx);
    2426           0 :         if (!temp) {
    2427           0 :                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
    2428             :                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID)));
    2429           0 :                 TALLOC_FREE(ctx);
    2430           0 :                 return false;
    2431             :         }
    2432             : 
    2433           0 :         if (!string_to_sid(&map->sid, temp)) {
    2434           0 :                 DEBUG(1, ("SID string [%s] could not be read as a valid SID\n", temp));
    2435           0 :                 TALLOC_FREE(ctx);
    2436           0 :                 return false;
    2437             :         }
    2438             : 
    2439           0 :         TALLOC_FREE(temp);
    2440           0 :         temp = smbldap_talloc_single_attribute(
    2441             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    2442             :                         entry,
    2443             :                         get_attr_key2string(groupmap_attr_list,
    2444             :                                 LDAP_ATTR_GROUP_TYPE),
    2445             :                         ctx);
    2446           0 :         if (!temp) {
    2447           0 :                 DEBUG(0, ("init_group_from_ldap: Mandatory attribute %s not found\n",
    2448             :                         get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
    2449           0 :                 TALLOC_FREE(ctx);
    2450           0 :                 return false;
    2451             :         }
    2452           0 :         map->sid_name_use = (enum lsa_SidType)atol(temp);
    2453             : 
    2454           0 :         if ((map->sid_name_use < SID_NAME_USER) ||
    2455           0 :                         (map->sid_name_use > SID_NAME_UNKNOWN)) {
    2456           0 :                 DEBUG(0, ("init_group_from_ldap: Unknown Group type: %d\n", map->sid_name_use));
    2457           0 :                 TALLOC_FREE(ctx);
    2458           0 :                 return false;
    2459             :         }
    2460             : 
    2461           0 :         TALLOC_FREE(temp);
    2462           0 :         temp = smbldap_talloc_single_attribute(
    2463             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    2464             :                         entry,
    2465             :                         get_attr_key2string(groupmap_attr_list,
    2466             :                                 LDAP_ATTR_DISPLAY_NAME),
    2467             :                         ctx);
    2468           0 :         if (!temp) {
    2469           0 :                 temp = smbldap_talloc_single_attribute(
    2470             :                                 smbldap_get_ldap(ldap_state->smbldap_state),
    2471             :                                 entry,
    2472             :                                 get_attr_key2string(groupmap_attr_list,
    2473             :                                         LDAP_ATTR_CN),
    2474             :                                 ctx);
    2475           0 :                 if (!temp) {
    2476           0 :                         DEBUG(0, ("init_group_from_ldap: Attributes cn not found either \
    2477             : for gidNumber(%lu)\n",(unsigned long)map->gid));
    2478           0 :                         TALLOC_FREE(ctx);
    2479           0 :                         return false;
    2480             :                 }
    2481             :         }
    2482           0 :         map->nt_name = talloc_strdup(map, temp);
    2483           0 :         if (!map->nt_name) {
    2484           0 :                 TALLOC_FREE(ctx);
    2485           0 :                 return false;
    2486             :         }
    2487             : 
    2488           0 :         TALLOC_FREE(temp);
    2489           0 :         temp = smbldap_talloc_single_attribute(
    2490             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    2491             :                         entry,
    2492             :                         get_attr_key2string(groupmap_attr_list,
    2493             :                                 LDAP_ATTR_DESC),
    2494             :                         ctx);
    2495           0 :         if (!temp) {
    2496           0 :                 temp = talloc_strdup(ctx, "");
    2497           0 :                 if (!temp) {
    2498           0 :                         TALLOC_FREE(ctx);
    2499           0 :                         return false;
    2500             :                 }
    2501             :         }
    2502           0 :         map->comment = talloc_strdup(map, temp);
    2503           0 :         if (!map->comment) {
    2504           0 :                 TALLOC_FREE(ctx);
    2505           0 :                 return false;
    2506             :         }
    2507             : 
    2508           0 :         if (lp_parm_bool(-1, "ldapsam", "trusted", false)) {
    2509           0 :                 struct unixid id;
    2510           0 :                 id.id = map->gid;
    2511           0 :                 id.type = ID_TYPE_GID;
    2512             : 
    2513           0 :                 idmap_cache_set_sid2unixid(&map->sid, &id);
    2514             :         }
    2515             : 
    2516           0 :         TALLOC_FREE(ctx);
    2517           0 :         return true;
    2518             : }
    2519             : 
    2520             : /**********************************************************************
    2521             :  *********************************************************************/
    2522             : 
    2523           0 : static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
    2524             :                                  const char *filter,
    2525             :                                  GROUP_MAP *map)
    2526             : {
    2527           0 :         struct ldapsam_privates *ldap_state =
    2528             :                 (struct ldapsam_privates *)methods->private_data;
    2529           0 :         LDAPMessage *result = NULL;
    2530           0 :         LDAPMessage *entry = NULL;
    2531           0 :         int count;
    2532             : 
    2533           0 :         if (ldapsam_search_one_group(ldap_state, filter, &result)
    2534             :             != LDAP_SUCCESS) {
    2535           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    2536             :         }
    2537             : 
    2538           0 :         count = ldap_count_entries(priv2ld(ldap_state), result);
    2539             : 
    2540           0 :         if (count < 1) {
    2541           0 :                 DEBUG(4, ("ldapsam_getgroup: Did not find group, filter was "
    2542             :                           "%s\n", filter));
    2543           0 :                 ldap_msgfree(result);
    2544           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    2545             :         }
    2546             : 
    2547           0 :         if (count > 1) {
    2548           0 :                 DEBUG(1, ("ldapsam_getgroup: Duplicate entries for filter %s: "
    2549             :                           "count=%d\n", filter, count));
    2550           0 :                 ldap_msgfree(result);
    2551           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    2552             :         }
    2553             : 
    2554           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    2555             : 
    2556           0 :         if (!entry) {
    2557           0 :                 ldap_msgfree(result);
    2558           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2559             :         }
    2560             : 
    2561           0 :         if (!init_group_from_ldap(ldap_state, map, entry)) {
    2562           0 :                 DEBUG(1, ("ldapsam_getgroup: init_group_from_ldap failed for "
    2563             :                           "group filter %s\n", filter));
    2564           0 :                 ldap_msgfree(result);
    2565           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    2566             :         }
    2567             : 
    2568           0 :         ldap_msgfree(result);
    2569           0 :         return NT_STATUS_OK;
    2570             : }
    2571             : 
    2572             : /**********************************************************************
    2573             :  *********************************************************************/
    2574             : 
    2575           0 : static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
    2576             :                                  struct dom_sid sid)
    2577             : {
    2578           0 :         char *filter = NULL;
    2579           0 :         NTSTATUS status;
    2580           0 :         struct dom_sid_buf tmp;
    2581             : 
    2582           0 :         if (asprintf(&filter, "(&(objectClass=%s)(%s=%s))",
    2583             :                 LDAP_OBJ_GROUPMAP,
    2584             :                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
    2585             :                 dom_sid_str_buf(&sid, &tmp)) < 0) {
    2586           0 :                 return NT_STATUS_NO_MEMORY;
    2587             :         }
    2588             : 
    2589           0 :         status = ldapsam_getgroup(methods, filter, map);
    2590           0 :         SAFE_FREE(filter);
    2591           0 :         return status;
    2592             : }
    2593             : 
    2594             : /**********************************************************************
    2595             :  *********************************************************************/
    2596             : 
    2597           0 : static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
    2598             :                                  gid_t gid)
    2599             : {
    2600           0 :         char *filter = NULL;
    2601           0 :         NTSTATUS status;
    2602             : 
    2603           0 :         if (asprintf(&filter, "(&(objectClass=%s)(%s=%lu))",
    2604             :                 LDAP_OBJ_GROUPMAP,
    2605             :                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
    2606             :                 (unsigned long)gid) < 0) {
    2607           0 :                 return NT_STATUS_NO_MEMORY;
    2608             :         }
    2609             : 
    2610           0 :         status = ldapsam_getgroup(methods, filter, map);
    2611           0 :         SAFE_FREE(filter);
    2612           0 :         return status;
    2613             : }
    2614             : 
    2615             : /**********************************************************************
    2616             :  *********************************************************************/
    2617             : 
    2618           0 : static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
    2619             :                                  const char *name)
    2620             : {
    2621           0 :         char *filter = NULL;
    2622           0 :         char *escape_name = escape_ldap_string(talloc_tos(), name);
    2623           0 :         NTSTATUS status;
    2624             : 
    2625           0 :         if (!escape_name) {
    2626           0 :                 return NT_STATUS_NO_MEMORY;
    2627             :         }
    2628             : 
    2629           0 :         if (asprintf(&filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
    2630             :                 LDAP_OBJ_GROUPMAP,
    2631             :                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
    2632             :                 get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
    2633             :                 escape_name) < 0) {
    2634           0 :                 TALLOC_FREE(escape_name);
    2635           0 :                 return NT_STATUS_NO_MEMORY;
    2636             :         }
    2637             : 
    2638           0 :         TALLOC_FREE(escape_name);
    2639           0 :         status = ldapsam_getgroup(methods, filter, map);
    2640           0 :         SAFE_FREE(filter);
    2641           0 :         return status;
    2642             : }
    2643             : 
    2644           0 : static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct,
    2645             :                                            LDAPMessage *entry,
    2646             :                                            const struct dom_sid *domain_sid,
    2647             :                                            uint32_t *rid)
    2648             : {
    2649           0 :         fstring str;
    2650           0 :         struct dom_sid sid;
    2651             : 
    2652           0 :         if (!smbldap_get_single_attribute(ldap_struct, entry, "sambaSID",
    2653             :                                           str, sizeof(str)-1)) {
    2654           0 :                 DEBUG(10, ("Could not find sambaSID attribute\n"));
    2655           0 :                 return False;
    2656             :         }
    2657             : 
    2658           0 :         if (!string_to_sid(&sid, str)) {
    2659           0 :                 DEBUG(10, ("Could not convert string %s to sid\n", str));
    2660           0 :                 return False;
    2661             :         }
    2662             : 
    2663           0 :         if (dom_sid_compare_domain(&sid, domain_sid) != 0) {
    2664           0 :                 struct dom_sid_buf buf;
    2665           0 :                 DEBUG(10, ("SID %s is not in expected domain %s\n",
    2666             :                            str,
    2667             :                            dom_sid_str_buf(domain_sid, &buf)));
    2668           0 :                 return False;
    2669             :         }
    2670             : 
    2671           0 :         if (!sid_peek_rid(&sid, rid)) {
    2672           0 :                 DEBUG(10, ("Could not peek into RID\n"));
    2673           0 :                 return False;
    2674             :         }
    2675             : 
    2676           0 :         return True;
    2677             : }
    2678             : 
    2679           0 : static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
    2680             :                                            TALLOC_CTX *mem_ctx,
    2681             :                                            const struct dom_sid *group,
    2682             :                                            uint32_t **pp_member_rids,
    2683             :                                            size_t *p_num_members)
    2684             : {
    2685           0 :         struct ldapsam_privates *ldap_state =
    2686             :                 (struct ldapsam_privates *)methods->private_data;
    2687           0 :         struct smbldap_state *conn = ldap_state->smbldap_state;
    2688           0 :         const char *id_attrs[] = { "memberUid", "gidNumber", NULL };
    2689           0 :         const char *sid_attrs[] = { "sambaSID", NULL };
    2690           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    2691           0 :         LDAPMessage *result = NULL;
    2692           0 :         LDAPMessage *entry;
    2693           0 :         char *filter;
    2694           0 :         char **values = NULL;
    2695           0 :         char **memberuid;
    2696           0 :         char *gidstr;
    2697           0 :         int rc, count;
    2698           0 :         struct dom_sid_buf buf;
    2699             : 
    2700           0 :         *pp_member_rids = NULL;
    2701           0 :         *p_num_members = 0;
    2702             : 
    2703           0 :         filter = talloc_asprintf(mem_ctx,
    2704             :                                  "(&(objectClass="LDAP_OBJ_POSIXGROUP")"
    2705             :                                  "(objectClass="LDAP_OBJ_GROUPMAP")"
    2706             :                                  "(sambaSID=%s))",
    2707             :                                  dom_sid_str_buf(group, &buf));
    2708           0 :         if (filter == NULL) {
    2709           0 :                 ret = NT_STATUS_NO_MEMORY;
    2710           0 :                 goto done;
    2711             :         }
    2712             : 
    2713           0 :         rc = smbldap_search(conn, lp_ldap_suffix(),
    2714             :                             LDAP_SCOPE_SUBTREE, filter, id_attrs, 0,
    2715             :                             &result);
    2716             : 
    2717           0 :         if (rc != LDAP_SUCCESS)
    2718           0 :                 goto done;
    2719             : 
    2720           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    2721             : 
    2722           0 :         count = ldap_count_entries(smbldap_get_ldap(conn), result);
    2723             : 
    2724           0 :         if (count > 1) {
    2725           0 :                 DEBUG(1, ("Found more than one groupmap entry for %s\n",
    2726             :                           dom_sid_str_buf(group, &buf)));
    2727           0 :                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2728           0 :                 goto done;
    2729             :         }
    2730             : 
    2731           0 :         if (count == 0) {
    2732           0 :                 ret = NT_STATUS_NO_SUCH_GROUP;
    2733           0 :                 goto done;
    2734             :         }
    2735             : 
    2736           0 :         entry = ldap_first_entry(smbldap_get_ldap(conn), result);
    2737           0 :         if (entry == NULL)
    2738           0 :                 goto done;
    2739             : 
    2740           0 :         gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
    2741           0 :         if (!gidstr) {
    2742           0 :                 DEBUG (0, ("ldapsam_enum_group_members: Unable to find the group's gid!\n"));
    2743           0 :                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2744           0 :                 goto done;
    2745             :         }
    2746             : 
    2747           0 :         values = ldap_get_values(smbldap_get_ldap(conn), entry, "memberUid");
    2748             : 
    2749           0 :         if ((values != NULL) && (values[0] != NULL)) {
    2750             : 
    2751           0 :                 filter = talloc_strdup(mem_ctx, "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|");
    2752             : 
    2753           0 :                 for (memberuid = values; *memberuid != NULL; memberuid += 1) {
    2754           0 :                         char *escape_memberuid;
    2755             : 
    2756           0 :                         escape_memberuid = escape_ldap_string(talloc_tos(),
    2757             :                                                               *memberuid);
    2758           0 :                         if (escape_memberuid == NULL) {
    2759           0 :                                 ret = NT_STATUS_NO_MEMORY;
    2760           0 :                                 goto done;
    2761             :                         }
    2762             : 
    2763           0 :                         filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
    2764           0 :                         TALLOC_FREE(escape_memberuid);
    2765           0 :                         if (filter == NULL) {
    2766           0 :                                 ret = NT_STATUS_NO_MEMORY;
    2767           0 :                                 goto done;
    2768             :                         }
    2769             :                 }
    2770             : 
    2771           0 :                 filter = talloc_asprintf_append_buffer(filter, "))");
    2772           0 :                 if (filter == NULL) {
    2773           0 :                         ret = NT_STATUS_NO_MEMORY;
    2774           0 :                         goto done;
    2775             :                 }
    2776             : 
    2777           0 :                 rc = smbldap_search(conn, lp_ldap_suffix(),
    2778             :                                     LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
    2779             :                                     &result);
    2780             : 
    2781           0 :                 if (rc != LDAP_SUCCESS)
    2782           0 :                         goto done;
    2783             : 
    2784           0 :                 count = ldap_count_entries(smbldap_get_ldap(conn), result);
    2785           0 :                 DEBUG(10,("ldapsam_enum_group_members: found %d accounts\n", count));
    2786             : 
    2787           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    2788             : 
    2789           0 :                 for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
    2790           0 :                      entry != NULL;
    2791           0 :                      entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
    2792             :                 {
    2793           0 :                         char *sidstr;
    2794           0 :                         struct dom_sid sid;
    2795           0 :                         uint32_t rid;
    2796             : 
    2797           0 :                         sidstr = smbldap_talloc_single_attribute(
    2798             :                                 smbldap_get_ldap(conn), entry, "sambaSID",
    2799             :                                 mem_ctx);
    2800           0 :                         if (!sidstr) {
    2801           0 :                                 DEBUG(0, ("Severe DB error, %s can't miss the sambaSID"
    2802             :                                           "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
    2803           0 :                                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2804           0 :                                 goto done;
    2805             :                         }
    2806             : 
    2807           0 :                         if (!string_to_sid(&sid, sidstr))
    2808           0 :                                 goto done;
    2809             : 
    2810           0 :                         if (!sid_check_is_in_our_sam(&sid)) {
    2811           0 :                                 DEBUG(0, ("Inconsistent SAM -- group member uid not "
    2812             :                                           "in our domain\n"));
    2813           0 :                                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2814           0 :                                 goto done;
    2815             :                         }
    2816             : 
    2817           0 :                         sid_peek_rid(&sid, &rid);
    2818             : 
    2819           0 :                         if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
    2820             :                                                 p_num_members)) {
    2821           0 :                                 ret = NT_STATUS_NO_MEMORY;
    2822           0 :                                 goto done;
    2823             :                         }
    2824             :                 }
    2825             :         }
    2826             : 
    2827           0 :         filter = talloc_asprintf(mem_ctx,
    2828             :                                  "(&(objectClass=%s)"
    2829             :                                  "(gidNumber=%s))",
    2830             :                                  LDAP_OBJ_SAMBASAMACCOUNT,
    2831             :                                  gidstr);
    2832             : 
    2833           0 :         rc = smbldap_search(conn, lp_ldap_suffix(),
    2834             :                             LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
    2835             :                             &result);
    2836             : 
    2837           0 :         if (rc != LDAP_SUCCESS)
    2838           0 :                 goto done;
    2839             : 
    2840           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    2841             : 
    2842           0 :         for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
    2843           0 :              entry != NULL;
    2844           0 :              entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
    2845             :         {
    2846           0 :                 uint32_t rid;
    2847             : 
    2848           0 :                 if (!ldapsam_extract_rid_from_entry(smbldap_get_ldap(conn),
    2849             :                                                     entry,
    2850           0 :                                                     get_global_sam_sid(),
    2851             :                                                     &rid)) {
    2852           0 :                         DEBUG(0, ("Severe DB error, %s can't miss the samba SID"
    2853             :                                   "attribute\n", LDAP_OBJ_SAMBASAMACCOUNT));
    2854           0 :                         ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2855           0 :                         goto done;
    2856             :                 }
    2857             : 
    2858           0 :                 if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids,
    2859             :                                         p_num_members)) {
    2860           0 :                         ret = NT_STATUS_NO_MEMORY;
    2861           0 :                         goto done;
    2862             :                 }
    2863             :         }
    2864             : 
    2865           0 :         ret = NT_STATUS_OK;
    2866             : 
    2867           0 :  done:
    2868             : 
    2869           0 :         if (values)
    2870           0 :                 ldap_value_free(values);
    2871             : 
    2872           0 :         return ret;
    2873             : }
    2874             : 
    2875           0 : static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
    2876             :                                                TALLOC_CTX *mem_ctx,
    2877             :                                                struct samu *user,
    2878             :                                                struct dom_sid **pp_sids,
    2879             :                                                gid_t **pp_gids,
    2880             :                                                uint32_t *p_num_groups)
    2881             : {
    2882           0 :         struct ldapsam_privates *ldap_state =
    2883             :                 (struct ldapsam_privates *)methods->private_data;
    2884           0 :         struct smbldap_state *conn = ldap_state->smbldap_state;
    2885           0 :         char *filter;
    2886           0 :         const char *attrs[] = { "gidNumber", "sambaSID", NULL };
    2887           0 :         char *escape_name;
    2888           0 :         int rc, count;
    2889           0 :         LDAPMessage *result = NULL;
    2890           0 :         LDAPMessage *entry;
    2891           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    2892           0 :         uint32_t num_sids;
    2893           0 :         uint32_t num_gids;
    2894           0 :         char *gidstr;
    2895           0 :         gid_t primary_gid = -1;
    2896           0 :         int error = 0;
    2897             : 
    2898           0 :         *pp_sids = NULL;
    2899           0 :         num_sids = 0;
    2900             : 
    2901           0 :         if (pdb_get_username(user) == NULL) {
    2902           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2903             :         }
    2904             : 
    2905           0 :         escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
    2906           0 :         if (escape_name == NULL)
    2907           0 :                 return NT_STATUS_NO_MEMORY;
    2908             : 
    2909           0 :         if (user->unix_pw) {
    2910           0 :                 primary_gid = user->unix_pw->pw_gid;
    2911             :         } else {
    2912             :                 /* retrieve the users primary gid */
    2913           0 :                 filter = talloc_asprintf(mem_ctx,
    2914             :                                          "(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(uid=%s))",
    2915             :                                          escape_name);
    2916           0 :                 if (filter == NULL) {
    2917           0 :                         ret = NT_STATUS_NO_MEMORY;
    2918           0 :                         goto done;
    2919             :                 }
    2920             : 
    2921           0 :                 rc = smbldap_search(conn, lp_ldap_suffix(),
    2922             :                                     LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
    2923             : 
    2924           0 :                 if (rc != LDAP_SUCCESS)
    2925           0 :                         goto done;
    2926             : 
    2927           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    2928             : 
    2929           0 :                 count = ldap_count_entries(priv2ld(ldap_state), result);
    2930             : 
    2931           0 :                 switch (count) {
    2932           0 :                 case 0:
    2933           0 :                         DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user)));
    2934           0 :                         ret = NT_STATUS_NO_SUCH_USER;
    2935           0 :                         goto done;
    2936           0 :                 case 1:
    2937           0 :                         entry = ldap_first_entry(priv2ld(ldap_state), result);
    2938             : 
    2939           0 :                         gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx);
    2940           0 :                         if (!gidstr) {
    2941           0 :                                 DEBUG (1, ("Unable to find the member's gid!\n"));
    2942           0 :                                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2943           0 :                                 goto done;
    2944             :                         }
    2945           0 :                         primary_gid = smb_strtoul(gidstr,
    2946             :                                                   NULL,
    2947             :                                                   10,
    2948             :                                                   &error,
    2949             :                                                   SMB_STR_STANDARD);
    2950           0 :                         if (error != 0) {
    2951           0 :                                 DBG_ERR("Failed to convert GID\n");
    2952           0 :                                 goto done;
    2953             :                         }
    2954           0 :                         break;
    2955           0 :                 default:
    2956           0 :                         DEBUG(1, ("found more than one account with the same user name ?!\n"));
    2957           0 :                         ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    2958           0 :                         goto done;
    2959             :                 }
    2960             :         }
    2961             : 
    2962           0 :         filter = talloc_asprintf(mem_ctx,
    2963             :                                  "(&(objectClass="LDAP_OBJ_POSIXGROUP")(|(memberUid=%s)(gidNumber=%u)))",
    2964             :                                  escape_name, (unsigned int)primary_gid);
    2965           0 :         if (filter == NULL) {
    2966           0 :                 ret = NT_STATUS_NO_MEMORY;
    2967           0 :                 goto done;
    2968             :         }
    2969             : 
    2970           0 :         rc = smbldap_search(conn, lp_ldap_suffix(),
    2971             :                             LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
    2972             : 
    2973           0 :         if (rc != LDAP_SUCCESS)
    2974           0 :                 goto done;
    2975             : 
    2976           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    2977             : 
    2978           0 :         num_gids = 0;
    2979           0 :         *pp_gids = NULL;
    2980             : 
    2981           0 :         num_sids = 0;
    2982           0 :         *pp_sids = NULL;
    2983             : 
    2984             :         /* We need to add the primary group as the first gid/sid */
    2985             : 
    2986           0 :         if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) {
    2987           0 :                 ret = NT_STATUS_NO_MEMORY;
    2988           0 :                 goto done;
    2989             :         }
    2990             : 
    2991             :         /* This sid will be replaced later */
    2992             : 
    2993           0 :         ret = add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids,
    2994             :                                       &num_sids);
    2995           0 :         if (!NT_STATUS_IS_OK(ret)) {
    2996           0 :                 goto done;
    2997             :         }
    2998             : 
    2999           0 :         for (entry = ldap_first_entry(smbldap_get_ldap(conn), result);
    3000           0 :              entry != NULL;
    3001           0 :              entry = ldap_next_entry(smbldap_get_ldap(conn), entry))
    3002             :         {
    3003           0 :                 fstring str;
    3004           0 :                 struct dom_sid sid;
    3005           0 :                 gid_t gid;
    3006             : 
    3007           0 :                 if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
    3008             :                                                   entry, "sambaSID",
    3009             :                                                   str, sizeof(str)-1))
    3010           0 :                         continue;
    3011             : 
    3012           0 :                 if (!string_to_sid(&sid, str))
    3013           0 :                         goto done;
    3014             : 
    3015           0 :                 if (!smbldap_get_single_attribute(smbldap_get_ldap(conn),
    3016             :                                                   entry, "gidNumber",
    3017             :                                                   str, sizeof(str)-1))
    3018           0 :                         continue;
    3019             : 
    3020           0 :                 gid = smb_strtoul(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
    3021             : 
    3022           0 :                 if (error != 0) {
    3023           0 :                         goto done;
    3024             :                 }
    3025             : 
    3026           0 :                 if (gid == primary_gid) {
    3027           0 :                         sid_copy(&(*pp_sids)[0], &sid);
    3028             :                 } else {
    3029           0 :                         if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids,
    3030             :                                                 &num_gids)) {
    3031           0 :                                 ret = NT_STATUS_NO_MEMORY;
    3032           0 :                                 goto done;
    3033             :                         }
    3034           0 :                         ret = add_sid_to_array_unique(mem_ctx, &sid, pp_sids,
    3035             :                                                       &num_sids);
    3036           0 :                         if (!NT_STATUS_IS_OK(ret)) {
    3037           0 :                                 goto done;
    3038             :                         }
    3039             :                 }
    3040             :         }
    3041             : 
    3042           0 :         if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) {
    3043           0 :                 DEBUG(3, ("primary group of [%s] not found\n",
    3044             :                           pdb_get_username(user)));
    3045           0 :                 ret = NT_STATUS_INTERNAL_DB_CORRUPTION;
    3046           0 :                 goto done;
    3047             :         }
    3048             : 
    3049           0 :         *p_num_groups = num_sids;
    3050             : 
    3051           0 :         ret = NT_STATUS_OK;
    3052             : 
    3053           0 :  done:
    3054             : 
    3055           0 :         TALLOC_FREE(escape_name);
    3056           0 :         return ret;
    3057             : }
    3058             : 
    3059             : /**********************************************************************
    3060             :  * Augment a posixGroup object with a sambaGroupMapping domgroup
    3061             :  *********************************************************************/
    3062             : 
    3063           0 : static NTSTATUS ldapsam_map_posixgroup(TALLOC_CTX *mem_ctx,
    3064             :                                        struct ldapsam_privates *ldap_state,
    3065             :                                        GROUP_MAP *map)
    3066             : {
    3067           0 :         const char *filter, *dn;
    3068           0 :         LDAPMessage *msg, *entry;
    3069           0 :         LDAPMod **mods;
    3070           0 :         struct dom_sid_buf buf;
    3071           0 :         int rc;
    3072             : 
    3073           0 :         filter = talloc_asprintf(mem_ctx,
    3074             :                                  "(&(objectClass="LDAP_OBJ_POSIXGROUP")(gidNumber=%u))",
    3075           0 :                                  (unsigned int)map->gid);
    3076           0 :         if (filter == NULL) {
    3077           0 :                 return NT_STATUS_NO_MEMORY;
    3078             :         }
    3079             : 
    3080           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
    3081             :                                    get_attr_list(mem_ctx, groupmap_attr_list),
    3082             :                                    &msg);
    3083           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    3084             : 
    3085           0 :         if ((rc != LDAP_SUCCESS) ||
    3086           0 :             (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    3087           0 :                                 msg) != 1) ||
    3088           0 :             ((entry = ldap_first_entry(
    3089             :                       smbldap_get_ldap(ldap_state->smbldap_state),
    3090             :                       msg)) == NULL)) {
    3091           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    3092             :         }
    3093             : 
    3094           0 :         dn = smbldap_talloc_dn(mem_ctx,
    3095             :                                smbldap_get_ldap(ldap_state->smbldap_state),
    3096             :                                entry);
    3097           0 :         if (dn == NULL) {
    3098           0 :                 return NT_STATUS_NO_MEMORY;
    3099             :         }
    3100             : 
    3101           0 :         mods = NULL;
    3102           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass",
    3103             :                         LDAP_OBJ_GROUPMAP);
    3104           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3105             :                          &mods, "sambaSid",
    3106           0 :                          dom_sid_str_buf(&map->sid, &buf));
    3107           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3108             :                          &mods, "sambaGroupType",
    3109           0 :                          talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
    3110           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3111             :                          &mods, "displayName",
    3112           0 :                          map->nt_name);
    3113           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3114             :                          &mods, "description",
    3115           0 :                          map->comment);
    3116           0 :         smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
    3117             : 
    3118           0 :         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    3119           0 :         if (rc != LDAP_SUCCESS) {
    3120           0 :                 return NT_STATUS_ACCESS_DENIED;
    3121             :         }
    3122             : 
    3123           0 :         return NT_STATUS_OK;
    3124             : }
    3125             : 
    3126           0 : static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
    3127             :                                                 GROUP_MAP *map)
    3128             : {
    3129           0 :         struct ldapsam_privates *ldap_state =
    3130             :                 (struct ldapsam_privates *)methods->private_data;
    3131           0 :         LDAPMessage *msg = NULL;
    3132           0 :         LDAPMod **mods = NULL;
    3133           0 :         const char *attrs[] = { NULL };
    3134           0 :         char *filter;
    3135             : 
    3136           0 :         char *dn;
    3137           0 :         TALLOC_CTX *mem_ctx;
    3138           0 :         NTSTATUS result;
    3139             : 
    3140           0 :         struct dom_sid sid;
    3141           0 :         struct dom_sid_buf buf;
    3142           0 :         struct unixid id;
    3143             : 
    3144           0 :         int rc;
    3145             : 
    3146           0 :         mem_ctx = talloc_new(NULL);
    3147           0 :         if (mem_ctx == NULL) {
    3148           0 :                 DEBUG(0, ("talloc_new failed\n"));
    3149           0 :                 return NT_STATUS_NO_MEMORY;
    3150             :         }
    3151             : 
    3152           0 :         filter = talloc_asprintf(mem_ctx, "(sambaSid=%s)",
    3153           0 :                                  dom_sid_str_buf(&map->sid, &buf));
    3154           0 :         if (filter == NULL) {
    3155           0 :                 result = NT_STATUS_NO_MEMORY;
    3156           0 :                 goto done;
    3157             :         }
    3158             : 
    3159           0 :         rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
    3160             :                             LDAP_SCOPE_SUBTREE, filter, attrs, True, &msg);
    3161           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    3162             : 
    3163           0 :         if ((rc == LDAP_SUCCESS) &&
    3164           0 :             (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    3165             :                                 msg) > 0)) {
    3166             : 
    3167           0 :                 DEBUG(3, ("SID %s already present in LDAP, refusing to add "
    3168             :                           "group mapping entry\n",
    3169             :                           dom_sid_str_buf(&map->sid, &buf)));
    3170           0 :                 result = NT_STATUS_GROUP_EXISTS;
    3171           0 :                 goto done;
    3172             :         }
    3173             : 
    3174           0 :         switch (map->sid_name_use) {
    3175             : 
    3176           0 :         case SID_NAME_DOM_GRP:
    3177             :                 /* To map a domain group we need to have a posix group
    3178             :                    to attach to. */
    3179           0 :                 result = ldapsam_map_posixgroup(mem_ctx, ldap_state, map);
    3180           0 :                 goto done;
    3181           0 :                 break;
    3182             : 
    3183           0 :         case SID_NAME_ALIAS:
    3184           0 :                 if (!sid_check_is_in_our_sam(&map->sid)
    3185           0 :                         && !sid_check_is_in_builtin(&map->sid) )
    3186             :                 {
    3187           0 :                         DEBUG(3, ("Refusing to map sid %s as an alias, not in our domain\n",
    3188             :                                   dom_sid_str_buf(&map->sid, &buf)));
    3189           0 :                         result = NT_STATUS_INVALID_PARAMETER;
    3190           0 :                         goto done;
    3191             :                 }
    3192           0 :                 break;
    3193             : 
    3194           0 :         default:
    3195           0 :                 DEBUG(3, ("Got invalid use '%s' for mapping\n",
    3196             :                           sid_type_lookup(map->sid_name_use)));
    3197           0 :                 result = NT_STATUS_INVALID_PARAMETER;
    3198           0 :                 goto done;
    3199             :         }
    3200             : 
    3201             :         /* Domain groups have been mapped in a separate routine, we have to
    3202             :          * create an alias now */
    3203             : 
    3204           0 :         if (map->gid == -1) {
    3205           0 :                 DEBUG(10, ("Refusing to map gid==-1\n"));
    3206           0 :                 result = NT_STATUS_INVALID_PARAMETER;
    3207           0 :                 goto done;
    3208             :         }
    3209             : 
    3210           0 :         id.id = map->gid;
    3211           0 :         id.type = ID_TYPE_GID;
    3212             : 
    3213           0 :         if (pdb_id_to_sid(&id, &sid)) {
    3214           0 :                 DEBUG(3, ("Gid %u is already mapped to SID %s, refusing to "
    3215             :                           "add\n",
    3216             :                           (unsigned int)map->gid,
    3217             :                           dom_sid_str_buf(&sid, &buf)));
    3218           0 :                 result = NT_STATUS_GROUP_EXISTS;
    3219           0 :                 goto done;
    3220             :         }
    3221             : 
    3222             :         /* Ok, enough checks done. It's still racy to go ahead now, but that's
    3223             :          * the best we can get out of LDAP. */
    3224             : 
    3225           0 :         dn = talloc_asprintf(mem_ctx, "sambaSid=%s,%s",
    3226           0 :                              dom_sid_str_buf(&map->sid, &buf),
    3227             :                              lp_ldap_group_suffix(talloc_tos()));
    3228           0 :         if (dn == NULL) {
    3229           0 :                 result = NT_STATUS_NO_MEMORY;
    3230           0 :                 goto done;
    3231             :         }
    3232             : 
    3233           0 :         mods = NULL;
    3234             : 
    3235           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3236             :                          &mods, "objectClass", LDAP_OBJ_SID_ENTRY);
    3237           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3238             :                          &mods, "objectClass", LDAP_OBJ_GROUPMAP);
    3239           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3240             :                          &mods, "sambaSid",
    3241           0 :                          dom_sid_str_buf(&map->sid, &buf));
    3242           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3243             :                          &mods, "sambaGroupType",
    3244           0 :                          talloc_asprintf(mem_ctx, "%d", map->sid_name_use));
    3245           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3246             :                          &mods, "displayName",
    3247           0 :                          map->nt_name);
    3248           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3249             :                          &mods, "description",
    3250           0 :                          map->comment);
    3251           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), NULL,
    3252             :                          &mods, "gidNumber",
    3253           0 :                          talloc_asprintf(mem_ctx, "%u",
    3254           0 :                                          (unsigned int)map->gid));
    3255           0 :         smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
    3256             : 
    3257           0 :         rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
    3258             : 
    3259           0 :         result = (rc == LDAP_SUCCESS) ?
    3260           0 :                 NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
    3261             : 
    3262           0 :  done:
    3263           0 :         TALLOC_FREE(mem_ctx);
    3264           0 :         return result;
    3265             : }
    3266             : 
    3267             : /**********************************************************************
    3268             :  * Update a group mapping entry. We're quite strict about what can be changed:
    3269             :  * Only the description and displayname may be changed. It simply does not
    3270             :  * make any sense to change the SID, gid or the type in a mapping.
    3271             :  *********************************************************************/
    3272             : 
    3273           0 : static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
    3274             :                                                    GROUP_MAP *map)
    3275             : {
    3276           0 :         struct ldapsam_privates *ldap_state =
    3277             :                 (struct ldapsam_privates *)methods->private_data;
    3278           0 :         int rc;
    3279           0 :         const char *filter, *dn;
    3280           0 :         LDAPMessage *msg = NULL;
    3281           0 :         LDAPMessage *entry = NULL;
    3282           0 :         LDAPMod **mods = NULL;
    3283           0 :         TALLOC_CTX *mem_ctx;
    3284           0 :         NTSTATUS result;
    3285           0 :         struct dom_sid_buf buf;
    3286             : 
    3287           0 :         mem_ctx = talloc_new(NULL);
    3288           0 :         if (mem_ctx == NULL) {
    3289           0 :                 DEBUG(0, ("talloc_new failed\n"));
    3290           0 :                 return NT_STATUS_NO_MEMORY;
    3291             :         }
    3292             : 
    3293             :         /* Make 100% sure that sid, gid and type are not changed by looking up
    3294             :          * exactly the values we're given in LDAP. */
    3295             : 
    3296           0 :         filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")"
    3297             :                                  "(sambaSid=%s)(gidNumber=%u)"
    3298             :                                  "(sambaGroupType=%d))",
    3299           0 :                                  dom_sid_str_buf(&map->sid, &buf),
    3300           0 :                                  (unsigned int)map->gid, map->sid_name_use);
    3301           0 :         if (filter == NULL) {
    3302           0 :                 result = NT_STATUS_NO_MEMORY;
    3303           0 :                 goto done;
    3304             :         }
    3305             : 
    3306           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
    3307             :                                    get_attr_list(mem_ctx, groupmap_attr_list),
    3308             :                                    &msg);
    3309           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    3310             : 
    3311           0 :         if ((rc != LDAP_SUCCESS) ||
    3312           0 :             (ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    3313           0 :                                 msg) != 1) ||
    3314           0 :             ((entry = ldap_first_entry(
    3315             :                       smbldap_get_ldap(ldap_state->smbldap_state),
    3316             :                       msg)) == NULL)) {
    3317           0 :                 result = NT_STATUS_NO_SUCH_GROUP;
    3318           0 :                 goto done;
    3319             :         }
    3320             : 
    3321           0 :         dn = smbldap_talloc_dn(
    3322             :                 mem_ctx, smbldap_get_ldap(ldap_state->smbldap_state), entry);
    3323             : 
    3324           0 :         if (dn == NULL) {
    3325           0 :                 result = NT_STATUS_NO_MEMORY;
    3326           0 :                 goto done;
    3327             :         }
    3328             : 
    3329           0 :         mods = NULL;
    3330           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3331           0 :                          &mods, "displayName", map->nt_name);
    3332           0 :         smbldap_make_mod(smbldap_get_ldap(ldap_state->smbldap_state), entry,
    3333           0 :                          &mods, "description", map->comment);
    3334           0 :         smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
    3335             : 
    3336           0 :         if (mods == NULL) {
    3337           0 :                 DEBUG(4, ("ldapsam_update_group_mapping_entry: mods is empty: "
    3338             :                           "nothing to do\n"));
    3339           0 :                 result = NT_STATUS_OK;
    3340           0 :                 goto done;
    3341             :         }
    3342             : 
    3343           0 :         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    3344             : 
    3345           0 :         if (rc != LDAP_SUCCESS) {
    3346           0 :                 result = NT_STATUS_ACCESS_DENIED;
    3347           0 :                 goto done;
    3348             :         }
    3349             : 
    3350           0 :         DEBUG(2, ("ldapsam_update_group_mapping_entry: successfully modified "
    3351             :                   "group %lu in LDAP\n", (unsigned long)map->gid));
    3352             : 
    3353           0 :         result = NT_STATUS_OK;
    3354             : 
    3355           0 :  done:
    3356           0 :         TALLOC_FREE(mem_ctx);
    3357           0 :         return result;
    3358             : }
    3359             : 
    3360             : /**********************************************************************
    3361             :  *********************************************************************/
    3362             : 
    3363           0 : static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
    3364             :                                                    struct dom_sid sid)
    3365             : {
    3366           0 :         struct ldapsam_privates *priv =
    3367             :                 (struct ldapsam_privates *)methods->private_data;
    3368           0 :         LDAPMessage *msg, *entry;
    3369           0 :         int rc;
    3370           0 :         NTSTATUS result;
    3371           0 :         TALLOC_CTX *mem_ctx;
    3372           0 :         char *filter;
    3373           0 :         struct dom_sid_buf buf;
    3374             : 
    3375           0 :         mem_ctx = talloc_new(NULL);
    3376           0 :         if (mem_ctx == NULL) {
    3377           0 :                 DEBUG(0, ("talloc_new failed\n"));
    3378           0 :                 return NT_STATUS_NO_MEMORY;
    3379             :         }
    3380             : 
    3381           0 :         filter = talloc_asprintf(mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")("LDAP_ATTRIBUTE_SID"=%s))",
    3382             :                                  dom_sid_str_buf(&sid, &buf));
    3383           0 :         if (filter == NULL) {
    3384           0 :                 result = NT_STATUS_NO_MEMORY;
    3385           0 :                 goto done;
    3386             :         }
    3387           0 :         rc = smbldap_search_suffix(priv->smbldap_state, filter,
    3388             :                                    get_attr_list(mem_ctx, groupmap_attr_list),
    3389             :                                    &msg);
    3390           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    3391             : 
    3392           0 :         if ((rc != LDAP_SUCCESS) ||
    3393           0 :             (ldap_count_entries(priv2ld(priv), msg) != 1) ||
    3394           0 :             ((entry = ldap_first_entry(priv2ld(priv), msg)) == NULL)) {
    3395           0 :                 result = NT_STATUS_NO_SUCH_GROUP;
    3396           0 :                 goto done;
    3397             :         }
    3398             : 
    3399           0 :         rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
    3400             :                                   get_attr_list(mem_ctx,
    3401             :                                                 groupmap_attr_list_to_delete));
    3402             : 
    3403           0 :         if ((rc == LDAP_NAMING_VIOLATION) ||
    3404           0 :             (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
    3405             :             (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
    3406           0 :                 const char *attrs[] = { "sambaGroupType", "description",
    3407             :                                         "displayName", "sambaSIDList",
    3408             :                                         NULL };
    3409             : 
    3410             :                 /* Second try. Don't delete the sambaSID attribute, this is
    3411             :                    for "old" entries that are tacked on a winbind
    3412             :                    sambaIdmapEntry. */
    3413             : 
    3414           0 :                 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
    3415             :                                           LDAP_OBJ_GROUPMAP, attrs);
    3416             :         }
    3417             : 
    3418           0 :         if ((rc == LDAP_NAMING_VIOLATION) ||
    3419           0 :             (rc == LDAP_NOT_ALLOWED_ON_RDN) ||
    3420             :             (rc == LDAP_OBJECT_CLASS_VIOLATION)) {
    3421           0 :                 const char *attrs[] = { "sambaGroupType", "description",
    3422             :                                         "displayName", "sambaSIDList",
    3423             :                                         "gidNumber", NULL };
    3424             : 
    3425             :                 /* Third try. This is a post-3.0.21 alias (containing only
    3426             :                  * sambaSidEntry and sambaGroupMapping classes), we also have
    3427             :                  * to delete the gidNumber attribute, only the sambaSidEntry
    3428             :                  * remains */
    3429             : 
    3430           0 :                 rc = ldapsam_delete_entry(priv, mem_ctx, entry,
    3431             :                                           LDAP_OBJ_GROUPMAP, attrs);
    3432             :         }
    3433             : 
    3434           0 :         result = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
    3435             : 
    3436           0 :  done:
    3437           0 :         TALLOC_FREE(mem_ctx);
    3438           0 :         return result;
    3439             :  }
    3440             : 
    3441             : /**********************************************************************
    3442             :  *********************************************************************/
    3443             : 
    3444           0 : static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods,
    3445             :                                     bool update)
    3446             : {
    3447           0 :         struct ldapsam_privates *ldap_state =
    3448             :                 (struct ldapsam_privates *)my_methods->private_data;
    3449           0 :         const char *filter = NULL;
    3450           0 :         int rc;
    3451           0 :         const char **attr_list;
    3452             : 
    3453           0 :         filter = "(objectclass="LDAP_OBJ_GROUPMAP")";
    3454           0 :         attr_list = get_attr_list( NULL, groupmap_attr_list );
    3455           0 :         rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
    3456             :                             LDAP_SCOPE_SUBTREE, filter,
    3457             :                             attr_list, 0, &ldap_state->result);
    3458           0 :         TALLOC_FREE(attr_list);
    3459             : 
    3460           0 :         if (rc != LDAP_SUCCESS) {
    3461           0 :                 DEBUG(0, ("ldapsam_setsamgrent: LDAP search failed: %s\n",
    3462             :                           ldap_err2string(rc)));
    3463           0 :                 DEBUG(3, ("ldapsam_setsamgrent: Query was: %s, %s\n",
    3464             :                           lp_ldap_suffix(), filter));
    3465           0 :                 ldap_msgfree(ldap_state->result);
    3466           0 :                 ldap_state->result = NULL;
    3467           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3468             :         }
    3469             : 
    3470           0 :         DEBUG(2, ("ldapsam_setsamgrent: %d entries in the base!\n",
    3471             :                   ldap_count_entries(
    3472             :                           smbldap_get_ldap(ldap_state->smbldap_state),
    3473             :                           ldap_state->result)));
    3474             : 
    3475           0 :         ldap_state->entry =
    3476           0 :                 ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    3477             :                                  ldap_state->result);
    3478           0 :         ldap_state->index = 0;
    3479             : 
    3480           0 :         return NT_STATUS_OK;
    3481             : }
    3482             : 
    3483             : /**********************************************************************
    3484             :  *********************************************************************/
    3485             : 
    3486           0 : static void ldapsam_endsamgrent(struct pdb_methods *my_methods)
    3487             : {
    3488           0 :         ldapsam_endsampwent(my_methods);
    3489           0 : }
    3490             : 
    3491             : /**********************************************************************
    3492             :  *********************************************************************/
    3493             : 
    3494           0 : static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
    3495             :                                     GROUP_MAP *map)
    3496             : {
    3497           0 :         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
    3498           0 :         struct ldapsam_privates *ldap_state =
    3499             :                 (struct ldapsam_privates *)my_methods->private_data;
    3500           0 :         bool bret = False;
    3501             : 
    3502           0 :         while (!bret) {
    3503           0 :                 if (!ldap_state->entry)
    3504           0 :                         return ret;
    3505             : 
    3506           0 :                 ldap_state->index++;
    3507           0 :                 bret = init_group_from_ldap(ldap_state, map,
    3508             :                                             ldap_state->entry);
    3509             : 
    3510           0 :                 ldap_state->entry = ldap_next_entry(
    3511             :                         smbldap_get_ldap(ldap_state->smbldap_state),
    3512             :                         ldap_state->entry);
    3513             :         }
    3514             : 
    3515           0 :         return NT_STATUS_OK;
    3516             : }
    3517             : 
    3518             : /**********************************************************************
    3519             :  *********************************************************************/
    3520             : 
    3521           0 : static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
    3522             :                                            const struct dom_sid *domsid, enum lsa_SidType sid_name_use,
    3523             :                                            GROUP_MAP ***pp_rmap,
    3524             :                                            size_t *p_num_entries,
    3525             :                                            bool unix_only)
    3526             : {
    3527           0 :         GROUP_MAP *map = NULL;
    3528           0 :         size_t entries = 0;
    3529             : 
    3530           0 :         *p_num_entries = 0;
    3531           0 :         *pp_rmap = NULL;
    3532             : 
    3533           0 :         if (!NT_STATUS_IS_OK(ldapsam_setsamgrent(methods, False))) {
    3534           0 :                 DEBUG(0, ("ldapsam_enum_group_mapping: Unable to open "
    3535             :                           "passdb\n"));
    3536           0 :                 return NT_STATUS_ACCESS_DENIED;
    3537             :         }
    3538             : 
    3539           0 :         while (true) {
    3540             : 
    3541           0 :                 map = talloc_zero(NULL, GROUP_MAP);
    3542           0 :                 if (!map) {
    3543           0 :                         return NT_STATUS_NO_MEMORY;
    3544             :                 }
    3545             : 
    3546           0 :                 if (!NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, map))) {
    3547           0 :                         TALLOC_FREE(map);
    3548           0 :                         break;
    3549             :                 }
    3550             : 
    3551           0 :                 if (sid_name_use != SID_NAME_UNKNOWN &&
    3552           0 :                     sid_name_use != map->sid_name_use) {
    3553           0 :                         DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
    3554             :                                   "not of the requested type\n",
    3555             :                                   map->nt_name));
    3556           0 :                         continue;
    3557             :                 }
    3558           0 :                 if (unix_only == ENUM_ONLY_MAPPED && map->gid == -1) {
    3559           0 :                         DEBUG(11,("ldapsam_enum_group_mapping: group %s is "
    3560             :                                   "non mapped\n", map->nt_name));
    3561           0 :                         continue;
    3562             :                 }
    3563             : 
    3564           0 :                 *pp_rmap = talloc_realloc(NULL, *pp_rmap,
    3565             :                                                 GROUP_MAP *, entries + 1);
    3566           0 :                 if (!(*pp_rmap)) {
    3567           0 :                         DEBUG(0,("ldapsam_enum_group_mapping: Unable to "
    3568             :                                  "enlarge group map!\n"));
    3569           0 :                         return NT_STATUS_UNSUCCESSFUL;
    3570             :                 }
    3571             : 
    3572           0 :                 (*pp_rmap)[entries] = talloc_move((*pp_rmap), &map);
    3573             : 
    3574           0 :                 entries += 1;
    3575             :         }
    3576             : 
    3577           0 :         ldapsam_endsamgrent(methods);
    3578             : 
    3579           0 :         *p_num_entries = entries;
    3580             : 
    3581           0 :         return NT_STATUS_OK;
    3582             : }
    3583             : 
    3584           0 : static NTSTATUS ldapsam_modify_aliasmem(struct pdb_methods *methods,
    3585             :                                         const struct dom_sid *alias,
    3586             :                                         const struct dom_sid *member,
    3587             :                                         int modop)
    3588             : {
    3589           0 :         struct ldapsam_privates *ldap_state =
    3590             :                 (struct ldapsam_privates *)methods->private_data;
    3591           0 :         char *dn = NULL;
    3592           0 :         LDAPMessage *result = NULL;
    3593           0 :         LDAPMessage *entry = NULL;
    3594           0 :         int count;
    3595           0 :         LDAPMod **mods = NULL;
    3596           0 :         int rc;
    3597           0 :         enum lsa_SidType type = SID_NAME_USE_NONE;
    3598           0 :         struct dom_sid_buf tmp;
    3599             : 
    3600           0 :         char *filter = NULL;
    3601             : 
    3602           0 :         if (sid_check_is_in_builtin(alias)) {
    3603           0 :                 type = SID_NAME_ALIAS;
    3604             :         }
    3605             : 
    3606           0 :         if (sid_check_is_in_our_sam(alias)) {
    3607           0 :                 type = SID_NAME_ALIAS;
    3608             :         }
    3609             : 
    3610           0 :         if (type == SID_NAME_USE_NONE) {
    3611           0 :                 struct dom_sid_buf buf;
    3612           0 :                 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
    3613             :                           dom_sid_str_buf(alias, &buf)));
    3614           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3615             :         }
    3616             : 
    3617           0 :         if (asprintf(&filter,
    3618             :                      "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
    3619             :                      LDAP_OBJ_GROUPMAP,
    3620             :                      dom_sid_str_buf(alias, &tmp),
    3621             :                      type) < 0) {
    3622           0 :                 return NT_STATUS_NO_MEMORY;
    3623             :         }
    3624             : 
    3625           0 :         if (ldapsam_search_one_group(ldap_state, filter,
    3626             :                                      &result) != LDAP_SUCCESS) {
    3627           0 :                 SAFE_FREE(filter);
    3628           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3629             :         }
    3630             : 
    3631           0 :         count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    3632             :                                    result);
    3633             : 
    3634           0 :         if (count < 1) {
    3635           0 :                 DEBUG(4, ("ldapsam_modify_aliasmem: Did not find alias\n"));
    3636           0 :                 ldap_msgfree(result);
    3637           0 :                 SAFE_FREE(filter);
    3638           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3639             :         }
    3640             : 
    3641           0 :         if (count > 1) {
    3642           0 :                 DEBUG(1, ("ldapsam_modify_aliasmem: Duplicate entries for "
    3643             :                           "filter %s: count=%d\n", filter, count));
    3644           0 :                 ldap_msgfree(result);
    3645           0 :                 SAFE_FREE(filter);
    3646           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3647             :         }
    3648             : 
    3649           0 :         SAFE_FREE(filter);
    3650             : 
    3651           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    3652             :                                  result);
    3653             : 
    3654           0 :         if (!entry) {
    3655           0 :                 ldap_msgfree(result);
    3656           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3657             :         }
    3658             : 
    3659           0 :         dn = smbldap_talloc_dn(talloc_tos(),
    3660             :                                smbldap_get_ldap(ldap_state->smbldap_state),
    3661             :                                entry);
    3662           0 :         if (!dn) {
    3663           0 :                 ldap_msgfree(result);
    3664           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3665             :         }
    3666             : 
    3667           0 :         smbldap_set_mod(&mods, modop,
    3668             :                         get_attr_key2string(groupmap_attr_list,
    3669             :                                             LDAP_ATTR_SID_LIST),
    3670           0 :                         dom_sid_str_buf(member, &tmp));
    3671             : 
    3672           0 :         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    3673             : 
    3674           0 :         ldap_mods_free(mods, True);
    3675           0 :         ldap_msgfree(result);
    3676           0 :         TALLOC_FREE(dn);
    3677             : 
    3678           0 :         if (rc == LDAP_TYPE_OR_VALUE_EXISTS) {
    3679           0 :                 return NT_STATUS_MEMBER_IN_ALIAS;
    3680             :         }
    3681             : 
    3682           0 :         if (rc == LDAP_NO_SUCH_ATTRIBUTE) {
    3683           0 :                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
    3684             :         }
    3685             : 
    3686           0 :         if (rc != LDAP_SUCCESS) {
    3687           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3688             :         }
    3689             : 
    3690           0 :         return NT_STATUS_OK;
    3691             : }
    3692             : 
    3693           0 : static NTSTATUS ldapsam_add_aliasmem(struct pdb_methods *methods,
    3694             :                                      const struct dom_sid *alias,
    3695             :                                      const struct dom_sid *member)
    3696             : {
    3697           0 :         return ldapsam_modify_aliasmem(methods, alias, member, LDAP_MOD_ADD);
    3698             : }
    3699             : 
    3700           0 : static NTSTATUS ldapsam_del_aliasmem(struct pdb_methods *methods,
    3701             :                                      const struct dom_sid *alias,
    3702             :                                      const struct dom_sid *member)
    3703             : {
    3704           0 :         return ldapsam_modify_aliasmem(methods, alias, member,
    3705             :                                        LDAP_MOD_DELETE);
    3706             : }
    3707             : 
    3708           0 : static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods,
    3709             :                                       const struct dom_sid *alias,
    3710             :                                       TALLOC_CTX *mem_ctx,
    3711             :                                       struct dom_sid **pp_members,
    3712             :                                       size_t *p_num_members)
    3713             : {
    3714           0 :         struct ldapsam_privates *ldap_state =
    3715             :                 (struct ldapsam_privates *)methods->private_data;
    3716           0 :         LDAPMessage *result = NULL;
    3717           0 :         LDAPMessage *entry = NULL;
    3718           0 :         int count;
    3719           0 :         char **values = NULL;
    3720           0 :         int i;
    3721           0 :         char *filter = NULL;
    3722           0 :         uint32_t num_members = 0;
    3723           0 :         enum lsa_SidType type = SID_NAME_USE_NONE;
    3724           0 :         struct dom_sid_buf tmp;
    3725             : 
    3726           0 :         *pp_members = NULL;
    3727           0 :         *p_num_members = 0;
    3728             : 
    3729           0 :         if (sid_check_is_in_builtin(alias)) {
    3730           0 :                 type = SID_NAME_ALIAS;
    3731             :         }
    3732             : 
    3733           0 :         if (sid_check_is_in_our_sam(alias)) {
    3734           0 :                 type = SID_NAME_ALIAS;
    3735             :         }
    3736             : 
    3737           0 :         if (type == SID_NAME_USE_NONE) {
    3738           0 :                 DEBUG(5, ("SID %s is neither in builtin nor in our domain!\n",
    3739             :                           dom_sid_str_buf(alias, &tmp)));
    3740           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3741             :         }
    3742             : 
    3743           0 :         if (asprintf(&filter,
    3744             :                      "(&(objectClass=%s)(sambaSid=%s)(sambaGroupType=%d))",
    3745             :                      LDAP_OBJ_GROUPMAP,
    3746             :                      dom_sid_str_buf(alias, &tmp),
    3747             :                      type) < 0) {
    3748           0 :                 return NT_STATUS_NO_MEMORY;
    3749             :         }
    3750             : 
    3751           0 :         if (ldapsam_search_one_group(ldap_state, filter,
    3752             :                                      &result) != LDAP_SUCCESS) {
    3753           0 :                 SAFE_FREE(filter);
    3754           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3755             :         }
    3756             : 
    3757           0 :         count = ldap_count_entries(smbldap_get_ldap(ldap_state->smbldap_state),
    3758             :                                    result);
    3759             : 
    3760           0 :         if (count < 1) {
    3761           0 :                 DEBUG(4, ("ldapsam_enum_aliasmem: Did not find alias\n"));
    3762           0 :                 ldap_msgfree(result);
    3763           0 :                 SAFE_FREE(filter);
    3764           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3765             :         }
    3766             : 
    3767           0 :         if (count > 1) {
    3768           0 :                 DEBUG(1, ("ldapsam_enum_aliasmem: Duplicate entries for "
    3769             :                           "filter %s: count=%d\n", filter, count));
    3770           0 :                 ldap_msgfree(result);
    3771           0 :                 SAFE_FREE(filter);
    3772           0 :                 return NT_STATUS_NO_SUCH_ALIAS;
    3773             :         }
    3774             : 
    3775           0 :         SAFE_FREE(filter);
    3776             : 
    3777           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    3778             :                                  result);
    3779             : 
    3780           0 :         if (!entry) {
    3781           0 :                 ldap_msgfree(result);
    3782           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3783             :         }
    3784             : 
    3785           0 :         values = ldap_get_values(smbldap_get_ldap(ldap_state->smbldap_state),
    3786             :                                  entry,
    3787             :                                  get_attr_key2string(groupmap_attr_list,
    3788             :                                                      LDAP_ATTR_SID_LIST));
    3789             : 
    3790           0 :         if (values == NULL) {
    3791           0 :                 ldap_msgfree(result);
    3792           0 :                 return NT_STATUS_OK;
    3793             :         }
    3794             : 
    3795           0 :         count = ldap_count_values(values);
    3796             : 
    3797           0 :         for (i=0; i<count; i++) {
    3798           0 :                 struct dom_sid member;
    3799           0 :                 NTSTATUS status;
    3800             : 
    3801           0 :                 if (!string_to_sid(&member, values[i]))
    3802           0 :                         continue;
    3803             : 
    3804           0 :                 status = add_sid_to_array(mem_ctx, &member, pp_members,
    3805             :                                           &num_members);
    3806           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3807           0 :                         ldap_value_free(values);
    3808           0 :                         ldap_msgfree(result);
    3809           0 :                         return status;
    3810             :                 }
    3811             :         }
    3812             : 
    3813           0 :         *p_num_members = num_members;
    3814           0 :         ldap_value_free(values);
    3815           0 :         ldap_msgfree(result);
    3816             : 
    3817           0 :         return NT_STATUS_OK;
    3818             : }
    3819             : 
    3820           0 : static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
    3821             :                                           TALLOC_CTX *mem_ctx,
    3822             :                                           const struct dom_sid *domain_sid,
    3823             :                                           const struct dom_sid *members,
    3824             :                                           size_t num_members,
    3825             :                                           uint32_t **pp_alias_rids,
    3826             :                                           size_t *p_num_alias_rids)
    3827             : {
    3828           0 :         struct ldapsam_privates *ldap_state =
    3829             :                 (struct ldapsam_privates *)methods->private_data;
    3830           0 :         LDAP *ldap_struct;
    3831             : 
    3832           0 :         const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
    3833             : 
    3834           0 :         LDAPMessage *result = NULL;
    3835           0 :         LDAPMessage *entry = NULL;
    3836           0 :         int i;
    3837           0 :         int rc;
    3838           0 :         char *filter;
    3839           0 :         enum lsa_SidType type = SID_NAME_USE_NONE;
    3840           0 :         bool is_builtin = false;
    3841           0 :         bool sid_added = false;
    3842             : 
    3843           0 :         *pp_alias_rids = NULL;
    3844           0 :         *p_num_alias_rids = 0;
    3845             : 
    3846           0 :         if (sid_check_is_builtin(domain_sid)) {
    3847           0 :                 is_builtin = true;
    3848           0 :                 type = SID_NAME_ALIAS;
    3849             :         }
    3850             : 
    3851           0 :         if (sid_check_is_our_sam(domain_sid)) {
    3852           0 :                 type = SID_NAME_ALIAS;
    3853             :         }
    3854             : 
    3855           0 :         if (type == SID_NAME_USE_NONE) {
    3856           0 :                 struct dom_sid_buf buf;
    3857           0 :                 DEBUG(5, ("SID %s is neither builtin nor domain!\n",
    3858             :                           dom_sid_str_buf(domain_sid, &buf)));
    3859           0 :                 return NT_STATUS_UNSUCCESSFUL;
    3860             :         }
    3861             : 
    3862           0 :         if (num_members == 0) {
    3863           0 :                 return NT_STATUS_OK;
    3864             :         }
    3865             : 
    3866           0 :         filter = talloc_asprintf(mem_ctx,
    3867             :                                  "(&(objectclass="LDAP_OBJ_GROUPMAP")(sambaGroupType=%d)(|",
    3868             :                                  type);
    3869             : 
    3870           0 :         for (i=0; i<num_members; i++) {
    3871           0 :                 struct dom_sid_buf buf;
    3872           0 :                 filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
    3873             :                                          filter,
    3874           0 :                                          dom_sid_str_buf(&members[i], &buf));
    3875             :         }
    3876             : 
    3877           0 :         filter = talloc_asprintf(mem_ctx, "%s))", filter);
    3878             : 
    3879           0 :         if (filter == NULL) {
    3880           0 :                 return NT_STATUS_NO_MEMORY;
    3881             :         }
    3882             : 
    3883           0 :         if (is_builtin &&
    3884           0 :             ldap_state->search_cache.filter &&
    3885           0 :             strcmp(ldap_state->search_cache.filter, filter) == 0) {
    3886           0 :                 filter = talloc_move(filter, &ldap_state->search_cache.filter);
    3887           0 :                 result = ldap_state->search_cache.result;
    3888           0 :                 ldap_state->search_cache.result = NULL;
    3889             :         } else {
    3890           0 :                 rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_suffix(),
    3891             :                                     LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
    3892           0 :                 if (rc != LDAP_SUCCESS) {
    3893           0 :                         return NT_STATUS_UNSUCCESSFUL;
    3894             :                 }
    3895           0 :                 smbldap_talloc_autofree_ldapmsg(filter, result);
    3896             :         }
    3897             : 
    3898           0 :         ldap_struct = smbldap_get_ldap(ldap_state->smbldap_state);
    3899             : 
    3900           0 :         for (entry = ldap_first_entry(ldap_struct, result);
    3901           0 :              entry != NULL;
    3902           0 :              entry = ldap_next_entry(ldap_struct, entry))
    3903             :         {
    3904           0 :                 fstring sid_str;
    3905           0 :                 struct dom_sid sid;
    3906           0 :                 uint32_t rid;
    3907             : 
    3908           0 :                 if (!smbldap_get_single_attribute(ldap_struct, entry,
    3909             :                                                   LDAP_ATTRIBUTE_SID,
    3910             :                                                   sid_str,
    3911             :                                                   sizeof(sid_str)-1))
    3912           0 :                         continue;
    3913             : 
    3914           0 :                 if (!string_to_sid(&sid, sid_str))
    3915           0 :                         continue;
    3916             : 
    3917           0 :                 if (!sid_peek_check_rid(domain_sid, &sid, &rid))
    3918           0 :                         continue;
    3919             : 
    3920           0 :                 sid_added = true;
    3921             : 
    3922           0 :                 if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids,
    3923             :                                         p_num_alias_rids)) {
    3924           0 :                         return NT_STATUS_NO_MEMORY;
    3925             :                 }
    3926             :         }
    3927             : 
    3928           0 :         if (!is_builtin && !sid_added) {
    3929           0 :                 TALLOC_FREE(ldap_state->search_cache.filter);
    3930             :                 /*
    3931             :                  * Note: result is a talloc child of filter because of the
    3932             :                  * smbldap_talloc_autofree_ldapmsg() usage
    3933             :                  */
    3934           0 :                 ldap_state->search_cache.filter = talloc_move(ldap_state, &filter);
    3935           0 :                 ldap_state->search_cache.result = result;
    3936             :         }
    3937             : 
    3938           0 :         return NT_STATUS_OK;
    3939             : }
    3940             : 
    3941           0 : static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
    3942             :                                                    enum pdb_policy_type type,
    3943             :                                                    uint32_t value)
    3944             : {
    3945           0 :         NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
    3946           0 :         int rc;
    3947           0 :         LDAPMod **mods = NULL;
    3948           0 :         fstring value_string;
    3949           0 :         const char *policy_attr = NULL;
    3950             : 
    3951           0 :         struct ldapsam_privates *ldap_state =
    3952             :                 (struct ldapsam_privates *)methods->private_data;
    3953             : 
    3954           0 :         DEBUG(10,("ldapsam_set_account_policy_in_ldap\n"));
    3955             : 
    3956           0 :         if (!ldap_state->domain_dn) {
    3957           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3958             :         }
    3959             : 
    3960           0 :         policy_attr = get_account_policy_attr(type);
    3961           0 :         if (policy_attr == NULL) {
    3962           0 :                 DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
    3963             :                          "policy\n"));
    3964           0 :                 return ntstatus;
    3965             :         }
    3966             : 
    3967           0 :         slprintf(value_string, sizeof(value_string) - 1, "%i", value);
    3968             : 
    3969           0 :         smbldap_set_mod(&mods, LDAP_MOD_REPLACE, policy_attr, value_string);
    3970             : 
    3971           0 :         rc = smbldap_modify(ldap_state->smbldap_state, ldap_state->domain_dn,
    3972             :                             mods);
    3973             : 
    3974           0 :         ldap_mods_free(mods, True);
    3975             : 
    3976           0 :         if (rc != LDAP_SUCCESS) {
    3977           0 :                 return ntstatus;
    3978             :         }
    3979             : 
    3980           0 :         if (!cache_account_policy_set(type, value)) {
    3981           0 :                 DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
    3982             :                          "update local tdb cache\n"));
    3983           0 :                 return ntstatus;
    3984             :         }
    3985             : 
    3986           0 :         return NT_STATUS_OK;
    3987             : }
    3988             : 
    3989           0 : static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
    3990             :                                            enum pdb_policy_type type,
    3991             :                                            uint32_t value)
    3992             : {
    3993           0 :         return ldapsam_set_account_policy_in_ldap(methods, type,
    3994             :                                                   value);
    3995             : }
    3996             : 
    3997           0 : static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
    3998             :                                                      enum pdb_policy_type type,
    3999             :                                                      uint32_t *value)
    4000             : {
    4001           0 :         NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
    4002           0 :         LDAPMessage *result = NULL;
    4003           0 :         LDAPMessage *entry = NULL;
    4004           0 :         int count;
    4005           0 :         int rc;
    4006           0 :         char **vals = NULL;
    4007           0 :         const char *filter;
    4008           0 :         const char *policy_attr = NULL;
    4009             : 
    4010           0 :         struct ldapsam_privates *ldap_state =
    4011             :                 (struct ldapsam_privates *)methods->private_data;
    4012             : 
    4013           0 :         const char *attrs[2];
    4014             : 
    4015           0 :         DEBUG(10,("ldapsam_get_account_policy_from_ldap\n"));
    4016             : 
    4017           0 :         if (!ldap_state->domain_dn) {
    4018           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4019             :         }
    4020             : 
    4021           0 :         policy_attr = get_account_policy_attr(type);
    4022           0 :         if (!policy_attr) {
    4023           0 :                 DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
    4024             :                          "policy index: %d\n", type));
    4025           0 :                 return ntstatus;
    4026             :         }
    4027             : 
    4028           0 :         attrs[0] = policy_attr;
    4029           0 :         attrs[1] = NULL;
    4030             : 
    4031           0 :         filter = "(objectClass="LDAP_OBJ_DOMINFO")";
    4032           0 :         rc = smbldap_search(ldap_state->smbldap_state, ldap_state->domain_dn,
    4033             :                             LDAP_SCOPE_BASE, filter, attrs, 0,
    4034             :                             &result);
    4035           0 :         if (rc != LDAP_SUCCESS) {
    4036           0 :                 return ntstatus;
    4037             :         }
    4038             : 
    4039           0 :         count = ldap_count_entries(priv2ld(ldap_state), result);
    4040           0 :         if (count < 1) {
    4041           0 :                 goto out;
    4042             :         }
    4043             : 
    4044           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    4045           0 :         if (entry == NULL) {
    4046           0 :                 goto out;
    4047             :         }
    4048             : 
    4049           0 :         vals = ldap_get_values(priv2ld(ldap_state), entry, policy_attr);
    4050           0 :         if (vals == NULL) {
    4051           0 :                 goto out;
    4052             :         }
    4053             : 
    4054           0 :         *value = (uint32_t)atol(vals[0]);
    4055             : 
    4056           0 :         ntstatus = NT_STATUS_OK;
    4057             : 
    4058           0 : out:
    4059           0 :         if (vals)
    4060           0 :                 ldap_value_free(vals);
    4061           0 :         ldap_msgfree(result);
    4062             : 
    4063           0 :         return ntstatus;
    4064             : }
    4065             : 
    4066             : /* wrapper around ldapsam_get_account_policy_from_ldap(), handles tdb as cache
    4067             : 
    4068             :    - if user hasn't decided to use account policies inside LDAP just reuse the
    4069             :      old tdb values
    4070             : 
    4071             :    - if there is a valid cache entry, return that
    4072             :    - if there is an LDAP entry, update cache and return
    4073             :    - otherwise set to default, update cache and return
    4074             : 
    4075             :    Guenther
    4076             : */
    4077           0 : static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
    4078             :                                            enum pdb_policy_type type,
    4079             :                                            uint32_t *value)
    4080             : {
    4081           0 :         NTSTATUS ntstatus;
    4082             : 
    4083           0 :         if (cache_account_policy_get(type, value)) {
    4084           0 :                 DEBUG(11,("ldapsam_get_account_policy: got valid value from "
    4085             :                           "cache\n"));
    4086           0 :                 return NT_STATUS_OK;
    4087             :         }
    4088             : 
    4089           0 :         ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
    4090             :                                                         value);
    4091           0 :         if (NT_STATUS_IS_OK(ntstatus)) {
    4092           0 :                 goto update_cache;
    4093             :         }
    4094             : 
    4095           0 :         DEBUG(10,("ldapsam_get_account_policy: failed to retrieve from "
    4096             :                   "ldap\n"));
    4097             : 
    4098             : #if 0
    4099             :         /* should we automagically migrate old tdb value here ? */
    4100             :         if (account_policy_get(type, value))
    4101             :                 goto update_ldap;
    4102             : 
    4103             :         DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
    4104             :                   "default\n", type));
    4105             : #endif
    4106             : 
    4107           0 :         if (!account_policy_get_default(type, value)) {
    4108           0 :                 return ntstatus;
    4109             :         }
    4110             : 
    4111             : /* update_ldap: */
    4112             : 
    4113           0 :         ntstatus = ldapsam_set_account_policy(methods, type, *value);
    4114           0 :         if (!NT_STATUS_IS_OK(ntstatus)) {
    4115           0 :                 return ntstatus;
    4116             :         }
    4117             : 
    4118           0 :  update_cache:
    4119             : 
    4120           0 :         if (!cache_account_policy_set(type, *value)) {
    4121           0 :                 DEBUG(0,("ldapsam_get_account_policy: failed to update local "
    4122             :                          "tdb as a cache\n"));
    4123           0 :                 return NT_STATUS_UNSUCCESSFUL;
    4124             :         }
    4125             : 
    4126           0 :         return NT_STATUS_OK;
    4127             : }
    4128             : 
    4129           0 : static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
    4130             :                                     const struct dom_sid *domain_sid,
    4131             :                                     int num_rids,
    4132             :                                     uint32_t *rids,
    4133             :                                     const char **names,
    4134             :                                     enum lsa_SidType *attrs)
    4135             : {
    4136           0 :         struct ldapsam_privates *ldap_state =
    4137             :                 (struct ldapsam_privates *)methods->private_data;
    4138           0 :         LDAPMessage *msg = NULL;
    4139           0 :         LDAPMessage *entry;
    4140           0 :         char *allsids = NULL;
    4141           0 :         size_t i, num_mapped;
    4142           0 :         int rc;
    4143           0 :         NTSTATUS result = NT_STATUS_NO_MEMORY;
    4144           0 :         TALLOC_CTX *mem_ctx;
    4145           0 :         LDAP *ld;
    4146           0 :         bool is_builtin;
    4147             : 
    4148           0 :         mem_ctx = talloc_new(NULL);
    4149           0 :         if (mem_ctx == NULL) {
    4150           0 :                 DEBUG(0, ("talloc_new failed\n"));
    4151           0 :                 goto done;
    4152             :         }
    4153             : 
    4154           0 :         if (!sid_check_is_builtin(domain_sid) &&
    4155           0 :             !sid_check_is_our_sam(domain_sid)) {
    4156           0 :                 result = NT_STATUS_INVALID_PARAMETER;
    4157           0 :                 goto done;
    4158             :         }
    4159             : 
    4160           0 :         if (num_rids == 0) {
    4161           0 :                 result = NT_STATUS_NONE_MAPPED;
    4162           0 :                 goto done;
    4163             :         }
    4164             : 
    4165           0 :         for (i=0; i<num_rids; i++)
    4166           0 :                 attrs[i] = SID_NAME_UNKNOWN;
    4167             : 
    4168           0 :         allsids = talloc_strdup(mem_ctx, "");
    4169           0 :         if (allsids == NULL) {
    4170           0 :                 goto done;
    4171             :         }
    4172             : 
    4173           0 :         for (i=0; i<num_rids; i++) {
    4174           0 :                 struct dom_sid sid;
    4175           0 :                 struct dom_sid_buf buf;
    4176           0 :                 sid_compose(&sid, domain_sid, rids[i]);
    4177           0 :                 allsids = talloc_asprintf_append_buffer(
    4178             :                         allsids,
    4179             :                         "(sambaSid=%s)",
    4180             :                         dom_sid_str_buf(&sid, &buf));
    4181           0 :                 if (allsids == NULL) {
    4182           0 :                         goto done;
    4183             :                 }
    4184             :         }
    4185             : 
    4186             :         /* First look for users */
    4187             : 
    4188             :         {
    4189           0 :                 char *filter;
    4190           0 :                 const char *ldap_attrs[] = { "uid", "sambaSid", NULL };
    4191             : 
    4192           0 :                 filter = talloc_asprintf(
    4193             :                         mem_ctx, ("(&(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")(|%s))"),
    4194             :                         allsids);
    4195             : 
    4196           0 :                 if (filter == NULL) {
    4197           0 :                         goto done;
    4198             :                 }
    4199             : 
    4200           0 :                 rc = smbldap_search(ldap_state->smbldap_state,
    4201             :                                     lp_ldap_user_suffix(talloc_tos()),
    4202             :                                     LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
    4203             :                                     &msg);
    4204           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    4205             :         }
    4206             : 
    4207           0 :         if (rc != LDAP_SUCCESS)
    4208           0 :                 goto done;
    4209             : 
    4210           0 :         ld = smbldap_get_ldap(ldap_state->smbldap_state);
    4211           0 :         num_mapped = 0;
    4212             : 
    4213           0 :         for (entry = ldap_first_entry(ld, msg);
    4214           0 :              entry != NULL;
    4215           0 :              entry = ldap_next_entry(ld, entry)) {
    4216           0 :                 uint32_t rid;
    4217           0 :                 int rid_index;
    4218           0 :                 const char *name;
    4219             : 
    4220           0 :                 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
    4221             :                                                     &rid)) {
    4222           0 :                         DEBUG(2, ("Could not find sid from ldap entry\n"));
    4223           0 :                         continue;
    4224             :                 }
    4225             : 
    4226           0 :                 name = smbldap_talloc_single_attribute(ld, entry, "uid",
    4227             :                                                        names);
    4228           0 :                 if (name == NULL) {
    4229           0 :                         DEBUG(2, ("Could not retrieve uid attribute\n"));
    4230           0 :                         continue;
    4231             :                 }
    4232             : 
    4233           0 :                 for (rid_index = 0; rid_index < num_rids; rid_index++) {
    4234           0 :                         if (rid == rids[rid_index])
    4235           0 :                                 break;
    4236             :                 }
    4237             : 
    4238           0 :                 if (rid_index == num_rids) {
    4239           0 :                         DEBUG(2, ("Got a RID not asked for: %d\n", rid));
    4240           0 :                         continue;
    4241             :                 }
    4242             : 
    4243           0 :                 attrs[rid_index] = SID_NAME_USER;
    4244           0 :                 names[rid_index] = name;
    4245           0 :                 num_mapped += 1;
    4246             :         }
    4247             : 
    4248           0 :         if (num_mapped == num_rids) {
    4249             :                 /* No need to look for groups anymore -- we're done */
    4250           0 :                 result = NT_STATUS_OK;
    4251           0 :                 goto done;
    4252             :         }
    4253             : 
    4254             :         /* Same game for groups */
    4255             : 
    4256             :         {
    4257           0 :                 char *filter;
    4258           0 :                 const char *ldap_attrs[] = { "cn", "displayName", "sambaSid",
    4259             :                                              "sambaGroupType", NULL };
    4260             : 
    4261           0 :                 filter = talloc_asprintf(
    4262             :                         mem_ctx, "(&(objectClass="LDAP_OBJ_GROUPMAP")(|%s))",
    4263             :                         allsids);
    4264           0 :                 if (filter == NULL) {
    4265           0 :                         goto done;
    4266             :                 }
    4267             : 
    4268           0 :                 rc = smbldap_search(ldap_state->smbldap_state,
    4269             :                                     lp_ldap_suffix(),
    4270             :                                     LDAP_SCOPE_SUBTREE, filter, ldap_attrs, 0,
    4271             :                                     &msg);
    4272           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, msg);
    4273             :         }
    4274             : 
    4275           0 :         if (rc != LDAP_SUCCESS)
    4276           0 :                 goto done;
    4277             : 
    4278             :         /* ldap_struct might have changed due to a reconnect */
    4279             : 
    4280           0 :         ld = smbldap_get_ldap(ldap_state->smbldap_state);
    4281             : 
    4282             :         /* For consistency checks, we already checked we're only domain or builtin */
    4283             : 
    4284           0 :         is_builtin = sid_check_is_builtin(domain_sid);
    4285             : 
    4286           0 :         for (entry = ldap_first_entry(ld, msg);
    4287           0 :              entry != NULL;
    4288           0 :              entry = ldap_next_entry(ld, entry))
    4289             :         {
    4290           0 :                 uint32_t rid;
    4291           0 :                 int rid_index;
    4292           0 :                 const char *attr;
    4293           0 :                 enum lsa_SidType type;
    4294           0 :                 const char *dn = smbldap_talloc_dn(mem_ctx, ld, entry);
    4295             : 
    4296           0 :                 attr = smbldap_talloc_single_attribute(ld, entry, "sambaGroupType",
    4297             :                                                        mem_ctx);
    4298           0 :                 if (attr == NULL) {
    4299           0 :                         DEBUG(2, ("Could not extract type from ldap entry %s\n",
    4300             :                                   dn));
    4301           0 :                         continue;
    4302             :                 }
    4303             : 
    4304           0 :                 type = (enum lsa_SidType)atol(attr);
    4305             : 
    4306             :                 /* Consistency checks */
    4307           0 :                 if ((is_builtin && (type != SID_NAME_ALIAS)) ||
    4308           0 :                     (!is_builtin && ((type != SID_NAME_ALIAS) &&
    4309           0 :                                      (type != SID_NAME_DOM_GRP)))) {
    4310           0 :                         DEBUG(2, ("Rejecting invalid group mapping entry %s\n", dn));
    4311             :                 }
    4312             : 
    4313           0 :                 if (!ldapsam_extract_rid_from_entry(ld, entry, domain_sid,
    4314             :                                                     &rid)) {
    4315           0 :                         DEBUG(2, ("Could not find sid from ldap entry %s\n", dn));
    4316           0 :                         continue;
    4317             :                 }
    4318             : 
    4319           0 :                 attr = smbldap_talloc_single_attribute(ld, entry, "displayName", names);
    4320             : 
    4321           0 :                 if (attr == NULL) {
    4322           0 :                         DEBUG(10, ("Could not retrieve 'displayName' attribute from %s\n",
    4323             :                                    dn));
    4324           0 :                         attr = smbldap_talloc_single_attribute(ld, entry, "cn", names);
    4325             :                 }
    4326             : 
    4327           0 :                 if (attr == NULL) {
    4328           0 :                         DEBUG(2, ("Could not retrieve naming attribute from %s\n",
    4329             :                                   dn));
    4330           0 :                         continue;
    4331             :                 }
    4332             : 
    4333           0 :                 for (rid_index = 0; rid_index < num_rids; rid_index++) {
    4334           0 :                         if (rid == rids[rid_index])
    4335           0 :                                 break;
    4336             :                 }
    4337             : 
    4338           0 :                 if (rid_index == num_rids) {
    4339           0 :                         DEBUG(2, ("Got a RID not asked for: %d\n", rid));
    4340           0 :                         continue;
    4341             :                 }
    4342             : 
    4343           0 :                 attrs[rid_index] = type;
    4344           0 :                 names[rid_index] = attr;
    4345           0 :                 num_mapped += 1;
    4346             :         }
    4347             : 
    4348           0 :         result = NT_STATUS_NONE_MAPPED;
    4349             : 
    4350           0 :         if (num_mapped > 0)
    4351           0 :                 result = (num_mapped == num_rids) ?
    4352           0 :                         NT_STATUS_OK : STATUS_SOME_UNMAPPED;
    4353           0 :  done:
    4354           0 :         TALLOC_FREE(mem_ctx);
    4355           0 :         return result;
    4356             : }
    4357             : 
    4358           0 : static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
    4359             : {
    4360           0 :         char *filter = NULL;
    4361           0 :         char *escaped = NULL;
    4362           0 :         char *result = NULL;
    4363             : 
    4364           0 :         if (asprintf(&filter, "(&%s(objectclass=%s))",
    4365             :                           "(uid=%u)", LDAP_OBJ_SAMBASAMACCOUNT) < 0) {
    4366           0 :                 goto done;
    4367             :         }
    4368             : 
    4369           0 :         escaped = escape_ldap_string(talloc_tos(), username);
    4370           0 :         if (escaped == NULL) goto done;
    4371             : 
    4372           0 :         result = talloc_string_sub(mem_ctx, filter, "%u", username);
    4373             : 
    4374           0 :  done:
    4375           0 :         SAFE_FREE(filter);
    4376           0 :         TALLOC_FREE(escaped);
    4377             : 
    4378           0 :         return result;
    4379             : }
    4380             : 
    4381           0 : static const char **talloc_attrs(TALLOC_CTX *mem_ctx, ...)
    4382             : {
    4383           0 :         int i, num = 0;
    4384           0 :         va_list ap;
    4385           0 :         const char **result;
    4386             : 
    4387           0 :         va_start(ap, mem_ctx);
    4388           0 :         while (va_arg(ap, const char *) != NULL)
    4389           0 :                 num += 1;
    4390           0 :         va_end(ap);
    4391             : 
    4392           0 :         if ((result = talloc_array(mem_ctx, const char *, num+1)) == NULL) {
    4393           0 :                 return NULL;
    4394             :         }
    4395             : 
    4396           0 :         va_start(ap, mem_ctx);
    4397           0 :         for (i=0; i<num; i++) {
    4398           0 :                 result[i] = talloc_strdup(result, va_arg(ap, const char*));
    4399           0 :                 if (result[i] == NULL) {
    4400           0 :                         talloc_free(result);
    4401           0 :                         va_end(ap);
    4402           0 :                         return NULL;
    4403             :                 }
    4404             :         }
    4405           0 :         va_end(ap);
    4406             : 
    4407           0 :         result[num] = NULL;
    4408           0 :         return result;
    4409             : }
    4410             : 
    4411             : struct ldap_search_state {
    4412             :         struct smbldap_state *connection;
    4413             : 
    4414             :         uint32_t acct_flags;
    4415             :         uint16_t group_type;
    4416             : 
    4417             :         const char *base;
    4418             :         int scope;
    4419             :         const char *filter;
    4420             :         const char **attrs;
    4421             :         int attrsonly;
    4422             :         void *pagedresults_cookie;
    4423             : 
    4424             :         LDAPMessage *entries, *current_entry;
    4425             :         bool (*ldap2displayentry)(struct ldap_search_state *state,
    4426             :                                   TALLOC_CTX *mem_ctx,
    4427             :                                   LDAP *ld, LDAPMessage *entry,
    4428             :                                   struct samr_displayentry *result);
    4429             : };
    4430             : 
    4431           0 : static bool ldapsam_search_firstpage(struct pdb_search *search)
    4432             : {
    4433           0 :         struct ldap_search_state *state =
    4434             :                 (struct ldap_search_state *)search->private_data;
    4435           0 :         LDAP *ld;
    4436           0 :         int rc = LDAP_OPERATIONS_ERROR;
    4437             : 
    4438           0 :         state->entries = NULL;
    4439             : 
    4440           0 :         if (smbldap_get_paged_results(state->connection)) {
    4441           0 :                 rc = smbldap_search_paged(state->connection, state->base,
    4442             :                                           state->scope, state->filter,
    4443             :                                           state->attrs, state->attrsonly,
    4444             :                                           lp_ldap_page_size(), &state->entries,
    4445             :                                           &state->pagedresults_cookie);
    4446             :         }
    4447             : 
    4448           0 :         if ((rc != LDAP_SUCCESS) || (state->entries == NULL)) {
    4449             : 
    4450           0 :                 if (state->entries != NULL) {
    4451             :                         /* Left over from unsuccessful paged attempt */
    4452           0 :                         ldap_msgfree(state->entries);
    4453           0 :                         state->entries = NULL;
    4454             :                 }
    4455             : 
    4456           0 :                 rc = smbldap_search(state->connection, state->base,
    4457             :                                     state->scope, state->filter, state->attrs,
    4458             :                                     state->attrsonly, &state->entries);
    4459             : 
    4460           0 :                 if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
    4461           0 :                         return False;
    4462             : 
    4463             :                 /* Ok, the server was lying. It told us it could do paged
    4464             :                  * searches when it could not. */
    4465           0 :                 smbldap_set_paged_results(state->connection, false);
    4466             :         }
    4467             : 
    4468           0 :         ld = smbldap_get_ldap(state->connection);
    4469           0 :         if ( ld == NULL) {
    4470           0 :                 DEBUG(5, ("Don't have an LDAP connection right after a "
    4471             :                           "search\n"));
    4472           0 :                 return False;
    4473             :         }
    4474           0 :         state->current_entry = ldap_first_entry(ld, state->entries);
    4475             : 
    4476           0 :         return True;
    4477             : }
    4478             : 
    4479           0 : static bool ldapsam_search_nextpage(struct pdb_search *search)
    4480             : {
    4481           0 :         struct ldap_search_state *state =
    4482             :                 (struct ldap_search_state *)search->private_data;
    4483           0 :         int rc;
    4484             : 
    4485           0 :         if (!smbldap_get_paged_results(state->connection)) {
    4486             :                 /* There is no next page when there are no paged results */
    4487           0 :                 return False;
    4488             :         }
    4489             : 
    4490           0 :         rc = smbldap_search_paged(state->connection, state->base,
    4491             :                                   state->scope, state->filter, state->attrs,
    4492             :                                   state->attrsonly, lp_ldap_page_size(),
    4493             :                                   &state->entries,
    4494             :                                   &state->pagedresults_cookie);
    4495             : 
    4496           0 :         if ((rc != LDAP_SUCCESS) || (state->entries == NULL))
    4497           0 :                 return False;
    4498             : 
    4499           0 :         state->current_entry = ldap_first_entry(
    4500             :                 smbldap_get_ldap(state->connection), state->entries);
    4501             : 
    4502           0 :         if (state->current_entry == NULL) {
    4503           0 :                 ldap_msgfree(state->entries);
    4504           0 :                 state->entries = NULL;
    4505           0 :                 return false;
    4506             :         }
    4507             : 
    4508           0 :         return True;
    4509             : }
    4510             : 
    4511           0 : static bool ldapsam_search_next_entry(struct pdb_search *search,
    4512             :                                       struct samr_displayentry *entry)
    4513             : {
    4514           0 :         struct ldap_search_state *state =
    4515             :                 (struct ldap_search_state *)search->private_data;
    4516           0 :         bool result;
    4517             : 
    4518           0 :  retry:
    4519           0 :         if ((state->entries == NULL) && (state->pagedresults_cookie == NULL))
    4520           0 :                 return False;
    4521             : 
    4522           0 :         if ((state->entries == NULL) &&
    4523           0 :             !ldapsam_search_nextpage(search))
    4524           0 :                     return False;
    4525             : 
    4526           0 :         if (state->current_entry == NULL) {
    4527           0 :                 return false;
    4528             :         }
    4529             : 
    4530           0 :         result = state->ldap2displayentry(state, search,
    4531             :                                           smbldap_get_ldap(state->connection),
    4532             :                                           state->current_entry, entry);
    4533             : 
    4534           0 :         if (!result) {
    4535           0 :                 char *dn;
    4536           0 :                 dn = ldap_get_dn(smbldap_get_ldap(state->connection),
    4537             :                                  state->current_entry);
    4538           0 :                 DEBUG(5, ("Skipping entry %s\n", dn != NULL ? dn : "<NULL>"));
    4539           0 :                 if (dn != NULL) ldap_memfree(dn);
    4540             :         }
    4541             : 
    4542           0 :         state->current_entry = ldap_next_entry(
    4543             :                 smbldap_get_ldap(state->connection), state->current_entry);
    4544             : 
    4545           0 :         if (state->current_entry == NULL) {
    4546           0 :                 ldap_msgfree(state->entries);
    4547           0 :                 state->entries = NULL;
    4548             :         }
    4549             : 
    4550           0 :         if (!result) goto retry;
    4551             : 
    4552           0 :         return True;
    4553             : }
    4554             : 
    4555           0 : static void ldapsam_search_end(struct pdb_search *search)
    4556             : {
    4557           0 :         struct ldap_search_state *state =
    4558             :                 (struct ldap_search_state *)search->private_data;
    4559           0 :         int rc;
    4560             : 
    4561           0 :         if (state->pagedresults_cookie == NULL)
    4562           0 :                 return;
    4563             : 
    4564           0 :         if (state->entries != NULL)
    4565           0 :                 ldap_msgfree(state->entries);
    4566             : 
    4567           0 :         state->entries = NULL;
    4568           0 :         state->current_entry = NULL;
    4569             : 
    4570           0 :         if (!smbldap_get_paged_results(state->connection)) {
    4571           0 :                 return;
    4572             :         }
    4573             : 
    4574             :         /* Tell the LDAP server we're not interested in the rest anymore. */
    4575             : 
    4576           0 :         rc = smbldap_search_paged(state->connection, state->base, state->scope,
    4577             :                                   state->filter, state->attrs,
    4578             :                                   state->attrsonly, 0, &state->entries,
    4579             :                                   &state->pagedresults_cookie);
    4580             : 
    4581           0 :         if (rc != LDAP_SUCCESS)
    4582           0 :                 DEBUG(5, ("Could not end search properly\n"));
    4583             : 
    4584           0 :         return;
    4585             : }
    4586             : 
    4587           0 : static bool ldapuser2displayentry(struct ldap_search_state *state,
    4588             :                                   TALLOC_CTX *mem_ctx,
    4589             :                                   LDAP *ld, LDAPMessage *entry,
    4590             :                                   struct samr_displayentry *result)
    4591             : {
    4592           0 :         char **vals;
    4593           0 :         size_t converted_size;
    4594           0 :         struct dom_sid sid;
    4595           0 :         uint32_t acct_flags;
    4596             : 
    4597           0 :         vals = ldap_get_values(ld, entry, "sambaAcctFlags");
    4598           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4599           0 :                 acct_flags = ACB_NORMAL;
    4600             :         } else {
    4601           0 :                 acct_flags = pdb_decode_acct_ctrl(vals[0]);
    4602           0 :                 ldap_value_free(vals);
    4603             :         }
    4604             : 
    4605           0 :         if ((state->acct_flags != 0) &&
    4606           0 :             ((state->acct_flags & acct_flags) == 0))
    4607           0 :                 return False;
    4608             : 
    4609           0 :         result->acct_flags = acct_flags;
    4610           0 :         result->account_name = "";
    4611           0 :         result->fullname = "";
    4612           0 :         result->description = "";
    4613             : 
    4614           0 :         vals = ldap_get_values(ld, entry, "uid");
    4615           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4616           0 :                 DEBUG(5, ("\"uid\" not found\n"));
    4617           0 :                 return False;
    4618             :         }
    4619           0 :         if (!pull_utf8_talloc(mem_ctx,
    4620           0 :                               discard_const_p(char *, &result->account_name),
    4621             :                               vals[0], &converted_size))
    4622             :         {
    4623           0 :                 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
    4624             :                          strerror(errno)));
    4625             :         }
    4626             : 
    4627           0 :         ldap_value_free(vals);
    4628             : 
    4629           0 :         vals = ldap_get_values(ld, entry, "displayName");
    4630           0 :         if ((vals == NULL) || (vals[0] == NULL))
    4631           0 :                 DEBUG(8, ("\"displayName\" not found\n"));
    4632           0 :         else if (!pull_utf8_talloc(mem_ctx,
    4633           0 :                                    discard_const_p(char *, &result->fullname),
    4634             :                                    vals[0], &converted_size))
    4635             :         {
    4636           0 :                 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
    4637             :                          strerror(errno)));
    4638             :         }
    4639             : 
    4640           0 :         ldap_value_free(vals);
    4641             : 
    4642           0 :         vals = ldap_get_values(ld, entry, "description");
    4643           0 :         if ((vals == NULL) || (vals[0] == NULL))
    4644           0 :                 DEBUG(8, ("\"description\" not found\n"));
    4645           0 :         else if (!pull_utf8_talloc(mem_ctx,
    4646           0 :                                    discard_const_p(char *, &result->description),
    4647             :                                    vals[0], &converted_size))
    4648             :         {
    4649           0 :                 DEBUG(0,("ldapuser2displayentry: pull_utf8_talloc failed: %s\n",
    4650             :                          strerror(errno)));
    4651             :         }
    4652             : 
    4653           0 :         ldap_value_free(vals);
    4654             : 
    4655           0 :         if ((result->account_name == NULL) ||
    4656           0 :             (result->fullname == NULL) ||
    4657           0 :             (result->description == NULL)) {
    4658           0 :                 DEBUG(0, ("talloc failed\n"));
    4659           0 :                 return False;
    4660             :         }
    4661             : 
    4662           0 :         vals = ldap_get_values(ld, entry, "sambaSid");
    4663           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4664           0 :                 DEBUG(0, ("\"objectSid\" not found\n"));
    4665           0 :                 return False;
    4666             :         }
    4667             : 
    4668           0 :         if (!string_to_sid(&sid, vals[0])) {
    4669           0 :                 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
    4670           0 :                 ldap_value_free(vals);
    4671           0 :                 return False;
    4672             :         }
    4673           0 :         ldap_value_free(vals);
    4674             : 
    4675           0 :         if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)) {
    4676           0 :                 struct dom_sid_buf buf;
    4677           0 :                 DEBUG(0, ("sid %s does not belong to our domain\n",
    4678             :                           dom_sid_str_buf(&sid, &buf)));
    4679           0 :                 return False;
    4680             :         }
    4681             : 
    4682           0 :         return True;
    4683             : }
    4684             : 
    4685             : 
    4686           0 : static bool ldapsam_search_users(struct pdb_methods *methods,
    4687             :                                  struct pdb_search *search,
    4688             :                                  uint32_t acct_flags)
    4689             : {
    4690           0 :         struct ldapsam_privates *ldap_state =
    4691             :                 (struct ldapsam_privates *)methods->private_data;
    4692           0 :         struct ldap_search_state *state;
    4693             : 
    4694           0 :         state = talloc(search, struct ldap_search_state);
    4695           0 :         if (state == NULL) {
    4696           0 :                 DEBUG(0, ("talloc failed\n"));
    4697           0 :                 return False;
    4698             :         }
    4699             : 
    4700           0 :         state->connection = ldap_state->smbldap_state;
    4701             : 
    4702           0 :         if ((acct_flags != 0) && ((acct_flags & ACB_NORMAL) != 0))
    4703           0 :                 state->base = lp_ldap_user_suffix(talloc_tos());
    4704           0 :         else if ((acct_flags != 0) &&
    4705           0 :                  ((acct_flags & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) != 0))
    4706           0 :                 state->base = lp_ldap_machine_suffix(talloc_tos());
    4707             :         else
    4708           0 :                 state->base = lp_ldap_suffix();
    4709             : 
    4710           0 :         state->acct_flags = acct_flags;
    4711           0 :         state->base = talloc_strdup(search, state->base);
    4712           0 :         state->scope = LDAP_SCOPE_SUBTREE;
    4713           0 :         state->filter = get_ldap_filter(search, "*");
    4714           0 :         state->attrs = talloc_attrs(search, "uid", "sambaSid",
    4715             :                                     "displayName", "description",
    4716             :                                     "sambaAcctFlags", NULL);
    4717           0 :         state->attrsonly = 0;
    4718           0 :         state->pagedresults_cookie = NULL;
    4719           0 :         state->entries = NULL;
    4720           0 :         state->ldap2displayentry = ldapuser2displayentry;
    4721             : 
    4722           0 :         if ((state->filter == NULL) || (state->attrs == NULL)) {
    4723           0 :                 DEBUG(0, ("talloc failed\n"));
    4724           0 :                 return False;
    4725             :         }
    4726             : 
    4727           0 :         search->private_data = state;
    4728           0 :         search->next_entry = ldapsam_search_next_entry;
    4729           0 :         search->search_end = ldapsam_search_end;
    4730             : 
    4731           0 :         return ldapsam_search_firstpage(search);
    4732             : }
    4733             : 
    4734           0 : static bool ldapgroup2displayentry(struct ldap_search_state *state,
    4735             :                                    TALLOC_CTX *mem_ctx,
    4736             :                                    LDAP *ld, LDAPMessage *entry,
    4737             :                                    struct samr_displayentry *result)
    4738             : {
    4739           0 :         char **vals;
    4740           0 :         size_t converted_size;
    4741           0 :         struct dom_sid sid;
    4742           0 :         uint16_t group_type;
    4743             : 
    4744           0 :         result->account_name = "";
    4745           0 :         result->fullname = "";
    4746           0 :         result->description = "";
    4747             : 
    4748             : 
    4749           0 :         vals = ldap_get_values(ld, entry, "sambaGroupType");
    4750           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4751           0 :                 DEBUG(5, ("\"sambaGroupType\" not found\n"));
    4752           0 :                 if (vals != NULL) {
    4753           0 :                         ldap_value_free(vals);
    4754             :                 }
    4755           0 :                 return False;
    4756             :         }
    4757             : 
    4758           0 :         group_type = atoi(vals[0]);
    4759             : 
    4760           0 :         if ((state->group_type != 0) &&
    4761           0 :             ((state->group_type != group_type))) {
    4762           0 :                 ldap_value_free(vals);
    4763           0 :                 return False;
    4764             :         }
    4765             : 
    4766           0 :         ldap_value_free(vals);
    4767             : 
    4768             :         /* display name is the NT group name */
    4769             : 
    4770           0 :         vals = ldap_get_values(ld, entry, "displayName");
    4771           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4772           0 :                 DEBUG(8, ("\"displayName\" not found\n"));
    4773             : 
    4774             :                 /* fallback to the 'cn' attribute */
    4775           0 :                 vals = ldap_get_values(ld, entry, "cn");
    4776           0 :                 if ((vals == NULL) || (vals[0] == NULL)) {
    4777           0 :                         DEBUG(5, ("\"cn\" not found\n"));
    4778           0 :                         return False;
    4779             :                 }
    4780           0 :                 if (!pull_utf8_talloc(mem_ctx,
    4781           0 :                                       discard_const_p(char *,
    4782             :                                                     &result->account_name),
    4783             :                                       vals[0], &converted_size))
    4784             :                 {
    4785           0 :                         DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc "
    4786             :                                   "failed: %s\n", strerror(errno)));
    4787             :                 }
    4788             :         }
    4789           0 :         else if (!pull_utf8_talloc(mem_ctx,
    4790           0 :                                    discard_const_p(char *,
    4791             :                                                  &result->account_name),
    4792             :                                    vals[0], &converted_size))
    4793             :         {
    4794           0 :                 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
    4795             :                           strerror(errno)));
    4796             :         }
    4797             : 
    4798           0 :         ldap_value_free(vals);
    4799             : 
    4800           0 :         vals = ldap_get_values(ld, entry, "description");
    4801           0 :         if ((vals == NULL) || (vals[0] == NULL))
    4802           0 :                 DEBUG(8, ("\"description\" not found\n"));
    4803           0 :         else if (!pull_utf8_talloc(mem_ctx,
    4804           0 :                                    discard_const_p(char *, &result->description),
    4805             :                                    vals[0], &converted_size))
    4806             :         {
    4807           0 :                 DEBUG(0,("ldapgroup2displayentry: pull_utf8_talloc failed: %s\n",
    4808             :                           strerror(errno)));
    4809             :         }
    4810           0 :         ldap_value_free(vals);
    4811             : 
    4812           0 :         if ((result->account_name == NULL) ||
    4813           0 :             (result->fullname == NULL) ||
    4814           0 :             (result->description == NULL)) {
    4815           0 :                 DEBUG(0, ("talloc failed\n"));
    4816           0 :                 return False;
    4817             :         }
    4818             : 
    4819           0 :         vals = ldap_get_values(ld, entry, "sambaSid");
    4820           0 :         if ((vals == NULL) || (vals[0] == NULL)) {
    4821           0 :                 DEBUG(0, ("\"objectSid\" not found\n"));
    4822           0 :                 if (vals != NULL) {
    4823           0 :                         ldap_value_free(vals);
    4824             :                 }
    4825           0 :                 return False;
    4826             :         }
    4827             : 
    4828           0 :         if (!string_to_sid(&sid, vals[0])) {
    4829           0 :                 DEBUG(0, ("Could not convert %s to SID\n", vals[0]));
    4830           0 :                 return False;
    4831             :         }
    4832             : 
    4833           0 :         ldap_value_free(vals);
    4834             : 
    4835           0 :         switch (group_type) {
    4836           0 :                 case SID_NAME_DOM_GRP:
    4837             :                 case SID_NAME_ALIAS:
    4838             : 
    4839           0 :                         if (!sid_peek_check_rid(get_global_sam_sid(), &sid, &result->rid)
    4840           0 :                                 && !sid_peek_check_rid(&global_sid_Builtin, &sid, &result->rid))
    4841             :                         {
    4842           0 :                                 struct dom_sid_buf buf;
    4843           0 :                                 DEBUG(0, ("%s is not in our domain\n",
    4844             :                                           dom_sid_str_buf(&sid, &buf)));
    4845           0 :                                 return False;
    4846             :                         }
    4847           0 :                         break;
    4848             : 
    4849           0 :                 default:
    4850           0 :                         DEBUG(0,("unknown group type: %d\n", group_type));
    4851           0 :                         return False;
    4852             :         }
    4853             : 
    4854           0 :         result->acct_flags = 0;
    4855             : 
    4856           0 :         return True;
    4857             : }
    4858             : 
    4859           0 : static bool ldapsam_search_grouptype(struct pdb_methods *methods,
    4860             :                                      struct pdb_search *search,
    4861             :                                      const struct dom_sid *sid,
    4862             :                                      enum lsa_SidType type)
    4863             : {
    4864           0 :         struct ldapsam_privates *ldap_state =
    4865             :                 (struct ldapsam_privates *)methods->private_data;
    4866           0 :         struct ldap_search_state *state;
    4867           0 :         struct dom_sid_buf tmp;
    4868             : 
    4869           0 :         state = talloc(search, struct ldap_search_state);
    4870           0 :         if (state == NULL) {
    4871           0 :                 DEBUG(0, ("talloc failed\n"));
    4872           0 :                 return False;
    4873             :         }
    4874             : 
    4875           0 :         state->connection = ldap_state->smbldap_state;
    4876             : 
    4877           0 :         state->base = lp_ldap_suffix();
    4878           0 :         state->connection = ldap_state->smbldap_state;
    4879           0 :         state->scope = LDAP_SCOPE_SUBTREE;
    4880           0 :         state->filter =      talloc_asprintf(search, "(&(objectclass="LDAP_OBJ_GROUPMAP")"
    4881             :                                         "(sambaGroupType=%d)(sambaSID=%s*))",
    4882             :                                          type,
    4883             :                                          dom_sid_str_buf(sid, &tmp));
    4884           0 :         state->attrs = talloc_attrs(search, "cn", "sambaSid",
    4885             :                                     "displayName", "description",
    4886             :                                     "sambaGroupType", NULL);
    4887           0 :         state->attrsonly = 0;
    4888           0 :         state->pagedresults_cookie = NULL;
    4889           0 :         state->entries = NULL;
    4890           0 :         state->group_type = type;
    4891           0 :         state->ldap2displayentry = ldapgroup2displayentry;
    4892             : 
    4893           0 :         if ((state->filter == NULL) || (state->attrs == NULL)) {
    4894           0 :                 DEBUG(0, ("talloc failed\n"));
    4895           0 :                 return False;
    4896             :         }
    4897             : 
    4898           0 :         search->private_data = state;
    4899           0 :         search->next_entry = ldapsam_search_next_entry;
    4900           0 :         search->search_end = ldapsam_search_end;
    4901             : 
    4902           0 :         return ldapsam_search_firstpage(search);
    4903             : }
    4904             : 
    4905           0 : static bool ldapsam_search_groups(struct pdb_methods *methods,
    4906             :                                   struct pdb_search *search)
    4907             : {
    4908           0 :         return ldapsam_search_grouptype(methods, search, get_global_sam_sid(), SID_NAME_DOM_GRP);
    4909             : }
    4910             : 
    4911           0 : static bool ldapsam_search_aliases(struct pdb_methods *methods,
    4912             :                                    struct pdb_search *search,
    4913             :                                    const struct dom_sid *sid)
    4914             : {
    4915           0 :         return ldapsam_search_grouptype(methods, search, sid, SID_NAME_ALIAS);
    4916             : }
    4917             : 
    4918           0 : static uint32_t ldapsam_capabilities(struct pdb_methods *methods)
    4919             : {
    4920           0 :         return PDB_CAP_STORE_RIDS;
    4921             : }
    4922             : 
    4923           0 : static NTSTATUS ldapsam_get_new_rid(struct ldapsam_privates *priv,
    4924             :                                     uint32_t *rid)
    4925             : {
    4926           0 :         struct smbldap_state *smbldap_state = priv->smbldap_state;
    4927             : 
    4928           0 :         LDAPMessage *result = NULL;
    4929           0 :         LDAPMessage *entry = NULL;
    4930           0 :         LDAPMod **mods = NULL;
    4931           0 :         NTSTATUS status;
    4932           0 :         char *value;
    4933           0 :         int rc;
    4934           0 :         uint32_t nextRid = 0;
    4935           0 :         const char *dn;
    4936           0 :         uint32_t tmp;
    4937           0 :         int error = 0;
    4938             : 
    4939           0 :         TALLOC_CTX *mem_ctx;
    4940             : 
    4941           0 :         mem_ctx = talloc_new(NULL);
    4942           0 :         if (mem_ctx == NULL) {
    4943           0 :                 DEBUG(0, ("talloc_new failed\n"));
    4944           0 :                 return NT_STATUS_NO_MEMORY;
    4945             :         }
    4946             : 
    4947           0 :         status = smbldap_search_domain_info(smbldap_state, &result,
    4948             :                                             get_global_sam_name(), False);
    4949           0 :         if (!NT_STATUS_IS_OK(status)) {
    4950           0 :                 DEBUG(3, ("Could not get domain info: %s\n",
    4951             :                           nt_errstr(status)));
    4952           0 :                 goto done;
    4953             :         }
    4954             : 
    4955           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    4956             : 
    4957           0 :         entry = ldap_first_entry(priv2ld(priv), result);
    4958           0 :         if (entry == NULL) {
    4959           0 :                 DEBUG(0, ("Could not get domain info entry\n"));
    4960           0 :                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
    4961           0 :                 goto done;
    4962             :         }
    4963             : 
    4964             :         /* Find the largest of the three attributes "sambaNextRid",
    4965             :            "sambaNextGroupRid" and "sambaNextUserRid". I gave up on the
    4966             :            concept of differentiating between user and group rids, and will
    4967             :            use only "sambaNextRid" in the future. But for compatibility
    4968             :            reasons I look if others have chosen different strategies -- VL */
    4969             : 
    4970           0 :         value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    4971             :                                                 "sambaNextRid",       mem_ctx);
    4972           0 :         if (value != NULL) {
    4973           0 :                 tmp = (uint32_t)smb_strtoul(value,
    4974             :                                             NULL,
    4975             :                                             10,
    4976             :                                             &error,
    4977             :                                             SMB_STR_STANDARD);
    4978           0 :                 if (error != 0) {
    4979           0 :                         goto done;
    4980             :                 }
    4981             : 
    4982           0 :                 nextRid = MAX(nextRid, tmp);
    4983             :         }
    4984             : 
    4985           0 :         value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    4986             :                                                 "sambaNextUserRid", mem_ctx);
    4987           0 :         if (value != NULL) {
    4988           0 :                 tmp = (uint32_t)smb_strtoul(value,
    4989             :                                             NULL,
    4990             :                                             10,
    4991             :                                             &error,
    4992             :                                             SMB_STR_STANDARD);
    4993           0 :                 if (error != 0) {
    4994           0 :                         goto done;
    4995             :                 }
    4996             : 
    4997           0 :                 nextRid = MAX(nextRid, tmp);
    4998             :         }
    4999             : 
    5000           0 :         value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    5001             :                                                 "sambaNextGroupRid", mem_ctx);
    5002           0 :         if (value != NULL) {
    5003           0 :                 tmp = (uint32_t)smb_strtoul(value,
    5004             :                                             NULL,
    5005             :                                             10,
    5006             :                                             &error,
    5007             :                                             SMB_STR_STANDARD);
    5008           0 :                 if (error != 0) {
    5009           0 :                         goto done;
    5010             :                 }
    5011             : 
    5012           0 :                 nextRid = MAX(nextRid, tmp);
    5013             :         }
    5014             : 
    5015           0 :         if (nextRid == 0) {
    5016           0 :                 nextRid = BASE_RID-1;
    5017             :         }
    5018             : 
    5019           0 :         nextRid += 1;
    5020             : 
    5021           0 :         smbldap_make_mod(priv2ld(priv), entry, &mods, "sambaNextRid",
    5022           0 :                          talloc_asprintf(mem_ctx, "%d", nextRid));
    5023           0 :         smbldap_talloc_autofree_ldapmod(mem_ctx, mods);
    5024             : 
    5025           0 :         if ((dn = smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)) == NULL) {
    5026           0 :                 status = NT_STATUS_NO_MEMORY;
    5027           0 :                 goto done;
    5028             :         }
    5029             : 
    5030           0 :         rc = smbldap_modify(smbldap_state, dn, mods);
    5031             : 
    5032             :         /* ACCESS_DENIED is used as a placeholder for "the modify failed,
    5033             :          * please retry" */
    5034             : 
    5035           0 :         status = (rc == LDAP_SUCCESS) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
    5036             : 
    5037           0 :  done:
    5038           0 :         if (NT_STATUS_IS_OK(status)) {
    5039           0 :                 *rid = nextRid;
    5040             :         }
    5041             : 
    5042           0 :         TALLOC_FREE(mem_ctx);
    5043           0 :         return status;
    5044             : }
    5045             : 
    5046           0 : static NTSTATUS ldapsam_new_rid_internal(struct pdb_methods *methods, uint32_t *rid)
    5047             : {
    5048           0 :         int i;
    5049             : 
    5050           0 :         for (i=0; i<10; i++) {
    5051           0 :                 NTSTATUS result = ldapsam_get_new_rid(
    5052           0 :                         (struct ldapsam_privates *)methods->private_data, rid);
    5053           0 :                 if (NT_STATUS_IS_OK(result)) {
    5054           0 :                         return result;
    5055             :                 }
    5056             : 
    5057           0 :                 if (!NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
    5058           0 :                         return result;
    5059             :                 }
    5060             : 
    5061             :                 /* The ldap update failed (maybe a race condition), retry */
    5062             :         }
    5063             : 
    5064             :         /* Tried 10 times, fail. */
    5065           0 :         return NT_STATUS_ACCESS_DENIED;
    5066             : }
    5067             : 
    5068           0 : static bool ldapsam_new_rid(struct pdb_methods *methods, uint32_t *rid)
    5069             : {
    5070           0 :         NTSTATUS result = ldapsam_new_rid_internal(methods, rid);
    5071           0 :         return NT_STATUS_IS_OK(result) ? True : False;
    5072             : }
    5073             : 
    5074           0 : static bool ldapsam_sid_to_id(struct pdb_methods *methods,
    5075             :                               const struct dom_sid *sid,
    5076             :                               struct unixid *id)
    5077             : {
    5078           0 :         struct ldapsam_privates *priv =
    5079             :                 (struct ldapsam_privates *)methods->private_data;
    5080           0 :         char *filter;
    5081           0 :         int error = 0;
    5082           0 :         struct dom_sid_buf buf;
    5083           0 :         const char *attrs[] = { "sambaGroupType", "gidNumber", "uidNumber",
    5084             :                                 NULL };
    5085           0 :         LDAPMessage *result = NULL;
    5086           0 :         LDAPMessage *entry = NULL;
    5087           0 :         bool ret = False;
    5088           0 :         char *value;
    5089           0 :         int rc;
    5090             : 
    5091           0 :         TALLOC_CTX *mem_ctx;
    5092             : 
    5093           0 :         ret = pdb_sid_to_id_unix_users_and_groups(sid, id);
    5094           0 :         if (ret == true) {
    5095           0 :                 return true;
    5096             :         }
    5097             : 
    5098           0 :         mem_ctx = talloc_new(NULL);
    5099           0 :         if (mem_ctx == NULL) {
    5100           0 :                 DEBUG(0, ("talloc_new failed\n"));
    5101           0 :                 return False;
    5102             :         }
    5103             : 
    5104           0 :         filter = talloc_asprintf(mem_ctx,
    5105             :                                  "(&(sambaSid=%s)"
    5106             :                                  "(|(objectClass="LDAP_OBJ_GROUPMAP")(objectClass="LDAP_OBJ_SAMBASAMACCOUNT")))",
    5107             :                                  dom_sid_str_buf(sid, &buf));
    5108           0 :         if (filter == NULL) {
    5109           0 :                 DEBUG(5, ("talloc_asprintf failed\n"));
    5110           0 :                 goto done;
    5111             :         }
    5112             : 
    5113           0 :         rc = smbldap_search_suffix(priv->smbldap_state, filter,
    5114             :                                    attrs, &result);
    5115           0 :         if (rc != LDAP_SUCCESS) {
    5116           0 :                 goto done;
    5117             :         }
    5118           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    5119             : 
    5120           0 :         if (ldap_count_entries(priv2ld(priv), result) != 1) {
    5121           0 :                 DEBUG(10, ("Got %d entries, expected one\n",
    5122             :                            ldap_count_entries(priv2ld(priv), result)));
    5123           0 :                 goto done;
    5124             :         }
    5125             : 
    5126           0 :         entry = ldap_first_entry(priv2ld(priv), result);
    5127             : 
    5128           0 :         value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    5129             :                                                 "sambaGroupType", mem_ctx);
    5130             : 
    5131           0 :         if (value != NULL) {
    5132           0 :                 const char *gid_str;
    5133             :                 /* It's a group */
    5134             : 
    5135           0 :                 gid_str = smbldap_talloc_single_attribute(
    5136             :                         priv2ld(priv), entry, "gidNumber", mem_ctx);
    5137           0 :                 if (gid_str == NULL) {
    5138           0 :                         DEBUG(1, ("%s has sambaGroupType but no gidNumber\n",
    5139             :                                   smbldap_talloc_dn(mem_ctx, priv2ld(priv),
    5140             :                                                     entry)));
    5141           0 :                         goto done;
    5142             :                 }
    5143             : 
    5144           0 :                 id->id = smb_strtoul(gid_str,
    5145             :                                      NULL,
    5146             :                                      10,
    5147             :                                      &error,
    5148             :                                      SMB_STR_STANDARD);
    5149           0 :                 if (error != 0) {
    5150           0 :                         goto done;
    5151             :                 }
    5152             : 
    5153           0 :                 id->type = ID_TYPE_GID;
    5154           0 :                 ret = True;
    5155           0 :                 goto done;
    5156             :         }
    5157             : 
    5158             :         /* It must be a user */
    5159             : 
    5160           0 :         value = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    5161             :                                                 "uidNumber", mem_ctx);
    5162           0 :         if (value == NULL) {
    5163           0 :                 DEBUG(1, ("Could not find uidNumber in %s\n",
    5164             :                           smbldap_talloc_dn(mem_ctx, priv2ld(priv), entry)));
    5165           0 :                 goto done;
    5166             :         }
    5167             : 
    5168           0 :         id->id = smb_strtoul(value, NULL, 10, &error, SMB_STR_STANDARD);
    5169           0 :         if (error != 0) {
    5170           0 :                 goto done;
    5171             :         }
    5172             : 
    5173           0 :         id->type = ID_TYPE_UID;
    5174           0 :         ret = True;
    5175           0 :  done:
    5176           0 :         TALLOC_FREE(mem_ctx);
    5177           0 :         return ret;
    5178             : }
    5179             : 
    5180             : /**
    5181             :  * Find the SID for a uid.
    5182             :  * This is shortcut is only used if ldapsam:trusted is set to true.
    5183             :  */
    5184           0 : static bool ldapsam_uid_to_sid(struct pdb_methods *methods, uid_t uid,
    5185             :                                struct dom_sid *sid)
    5186             : {
    5187           0 :         struct ldapsam_privates *priv =
    5188             :                 (struct ldapsam_privates *)methods->private_data;
    5189           0 :         char *filter;
    5190           0 :         const char *attrs[] = { "sambaSID", NULL };
    5191           0 :         LDAPMessage *result = NULL;
    5192           0 :         LDAPMessage *entry = NULL;
    5193           0 :         bool ret = false;
    5194           0 :         char *user_sid_string;
    5195           0 :         struct dom_sid user_sid;
    5196           0 :         int rc;
    5197           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    5198             : 
    5199           0 :         filter = talloc_asprintf(tmp_ctx,
    5200             :                                  "(&(uidNumber=%u)"
    5201             :                                  "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
    5202             :                                  "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
    5203             :                                  (unsigned int)uid);
    5204           0 :         if (filter == NULL) {
    5205           0 :                 DEBUG(3, ("talloc_asprintf failed\n"));
    5206           0 :                 goto done;
    5207             :         }
    5208             : 
    5209           0 :         rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
    5210           0 :         if (rc != LDAP_SUCCESS) {
    5211           0 :                 goto done;
    5212             :         }
    5213           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5214             : 
    5215           0 :         if (ldap_count_entries(priv2ld(priv), result) != 1) {
    5216           0 :                 DEBUG(3, ("ERROR: Got %d entries for uid %u, expected one\n",
    5217             :                            ldap_count_entries(priv2ld(priv), result),
    5218             :                            (unsigned int)uid));
    5219           0 :                 goto done;
    5220             :         }
    5221             : 
    5222           0 :         entry = ldap_first_entry(priv2ld(priv), result);
    5223             : 
    5224           0 :         user_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    5225             :                                                           "sambaSID", tmp_ctx);
    5226           0 :         if (user_sid_string == NULL) {
    5227           0 :                 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
    5228             :                           smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
    5229           0 :                 goto done;
    5230             :         }
    5231             : 
    5232           0 :         if (!string_to_sid(&user_sid, user_sid_string)) {
    5233           0 :                 DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
    5234             :                           user_sid_string));
    5235           0 :                 goto done;
    5236             :         }
    5237             : 
    5238           0 :         sid_copy(sid, &user_sid);
    5239             : 
    5240           0 :         ret = true;
    5241             : 
    5242           0 :  done:
    5243           0 :         TALLOC_FREE(tmp_ctx);
    5244           0 :         return ret;
    5245             : }
    5246             : 
    5247             : /**
    5248             :  * Find the SID for a gid.
    5249             :  * This is shortcut is only used if ldapsam:trusted is set to true.
    5250             :  */
    5251           0 : static bool ldapsam_gid_to_sid(struct pdb_methods *methods, gid_t gid,
    5252             :                                struct dom_sid *sid)
    5253             : {
    5254           0 :         struct ldapsam_privates *priv =
    5255             :                 (struct ldapsam_privates *)methods->private_data;
    5256           0 :         char *filter;
    5257           0 :         const char *attrs[] = { "sambaSID", NULL };
    5258           0 :         LDAPMessage *result = NULL;
    5259           0 :         LDAPMessage *entry = NULL;
    5260           0 :         bool ret = false;
    5261           0 :         char *group_sid_string;
    5262           0 :         struct dom_sid group_sid;
    5263           0 :         int rc;
    5264           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    5265             : 
    5266           0 :         filter = talloc_asprintf(tmp_ctx,
    5267             :                                  "(&(gidNumber=%u)"
    5268             :                                  "(objectClass="LDAP_OBJ_GROUPMAP"))",
    5269             :                                  (unsigned int)gid);
    5270           0 :         if (filter == NULL) {
    5271           0 :                 DEBUG(3, ("talloc_asprintf failed\n"));
    5272           0 :                 goto done;
    5273             :         }
    5274             : 
    5275           0 :         rc = smbldap_search_suffix(priv->smbldap_state, filter, attrs, &result);
    5276           0 :         if (rc != LDAP_SUCCESS) {
    5277           0 :                 goto done;
    5278             :         }
    5279           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5280             : 
    5281           0 :         if (ldap_count_entries(priv2ld(priv), result) != 1) {
    5282           0 :                 DEBUG(3, ("ERROR: Got %d entries for gid %u, expected one\n",
    5283             :                            ldap_count_entries(priv2ld(priv), result),
    5284             :                            (unsigned int)gid));
    5285           0 :                 goto done;
    5286             :         }
    5287             : 
    5288           0 :         entry = ldap_first_entry(priv2ld(priv), result);
    5289             : 
    5290           0 :         group_sid_string = smbldap_talloc_single_attribute(priv2ld(priv), entry,
    5291             :                                                           "sambaSID", tmp_ctx);
    5292           0 :         if (group_sid_string == NULL) {
    5293           0 :                 DEBUG(1, ("Could not find sambaSID in object '%s'\n",
    5294             :                           smbldap_talloc_dn(tmp_ctx, priv2ld(priv), entry)));
    5295           0 :                 goto done;
    5296             :         }
    5297             : 
    5298           0 :         if (!string_to_sid(&group_sid, group_sid_string)) {
    5299           0 :                 DEBUG(3, ("Error calling string_to_sid for sid '%s'\n",
    5300             :                           group_sid_string));
    5301           0 :                 goto done;
    5302             :         }
    5303             : 
    5304           0 :         sid_copy(sid, &group_sid);
    5305             : 
    5306           0 :         ret = true;
    5307             : 
    5308           0 :  done:
    5309           0 :         TALLOC_FREE(tmp_ctx);
    5310           0 :         return ret;
    5311             : }
    5312             : 
    5313           0 : static bool ldapsam_id_to_sid(struct pdb_methods *methods, struct unixid *id,
    5314             :                                    struct dom_sid *sid)
    5315             : {
    5316           0 :         switch (id->type) {
    5317           0 :         case ID_TYPE_UID:
    5318           0 :                 return ldapsam_uid_to_sid(methods, id->id, sid);
    5319             : 
    5320           0 :         case ID_TYPE_GID:
    5321           0 :                 return ldapsam_gid_to_sid(methods, id->id, sid);
    5322             : 
    5323           0 :         default:
    5324           0 :                 return false;
    5325             :         }
    5326             : }
    5327             : 
    5328             : 
    5329             : /*
    5330             :  * The following functions are called only if
    5331             :  * ldapsam:trusted and ldapsam:editposix are
    5332             :  * set to true
    5333             :  */
    5334             : 
    5335             : /*
    5336             :  * ldapsam_create_user creates a new
    5337             :  * posixAccount and sambaSamAccount object
    5338             :  * in the ldap users subtree
    5339             :  *
    5340             :  * The uid is allocated by winbindd.
    5341             :  */
    5342             : 
    5343           0 : static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
    5344             :                                     TALLOC_CTX *tmp_ctx, const char *name,
    5345             :                                     uint32_t acb_info, uint32_t *rid)
    5346             : {
    5347           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    5348           0 :         LDAPMessage *entry = NULL;
    5349           0 :         LDAPMessage *result = NULL;
    5350           0 :         uint32_t num_result;
    5351           0 :         bool is_machine = False;
    5352           0 :         bool add_posix = False;
    5353           0 :         bool init_okay = False;
    5354           0 :         LDAPMod **mods = NULL;
    5355           0 :         struct samu *user;
    5356           0 :         char *filter;
    5357           0 :         char *username;
    5358           0 :         char *homedir;
    5359           0 :         char *gidstr;
    5360           0 :         char *uidstr;
    5361           0 :         char *shell;
    5362           0 :         const char *dn = NULL;
    5363           0 :         struct dom_sid group_sid;
    5364           0 :         struct dom_sid user_sid;
    5365           0 :         gid_t gid = -1;
    5366           0 :         uid_t uid = -1;
    5367           0 :         NTSTATUS ret;
    5368           0 :         int rc;
    5369             : 
    5370           0 :         if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
    5371           0 :               acb_info & ACB_WSTRUST ||
    5372           0 :               acb_info & ACB_SVRTRUST ||
    5373           0 :               acb_info & ACB_DOMTRUST) {
    5374           0 :                 is_machine = True;
    5375             :         }
    5376             : 
    5377           0 :         username = escape_ldap_string(talloc_tos(), name);
    5378           0 :         filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass="LDAP_OBJ_POSIXACCOUNT"))",
    5379             :                                  username);
    5380           0 :         TALLOC_FREE(username);
    5381             : 
    5382           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5383           0 :         if (rc != LDAP_SUCCESS) {
    5384           0 :                 DEBUG(0,("ldapsam_create_user: ldap search failed!\n"));
    5385           0 :                 return NT_STATUS_ACCESS_DENIED;
    5386             :         }
    5387           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5388             : 
    5389           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5390             : 
    5391           0 :         if (num_result > 1) {
    5392           0 :                 DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
    5393           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5394             :         }
    5395             : 
    5396           0 :         if (num_result == 1) {
    5397           0 :                 char *tmp;
    5398             :                 /* check if it is just a posix account.
    5399             :                  * or if there is a sid attached to this entry
    5400             :                  */
    5401             : 
    5402           0 :                 entry = ldap_first_entry(priv2ld(ldap_state), result);
    5403           0 :                 if (!entry) {
    5404           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5405             :                 }
    5406             : 
    5407           0 :                 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
    5408           0 :                 if (tmp) {
    5409           0 :                         DEBUG (1, ("ldapsam_create_user: The user [%s] already exist!\n", name));
    5410           0 :                         return NT_STATUS_USER_EXISTS;
    5411             :                 }
    5412             : 
    5413             :                 /* it is just a posix account, retrieve the dn for later use */
    5414           0 :                 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
    5415           0 :                 if (!dn) {
    5416           0 :                         DEBUG(0,("ldapsam_create_user: Out of memory!\n"));
    5417           0 :                         return NT_STATUS_NO_MEMORY;
    5418             :                 }
    5419             :         }
    5420             : 
    5421           0 :         if (num_result == 0) {
    5422           0 :                 add_posix = True;
    5423             :         }
    5424             : 
    5425             :         /* Create the basic samu structure and generate the mods for the ldap commit */
    5426           0 :         if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
    5427           0 :                 DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
    5428           0 :                 return ret;
    5429             :         }
    5430             : 
    5431           0 :         sid_compose(&user_sid, get_global_sam_sid(), *rid);
    5432             : 
    5433           0 :         user = samu_new(tmp_ctx);
    5434           0 :         if (!user) {
    5435           0 :                 DEBUG(1,("ldapsam_create_user: Unable to allocate user struct\n"));
    5436           0 :                 return NT_STATUS_NO_MEMORY;
    5437             :         }
    5438             : 
    5439           0 :         if (!pdb_set_username(user, name, PDB_SET)) {
    5440           0 :                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5441           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5442             :         }
    5443           0 :         if (!pdb_set_domain(user, get_global_sam_name(), PDB_SET)) {
    5444           0 :                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5445           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5446             :         }
    5447           0 :         if (is_machine) {
    5448           0 :                 if (acb_info & ACB_NORMAL) {
    5449           0 :                         if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) {
    5450           0 :                                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5451           0 :                                 return NT_STATUS_UNSUCCESSFUL;
    5452             :                         }
    5453             :                 } else {
    5454           0 :                         if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) {
    5455           0 :                                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5456           0 :                                 return NT_STATUS_UNSUCCESSFUL;
    5457             :                         }
    5458             :                 }
    5459             :         } else {
    5460           0 :                 if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) {
    5461           0 :                         DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5462           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5463             :                 }
    5464             :         }
    5465             : 
    5466           0 :         if (!pdb_set_user_sid(user, &user_sid, PDB_SET)) {
    5467           0 :                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5468           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5469             :         }
    5470             : 
    5471           0 :         init_okay = init_ldap_from_sam(ldap_state, entry, &mods, user, pdb_element_is_set_or_changed);
    5472             : 
    5473           0 :         if (!init_okay) {
    5474           0 :                 DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n"));
    5475           0 :                 ldap_mods_free(mods, true);
    5476           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5477             :         }
    5478             : 
    5479           0 :         if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) {
    5480           0 :                 DEBUG(1,("ldapsam_create_user: Unsupported schema version\n"));
    5481             :         }
    5482           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
    5483             : 
    5484           0 :         if (add_posix) {
    5485           0 :                 char *escape_name;
    5486             : 
    5487           0 :                 DEBUG(3,("ldapsam_create_user: Creating new posix user\n"));
    5488             : 
    5489             :                 /* retrieve the Domain Users group gid */
    5490           0 :                 if (!sid_compose(&group_sid, get_global_sam_sid(), DOMAIN_RID_USERS) ||
    5491           0 :                     !sid_to_gid(&group_sid, &gid)) {
    5492           0 :                         DEBUG (0, ("ldapsam_create_user: Unable to get the Domain Users gid: bailing out!\n"));
    5493           0 :                         ldap_mods_free(mods, true);
    5494           0 :                         return NT_STATUS_INVALID_PRIMARY_GROUP;
    5495             :                 }
    5496             : 
    5497             :                 /* lets allocate a new userid for this user */
    5498           0 :                 if (!winbind_allocate_uid(&uid)) {
    5499           0 :                         DEBUG (0, ("ldapsam_create_user: Unable to allocate a new user id: bailing out!\n"));
    5500           0 :                         ldap_mods_free(mods, true);
    5501           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5502             :                 }
    5503             : 
    5504             : 
    5505           0 :                 if (is_machine) {
    5506             :                         /* TODO: choose a more appropriate default for machines */
    5507           0 :                         homedir = talloc_sub_specified(tmp_ctx,
    5508             :                                                        lp_template_homedir(),
    5509             :                                                        "SMB_workstations_home",
    5510             :                                                        NULL,
    5511             :                                                        ldap_state->domain_name,
    5512             :                                                        uid,
    5513             :                                                        gid);
    5514           0 :                         shell = talloc_strdup(tmp_ctx, "/bin/false");
    5515             :                 } else {
    5516           0 :                         homedir = talloc_sub_specified(tmp_ctx,
    5517             :                                                        lp_template_homedir(),
    5518             :                                                        name,
    5519             :                                                        NULL,
    5520             :                                                        ldap_state->domain_name,
    5521             :                                                        uid,
    5522             :                                                        gid);
    5523           0 :                         shell = talloc_sub_specified(tmp_ctx,
    5524             :                                                      lp_template_shell(),
    5525             :                                                      name,
    5526             :                                                      NULL,
    5527             :                                                      ldap_state->domain_name,
    5528             :                                                      uid,
    5529             :                                                      gid);
    5530             :                 }
    5531           0 :                 uidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)uid);
    5532           0 :                 gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
    5533             : 
    5534           0 :                 escape_name = escape_rdn_val_string_alloc(name);
    5535           0 :                 if (!escape_name) {
    5536           0 :                         DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
    5537           0 :                         ldap_mods_free(mods, true);
    5538           0 :                         return NT_STATUS_NO_MEMORY;
    5539             :                 }
    5540             : 
    5541           0 :                 if (is_machine) {
    5542           0 :                         dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_machine_suffix (talloc_tos()));
    5543             :                 } else {
    5544           0 :                         dn = talloc_asprintf(tmp_ctx, "uid=%s,%s", escape_name, lp_ldap_user_suffix (talloc_tos()));
    5545             :                 }
    5546             : 
    5547           0 :                 SAFE_FREE(escape_name);
    5548             : 
    5549           0 :                 if (!homedir || !shell || !uidstr || !gidstr || !dn) {
    5550           0 :                         DEBUG (0, ("ldapsam_create_user: Out of memory!\n"));
    5551           0 :                         ldap_mods_free(mods, true);
    5552           0 :                         return NT_STATUS_NO_MEMORY;
    5553             :                 }
    5554             : 
    5555           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
    5556           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
    5557           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
    5558           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
    5559           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
    5560           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", homedir);
    5561           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
    5562             :         }
    5563             : 
    5564           0 :         if (add_posix) {
    5565           0 :                 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
    5566             :         } else {
    5567           0 :                 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    5568             :         }
    5569             : 
    5570           0 :         ldap_mods_free(mods, true);
    5571             : 
    5572           0 :         if (rc != LDAP_SUCCESS) {
    5573           0 :                 DEBUG(0,("ldapsam_create_user: failed to create a new user [%s] (dn = %s)\n", name ,dn));
    5574           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5575             :         }
    5576             : 
    5577           0 :         DEBUG(2,("ldapsam_create_user: added account [%s] in the LDAP database\n", name));
    5578             : 
    5579           0 :         flush_pwnam_cache();
    5580             : 
    5581           0 :         return NT_STATUS_OK;
    5582             : }
    5583             : 
    5584           0 : static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, struct samu *sam_acct)
    5585             : {
    5586           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    5587           0 :         LDAPMessage *result = NULL;
    5588           0 :         LDAPMessage *entry = NULL;
    5589           0 :         int num_result;
    5590           0 :         const char *dn;
    5591           0 :         char *filter;
    5592           0 :         int rc;
    5593             : 
    5594           0 :         DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
    5595             : 
    5596           0 :         filter = talloc_asprintf(tmp_ctx,
    5597             :                                  "(&(uid=%s)"
    5598             :                                  "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
    5599             :                                  "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
    5600             :                                  pdb_get_username(sam_acct));
    5601           0 :         if (filter == NULL) {
    5602           0 :                 return NT_STATUS_NO_MEMORY;
    5603             :         }
    5604             : 
    5605           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5606           0 :         if (rc != LDAP_SUCCESS) {
    5607           0 :                 DEBUG(0,("ldapsam_delete_user: user search failed!\n"));
    5608           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5609             :         }
    5610           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5611             : 
    5612           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5613             : 
    5614           0 :         if (num_result == 0) {
    5615           0 :                 DEBUG(0,("ldapsam_delete_user: user not found!\n"));
    5616           0 :                 return NT_STATUS_NO_SUCH_USER;
    5617             :         }
    5618             : 
    5619           0 :         if (num_result > 1) {
    5620           0 :                 DEBUG (0, ("ldapsam_delete_user: More than one user with name [%s] ?!\n", pdb_get_username(sam_acct)));
    5621           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5622             :         }
    5623             : 
    5624           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    5625           0 :         if (!entry) {
    5626           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5627             :         }
    5628             : 
    5629             :         /* it is just a posix account, retrieve the dn for later use */
    5630           0 :         dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
    5631           0 :         if (!dn) {
    5632           0 :                 DEBUG(0,("ldapsam_delete_user: Out of memory!\n"));
    5633           0 :                 return NT_STATUS_NO_MEMORY;
    5634             :         }
    5635             : 
    5636             :         /* try to remove memberships first */
    5637             :         {
    5638           0 :                 NTSTATUS status;
    5639           0 :                 struct dom_sid *sids = NULL;
    5640           0 :                 gid_t *gids = NULL;
    5641           0 :                 uint32_t num_groups = 0;
    5642           0 :                 int i;
    5643           0 :                 uint32_t user_rid = pdb_get_user_rid(sam_acct);
    5644             : 
    5645           0 :                 status = ldapsam_enum_group_memberships(my_methods,
    5646             :                                                         tmp_ctx,
    5647             :                                                         sam_acct,
    5648             :                                                         &sids,
    5649             :                                                         &gids,
    5650             :                                                         &num_groups);
    5651           0 :                 if (!NT_STATUS_IS_OK(status)) {
    5652           0 :                         goto delete_dn;
    5653             :                 }
    5654             : 
    5655           0 :                 for (i=0; i < num_groups; i++) {
    5656             : 
    5657           0 :                         uint32_t group_rid;
    5658             : 
    5659           0 :                         sid_peek_rid(&sids[i], &group_rid);
    5660             : 
    5661           0 :                         ldapsam_del_groupmem(my_methods,
    5662             :                                              tmp_ctx,
    5663             :                                              group_rid,
    5664             :                                              user_rid);
    5665             :                 }
    5666             :         }
    5667             : 
    5668           0 :  delete_dn:
    5669             : 
    5670           0 :         rc = smbldap_delete(ldap_state->smbldap_state, dn);
    5671           0 :         if (rc != LDAP_SUCCESS) {
    5672           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5673             :         }
    5674             : 
    5675           0 :         flush_pwnam_cache();
    5676             : 
    5677           0 :         return NT_STATUS_OK;
    5678             : }
    5679             : 
    5680             : /*
    5681             :  * ldapsam_create_group creates a new
    5682             :  * posixGroup and sambaGroupMapping object
    5683             :  * in the ldap groups subtree
    5684             :  *
    5685             :  * The gid is allocated by winbindd.
    5686             :  */
    5687             : 
    5688           0 : static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
    5689             :                                          TALLOC_CTX *tmp_ctx,
    5690             :                                          const char *name,
    5691             :                                          uint32_t *rid)
    5692             : {
    5693           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    5694           0 :         NTSTATUS ret;
    5695           0 :         LDAPMessage *entry = NULL;
    5696           0 :         LDAPMessage *result = NULL;
    5697           0 :         uint32_t num_result;
    5698           0 :         bool is_new_entry = False;
    5699           0 :         LDAPMod **mods = NULL;
    5700           0 :         char *filter;
    5701           0 :         char *groupname;
    5702           0 :         const char *grouptype;
    5703           0 :         char *gidstr;
    5704           0 :         const char *dn = NULL;
    5705           0 :         struct dom_sid group_sid;
    5706           0 :         struct dom_sid_buf buf;
    5707           0 :         gid_t gid = -1;
    5708           0 :         int rc;
    5709           0 :         int error = 0;
    5710             : 
    5711           0 :         groupname = escape_ldap_string(talloc_tos(), name);
    5712           0 :         filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass="LDAP_OBJ_POSIXGROUP"))",
    5713             :                                  groupname);
    5714           0 :         TALLOC_FREE(groupname);
    5715             : 
    5716           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5717           0 :         if (rc != LDAP_SUCCESS) {
    5718           0 :                 DEBUG(0,("ldapsam_create_group: ldap search failed!\n"));
    5719           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5720             :         }
    5721           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5722             : 
    5723           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5724             : 
    5725           0 :         if (num_result > 1) {
    5726           0 :                 DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
    5727           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5728             :         }
    5729             : 
    5730           0 :         if (num_result == 1) {
    5731           0 :                 char *tmp;
    5732             :                 /* check if it is just a posix group.
    5733             :                  * or if there is a sid attached to this entry
    5734             :                  */
    5735             : 
    5736           0 :                 entry = ldap_first_entry(priv2ld(ldap_state), result);
    5737           0 :                 if (!entry) {
    5738           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5739             :                 }
    5740             : 
    5741           0 :                 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "sambaSID", tmp_ctx);
    5742           0 :                 if (tmp) {
    5743           0 :                         DEBUG (1, ("ldapsam_create_group: The group [%s] already exist!\n", name));
    5744           0 :                         return NT_STATUS_GROUP_EXISTS;
    5745             :                 }
    5746             : 
    5747             :                 /* it is just a posix group, retrieve the gid and the dn for later use */
    5748           0 :                 tmp = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
    5749           0 :                 if (!tmp) {
    5750           0 :                         DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
    5751           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5752             :                 }
    5753             : 
    5754           0 :                 gid = smb_strtoul(tmp, NULL, 10, &error, SMB_STR_STANDARD);
    5755           0 :                 if (error != 0) {
    5756           0 :                         DBG_ERR("Failed to convert gidNumber\n");
    5757           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5758             :                 }
    5759             : 
    5760           0 :                 dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
    5761           0 :                 if (!dn) {
    5762           0 :                         DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
    5763           0 :                         return NT_STATUS_NO_MEMORY;
    5764             :                 }
    5765             :         }
    5766             : 
    5767           0 :         if (num_result == 0) {
    5768           0 :                 is_new_entry = true;
    5769             :         }
    5770             : 
    5771           0 :         if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
    5772           0 :                 DEBUG(1, ("ldapsam_create_group: Could not allocate a new RID\n"));
    5773           0 :                 return ret;
    5774             :         }
    5775             : 
    5776           0 :         sid_compose(&group_sid, get_global_sam_sid(), *rid);
    5777             : 
    5778           0 :         grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP);
    5779             : 
    5780           0 :         if (!grouptype) {
    5781           0 :                 DEBUG(0,("ldapsam_create_group: Out of memory!\n"));
    5782           0 :                 return NT_STATUS_NO_MEMORY;
    5783             :         }
    5784             : 
    5785           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
    5786           0 :         smbldap_set_mod(&mods,
    5787             :                         LDAP_MOD_ADD,
    5788             :                         "sambaSid",
    5789           0 :                         dom_sid_str_buf(&group_sid, &buf));
    5790           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype);
    5791           0 :         smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
    5792             : 
    5793           0 :         if (is_new_entry) {
    5794           0 :                 char *escape_name;
    5795             : 
    5796           0 :                 DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
    5797             : 
    5798             :                 /* lets allocate a new groupid for this group */
    5799           0 :                 if (!winbind_allocate_gid(&gid)) {
    5800           0 :                         DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
    5801           0 :                         return NT_STATUS_UNSUCCESSFUL;
    5802             :                 }
    5803             : 
    5804           0 :                 gidstr = talloc_asprintf(tmp_ctx, "%u", (unsigned int)gid);
    5805             : 
    5806           0 :                 escape_name = escape_rdn_val_string_alloc(name);
    5807           0 :                 if (!escape_name) {
    5808           0 :                         DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
    5809           0 :                         return NT_STATUS_NO_MEMORY;
    5810             :                 }
    5811             : 
    5812           0 :                 dn = talloc_asprintf(tmp_ctx, "cn=%s,%s", escape_name, lp_ldap_group_suffix(talloc_tos()));
    5813             : 
    5814           0 :                 SAFE_FREE(escape_name);
    5815             : 
    5816           0 :                 if (!gidstr || !dn) {
    5817           0 :                         DEBUG (0, ("ldapsam_create_group: Out of memory!\n"));
    5818           0 :                         return NT_STATUS_NO_MEMORY;
    5819             :                 }
    5820             : 
    5821           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
    5822           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
    5823           0 :                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
    5824             :         }
    5825             : 
    5826           0 :         smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
    5827             : 
    5828           0 :         if (is_new_entry) {
    5829           0 :                 rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
    5830             : #if 0
    5831             :                 if (rc == LDAP_OBJECT_CLASS_VIOLATION) {
    5832             :                         /* This call may fail with rfc2307bis schema */
    5833             :                         /* Retry adding a structural class */
    5834             :                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "????");
    5835             :                         rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
    5836             :                 }
    5837             : #endif
    5838             :         } else {
    5839           0 :                 rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    5840             :         }
    5841             : 
    5842           0 :         if (rc != LDAP_SUCCESS) {
    5843           0 :                 DEBUG(0,("ldapsam_create_group: failed to create a new group [%s] (dn = %s)\n", name ,dn));
    5844           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5845             :         }
    5846             : 
    5847           0 :         DEBUG(2,("ldapsam_create_group: added group [%s] in the LDAP database\n", name));
    5848             : 
    5849           0 :         return NT_STATUS_OK;
    5850             : }
    5851             : 
    5852           0 : static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_CTX *tmp_ctx, uint32_t rid)
    5853             : {
    5854           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    5855           0 :         LDAPMessage *result = NULL;
    5856           0 :         LDAPMessage *entry = NULL;
    5857           0 :         int num_result;
    5858           0 :         const char *dn;
    5859           0 :         char *gidstr;
    5860           0 :         char *filter;
    5861           0 :         struct dom_sid group_sid;
    5862           0 :         struct dom_sid_buf buf;
    5863           0 :         int rc;
    5864             : 
    5865             :         /* get the group sid */
    5866           0 :         sid_compose(&group_sid, get_global_sam_sid(), rid);
    5867             : 
    5868           0 :         filter = talloc_asprintf(tmp_ctx,
    5869             :                                  "(&(sambaSID=%s)"
    5870             :                                  "(objectClass="LDAP_OBJ_POSIXGROUP")"
    5871             :                                  "(objectClass="LDAP_OBJ_GROUPMAP"))",
    5872             :                                  dom_sid_str_buf(&group_sid, &buf));
    5873           0 :         if (filter == NULL) {
    5874           0 :                 return NT_STATUS_NO_MEMORY;
    5875             :         }
    5876             : 
    5877           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5878           0 :         if (rc != LDAP_SUCCESS) {
    5879           0 :                 DEBUG(1,("ldapsam_delete_dom_group: group search failed!\n"));
    5880           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5881             :         }
    5882           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5883             : 
    5884           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5885             : 
    5886           0 :         if (num_result == 0) {
    5887           0 :                 DEBUG(1,("ldapsam_delete_dom_group: group not found!\n"));
    5888           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    5889             :         }
    5890             : 
    5891           0 :         if (num_result > 1) {
    5892           0 :                 DEBUG (0, ("ldapsam_delete_dom_group: More than one group with the same SID ?!\n"));
    5893           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5894             :         }
    5895             : 
    5896           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    5897           0 :         if (!entry) {
    5898           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5899             :         }
    5900             : 
    5901             :         /* here it is, retrieve the dn for later use */
    5902           0 :         dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
    5903           0 :         if (!dn) {
    5904           0 :                 DEBUG(0,("ldapsam_delete_dom_group: Out of memory!\n"));
    5905           0 :                 return NT_STATUS_NO_MEMORY;
    5906             :         }
    5907             : 
    5908           0 :         gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
    5909           0 :         if (!gidstr) {
    5910           0 :                 DEBUG (0, ("ldapsam_delete_dom_group: Unable to find the group's gid!\n"));
    5911           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    5912             :         }
    5913             : 
    5914             :         /* check no user have this group marked as primary group */
    5915           0 :         filter = talloc_asprintf(tmp_ctx,
    5916             :                                  "(&(gidNumber=%s)"
    5917             :                                  "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
    5918             :                                  "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
    5919             :                                  gidstr);
    5920             : 
    5921           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5922           0 :         if (rc != LDAP_SUCCESS) {
    5923           0 :                 DEBUG(1,("ldapsam_delete_dom_group: accounts search failed!\n"));
    5924           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5925             :         }
    5926           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5927             : 
    5928           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5929             : 
    5930           0 :         if (num_result != 0) {
    5931           0 :                 DEBUG(3,("ldapsam_delete_dom_group: Can't delete group, it is a primary group for %d users\n", num_result));
    5932           0 :                 return NT_STATUS_MEMBERS_PRIMARY_GROUP;
    5933             :         }
    5934             : 
    5935           0 :         rc = smbldap_delete(ldap_state->smbldap_state, dn);
    5936           0 :         if (rc != LDAP_SUCCESS) {
    5937           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5938             :         }
    5939             : 
    5940           0 :         return NT_STATUS_OK;
    5941             : }
    5942             : 
    5943           0 : static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
    5944             :                                         TALLOC_CTX *tmp_ctx,
    5945             :                                         uint32_t group_rid,
    5946             :                                         uint32_t member_rid,
    5947             :                                         int modop)
    5948             : {
    5949           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    5950           0 :         LDAPMessage *entry = NULL;
    5951           0 :         LDAPMessage *result = NULL;
    5952           0 :         uint32_t num_result;
    5953           0 :         LDAPMod **mods = NULL;
    5954           0 :         char *filter;
    5955           0 :         char *uidstr;
    5956           0 :         const char *dn = NULL;
    5957           0 :         struct dom_sid group_sid;
    5958           0 :         struct dom_sid member_sid;
    5959           0 :         struct dom_sid_buf buf;
    5960           0 :         int rc;
    5961           0 :         int error = 0;
    5962             : 
    5963           0 :         switch (modop) {
    5964           0 :         case LDAP_MOD_ADD:
    5965           0 :                 DEBUG(1,("ldapsam_change_groupmem: add new member(rid=%d) to a domain group(rid=%d)\n", member_rid, group_rid));
    5966           0 :                 break;
    5967           0 :         case LDAP_MOD_DELETE:
    5968           0 :                 DEBUG(1,("ldapsam_change_groupmem: delete member(rid=%d) from a domain group(rid=%d)\n", member_rid, group_rid));
    5969           0 :                 break;
    5970           0 :         default:
    5971           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5972             :         }
    5973             : 
    5974             :         /* get member sid  */
    5975           0 :         sid_compose(&member_sid, get_global_sam_sid(), member_rid);
    5976             : 
    5977             :         /* get the group sid */
    5978           0 :         sid_compose(&group_sid, get_global_sam_sid(), group_rid);
    5979             : 
    5980           0 :         filter = talloc_asprintf(tmp_ctx,
    5981             :                                  "(&(sambaSID=%s)"
    5982             :                                  "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
    5983             :                                  "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
    5984             :                                  dom_sid_str_buf(&member_sid, &buf));
    5985           0 :         if (filter == NULL) {
    5986           0 :                 return NT_STATUS_NO_MEMORY;
    5987             :         }
    5988             : 
    5989             :         /* get the member uid */
    5990           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    5991           0 :         if (rc != LDAP_SUCCESS) {
    5992           0 :                 DEBUG(1,("ldapsam_change_groupmem: member search failed!\n"));
    5993           0 :                 return NT_STATUS_UNSUCCESSFUL;
    5994             :         }
    5995           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    5996             : 
    5997           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    5998             : 
    5999           0 :         if (num_result == 0) {
    6000           0 :                 DEBUG(1,("ldapsam_change_groupmem: member not found!\n"));
    6001           0 :                 return NT_STATUS_NO_SUCH_MEMBER;
    6002             :         }
    6003             : 
    6004           0 :         if (num_result > 1) {
    6005           0 :                 DEBUG (0, ("ldapsam_change_groupmem: More than one account with the same SID ?!\n"));
    6006           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    6007             :         }
    6008             : 
    6009           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    6010           0 :         if (!entry) {
    6011           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6012             :         }
    6013             : 
    6014           0 :         if (modop == LDAP_MOD_DELETE) {
    6015             :                 /* check if we are trying to remove the member from his primary group */
    6016           0 :                 char *gidstr;
    6017           0 :                 gid_t user_gid, group_gid;
    6018             : 
    6019           0 :                 gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
    6020           0 :                 if (!gidstr) {
    6021           0 :                         DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
    6022           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    6023             :                 }
    6024             : 
    6025           0 :                 user_gid = smb_strtoul(gidstr, NULL, 10, &error, SMB_STR_STANDARD);
    6026           0 :                 if (error != 0) {
    6027           0 :                         DBG_ERR("Failed to convert user gid\n");
    6028           0 :                         return NT_STATUS_UNSUCCESSFUL;
    6029             :                 }
    6030             : 
    6031           0 :                 if (!sid_to_gid(&group_sid, &group_gid)) {
    6032           0 :                         DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
    6033           0 :                         return NT_STATUS_UNSUCCESSFUL;
    6034             :                 }
    6035             : 
    6036           0 :                 if (user_gid == group_gid) {
    6037           0 :                         DEBUG (3, ("ldapsam_change_groupmem: can't remove user from its own primary group!\n"));
    6038           0 :                         return NT_STATUS_MEMBERS_PRIMARY_GROUP;
    6039             :                 }
    6040             :         }
    6041             : 
    6042             :         /* here it is, retrieve the uid for later use */
    6043           0 :         uidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "uid", tmp_ctx);
    6044           0 :         if (!uidstr) {
    6045           0 :                 DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's name!\n"));
    6046           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    6047             :         }
    6048             : 
    6049           0 :         filter = talloc_asprintf(tmp_ctx,
    6050             :                                  "(&(sambaSID=%s)"
    6051             :                                  "(objectClass="LDAP_OBJ_POSIXGROUP")"
    6052             :                                  "(objectClass="LDAP_OBJ_GROUPMAP"))",
    6053             :                                  dom_sid_str_buf(&group_sid, &buf));
    6054             : 
    6055             :         /* get the group */
    6056           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    6057           0 :         if (rc != LDAP_SUCCESS) {
    6058           0 :                 DEBUG(1,("ldapsam_change_groupmem: group search failed!\n"));
    6059           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6060             :         }
    6061           0 :         smbldap_talloc_autofree_ldapmsg(tmp_ctx, result);
    6062             : 
    6063           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    6064             : 
    6065           0 :         if (num_result == 0) {
    6066           0 :                 DEBUG(1,("ldapsam_change_groupmem: group not found!\n"));
    6067           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    6068             :         }
    6069             : 
    6070           0 :         if (num_result > 1) {
    6071           0 :                 DEBUG (0, ("ldapsam_change_groupmem: More than one group with the same SID ?!\n"));
    6072           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    6073             :         }
    6074             : 
    6075           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    6076           0 :         if (!entry) {
    6077           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6078             :         }
    6079             : 
    6080             :         /* here it is, retrieve the dn for later use */
    6081           0 :         dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
    6082           0 :         if (!dn) {
    6083           0 :                 DEBUG(0,("ldapsam_change_groupmem: Out of memory!\n"));
    6084           0 :                 return NT_STATUS_NO_MEMORY;
    6085             :         }
    6086             : 
    6087           0 :         smbldap_set_mod(&mods, modop, "memberUid", uidstr);
    6088             : 
    6089           0 :         smbldap_talloc_autofree_ldapmod(tmp_ctx, mods);
    6090             : 
    6091           0 :         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    6092           0 :         if (rc != LDAP_SUCCESS) {
    6093           0 :                 if (rc == LDAP_TYPE_OR_VALUE_EXISTS && modop == LDAP_MOD_ADD) {
    6094           0 :                         DEBUG(1,("ldapsam_change_groupmem: member is already in group, add failed!\n"));
    6095           0 :                         return NT_STATUS_MEMBER_IN_GROUP;
    6096             :                 }
    6097           0 :                 if (rc == LDAP_NO_SUCH_ATTRIBUTE && modop == LDAP_MOD_DELETE) {
    6098           0 :                         DEBUG(1,("ldapsam_change_groupmem: member is not in group, delete failed!\n"));
    6099           0 :                         return NT_STATUS_MEMBER_NOT_IN_GROUP;
    6100             :                 }
    6101           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6102             :         }
    6103             : 
    6104           0 :         return NT_STATUS_OK;
    6105             : }
    6106             : 
    6107           0 : static NTSTATUS ldapsam_add_groupmem(struct pdb_methods *my_methods,
    6108             :                                      TALLOC_CTX *tmp_ctx,
    6109             :                                      uint32_t group_rid,
    6110             :                                      uint32_t member_rid)
    6111             : {
    6112           0 :         return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_ADD);
    6113             : }
    6114           0 : static NTSTATUS ldapsam_del_groupmem(struct pdb_methods *my_methods,
    6115             :                                      TALLOC_CTX *tmp_ctx,
    6116             :                                      uint32_t group_rid,
    6117             :                                      uint32_t member_rid)
    6118             : {
    6119           0 :         return ldapsam_change_groupmem(my_methods, tmp_ctx, group_rid, member_rid, LDAP_MOD_DELETE);
    6120             : }
    6121             : 
    6122           0 : static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
    6123             :                                           TALLOC_CTX *mem_ctx,
    6124             :                                           struct samu *sampass)
    6125             : {
    6126           0 :         struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
    6127           0 :         LDAPMessage *entry = NULL;
    6128           0 :         LDAPMessage *result = NULL;
    6129           0 :         uint32_t num_result;
    6130           0 :         LDAPMod **mods = NULL;
    6131           0 :         char *filter;
    6132           0 :         char *escape_username;
    6133           0 :         char *gidstr;
    6134           0 :         char *dn = NULL;
    6135           0 :         gid_t gid;
    6136           0 :         int rc;
    6137             : 
    6138           0 :         DEBUG(0,("ldapsam_set_primary_group: Attempt to set primary group for user [%s]\n", pdb_get_username(sampass)));
    6139             : 
    6140           0 :         if (!sid_to_gid(pdb_get_group_sid(sampass), &gid)) {
    6141           0 :                 DEBUG(0,("ldapsam_set_primary_group: failed to retrieve gid from user's group SID!\n"));
    6142           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6143             :         }
    6144           0 :         gidstr = talloc_asprintf(mem_ctx, "%u", (unsigned int)gid);
    6145           0 :         if (!gidstr) {
    6146           0 :                 DEBUG(0,("ldapsam_set_primary_group: Out of Memory!\n"));
    6147           0 :                 return NT_STATUS_NO_MEMORY;
    6148             :         }
    6149             : 
    6150           0 :         escape_username = escape_ldap_string(talloc_tos(),
    6151             :                                              pdb_get_username(sampass));
    6152           0 :         if (escape_username== NULL) {
    6153           0 :                 return NT_STATUS_NO_MEMORY;
    6154             :         }
    6155             : 
    6156           0 :         filter = talloc_asprintf(mem_ctx,
    6157             :                                  "(&(uid=%s)"
    6158             :                                  "(objectClass="LDAP_OBJ_POSIXACCOUNT")"
    6159             :                                  "(objectClass="LDAP_OBJ_SAMBASAMACCOUNT"))",
    6160             :                                  escape_username);
    6161             : 
    6162           0 :         TALLOC_FREE(escape_username);
    6163             : 
    6164           0 :         if (filter == NULL) {
    6165           0 :                 return NT_STATUS_NO_MEMORY;
    6166             :         }
    6167             : 
    6168           0 :         rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
    6169           0 :         if (rc != LDAP_SUCCESS) {
    6170           0 :                 DEBUG(0,("ldapsam_set_primary_group: user search failed!\n"));
    6171           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6172             :         }
    6173           0 :         smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    6174             : 
    6175           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    6176             : 
    6177           0 :         if (num_result == 0) {
    6178           0 :                 DEBUG(0,("ldapsam_set_primary_group: user not found!\n"));
    6179           0 :                 return NT_STATUS_NO_SUCH_USER;
    6180             :         }
    6181             : 
    6182           0 :         if (num_result > 1) {
    6183           0 :                 DEBUG (0, ("ldapsam_set_primary_group: More than one user with name [%s] ?!\n", pdb_get_username(sampass)));
    6184           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    6185             :         }
    6186             : 
    6187           0 :         entry = ldap_first_entry(priv2ld(ldap_state), result);
    6188           0 :         if (!entry) {
    6189           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6190             :         }
    6191             : 
    6192             :         /* retrieve the dn for later use */
    6193           0 :         dn = smbldap_talloc_dn(mem_ctx, priv2ld(ldap_state), entry);
    6194           0 :         if (!dn) {
    6195           0 :                 DEBUG(0,("ldapsam_set_primary_group: Out of memory!\n"));
    6196           0 :                 return NT_STATUS_NO_MEMORY;
    6197             :         }
    6198             : 
    6199             :         /* remove the old one, and add the new one, this way we do not risk races */
    6200           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "gidNumber", gidstr);
    6201             : 
    6202           0 :         if (mods == NULL) {
    6203           0 :                 TALLOC_FREE(dn);
    6204           0 :                 return NT_STATUS_OK;
    6205             :         }
    6206             : 
    6207           0 :         rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
    6208           0 :         TALLOC_FREE(dn);
    6209           0 :         if (rc != LDAP_SUCCESS) {
    6210           0 :                 DEBUG(0,("ldapsam_set_primary_group: failed to modify [%s] primary group to [%s]\n",
    6211             :                          pdb_get_username(sampass), gidstr));
    6212           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6213             :         }
    6214             : 
    6215           0 :         flush_pwnam_cache();
    6216             : 
    6217           0 :         return NT_STATUS_OK;
    6218             : }
    6219             : 
    6220             : 
    6221             : /**********************************************************************
    6222             :  trusted domains functions
    6223             :  *********************************************************************/
    6224             : 
    6225           0 : static char *trusteddom_dn(struct ldapsam_privates *ldap_state,
    6226             :                            const char *domain)
    6227             : {
    6228           0 :         return talloc_asprintf(talloc_tos(), "sambaDomainName=%s,%s", domain,
    6229             :                                ldap_state->domain_dn);
    6230             : }
    6231             : 
    6232           0 : static bool get_trusteddom_pw_int(struct ldapsam_privates *ldap_state,
    6233             :                                   TALLOC_CTX *mem_ctx,
    6234             :                                   const char *domain, LDAPMessage **entry)
    6235             : {
    6236           0 :         int rc;
    6237           0 :         char *filter;
    6238           0 :         int scope = LDAP_SCOPE_SUBTREE;
    6239           0 :         const char **attrs = NULL; /* NULL: get all attrs */
    6240           0 :         int attrsonly = 0; /* 0: return values too */
    6241           0 :         LDAPMessage *result = NULL;
    6242           0 :         char *trusted_dn;
    6243           0 :         uint32_t num_result;
    6244             : 
    6245           0 :         filter = talloc_asprintf(talloc_tos(),
    6246             :                                  "(&(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")(sambaDomainName=%s))",
    6247             :                                  domain);
    6248             : 
    6249           0 :         trusted_dn = trusteddom_dn(ldap_state, domain);
    6250           0 :         if (trusted_dn == NULL) {
    6251           0 :                 return False;
    6252             :         }
    6253           0 :         rc = smbldap_search(ldap_state->smbldap_state, trusted_dn, scope,
    6254             :                             filter, attrs, attrsonly, &result);
    6255             : 
    6256           0 :         if (result != NULL) {
    6257           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    6258             :         }
    6259             : 
    6260           0 :         if (rc == LDAP_NO_SUCH_OBJECT) {
    6261           0 :                 *entry = NULL;
    6262           0 :                 return True;
    6263             :         }
    6264             : 
    6265           0 :         if (rc != LDAP_SUCCESS) {
    6266           0 :                 return False;
    6267             :         }
    6268             : 
    6269           0 :         num_result = ldap_count_entries(priv2ld(ldap_state), result);
    6270             : 
    6271           0 :         if (num_result > 1) {
    6272           0 :                 DEBUG(1, ("ldapsam_get_trusteddom_pw: more than one "
    6273             :                           "%s object for domain '%s'?!\n",
    6274             :                           LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
    6275           0 :                 return False;
    6276             :         }
    6277             : 
    6278           0 :         if (num_result == 0) {
    6279           0 :                 DEBUG(1, ("ldapsam_get_trusteddom_pw: no "
    6280             :                           "%s object for domain %s.\n",
    6281             :                           LDAP_OBJ_TRUSTDOM_PASSWORD, domain));
    6282           0 :                 *entry = NULL;
    6283             :         } else {
    6284           0 :                 *entry = ldap_first_entry(priv2ld(ldap_state), result);
    6285             :         }
    6286             : 
    6287           0 :         return True;
    6288             : }
    6289             : 
    6290           0 : static bool ldapsam_get_trusteddom_pw(struct pdb_methods *methods,
    6291             :                                       const char *domain,
    6292             :                                       char** pwd,
    6293             :                                       struct dom_sid *sid,
    6294             :                                       time_t *pass_last_set_time)
    6295             : {
    6296           0 :         struct ldapsam_privates *ldap_state =
    6297             :                 (struct ldapsam_privates *)methods->private_data;
    6298           0 :         LDAPMessage *entry = NULL;
    6299             : 
    6300           0 :         DEBUG(10, ("ldapsam_get_trusteddom_pw called for domain %s\n", domain));
    6301             : 
    6302           0 :         if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry) ||
    6303           0 :             (entry == NULL))
    6304             :         {
    6305           0 :                 return False;
    6306             :         }
    6307             : 
    6308             :         /* password */
    6309           0 :         if (pwd != NULL) {
    6310           0 :                 char *pwd_str;
    6311           0 :                 pwd_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
    6312             :                                 entry, "sambaClearTextPassword", talloc_tos());
    6313           0 :                 if (pwd_str == NULL) {
    6314           0 :                         return False;
    6315             :                 }
    6316             :                 /* trusteddom_pw routines do not use talloc yet... */
    6317           0 :                 *pwd = SMB_STRDUP(pwd_str);
    6318           0 :                 if (*pwd == NULL) {
    6319           0 :                         return False;
    6320             :                 }
    6321             :         }
    6322             : 
    6323             :         /* last change time */
    6324           0 :         if (pass_last_set_time != NULL) {
    6325           0 :                 char *time_str;
    6326           0 :                 time_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
    6327             :                                 entry, "sambaPwdLastSet", talloc_tos());
    6328           0 :                 if (time_str == NULL) {
    6329           0 :                         return False;
    6330             :                 }
    6331           0 :                 *pass_last_set_time = (time_t)atol(time_str);
    6332             :         }
    6333             : 
    6334             :         /* domain sid */
    6335           0 :         if (sid != NULL) {
    6336           0 :                 char *sid_str;
    6337           0 :                 struct dom_sid dom_sid;
    6338           0 :                 sid_str = smbldap_talloc_single_attribute(priv2ld(ldap_state),
    6339             :                                                           entry, "sambaSID",
    6340             :                                                           talloc_tos());
    6341           0 :                 if (sid_str == NULL) {
    6342           0 :                         return False;
    6343             :                 }
    6344           0 :                 if (!string_to_sid(&dom_sid, sid_str)) {
    6345           0 :                         return False;
    6346             :                 }
    6347           0 :                 sid_copy(sid, &dom_sid);
    6348             :         }
    6349             : 
    6350           0 :         return True;
    6351             : }
    6352             : 
    6353           0 : static bool ldapsam_set_trusteddom_pw(struct pdb_methods *methods,
    6354             :                                       const char* domain,
    6355             :                                       const char* pwd,
    6356             :                                       const struct dom_sid *sid)
    6357             : {
    6358           0 :         struct ldapsam_privates *ldap_state =
    6359             :                 (struct ldapsam_privates *)methods->private_data;
    6360           0 :         LDAPMessage *entry = NULL;
    6361           0 :         LDAPMod **mods = NULL;
    6362           0 :         char *prev_pwd = NULL;
    6363           0 :         char *trusted_dn = NULL;
    6364           0 :         struct dom_sid_buf buf;
    6365           0 :         int rc;
    6366             : 
    6367           0 :         DEBUG(10, ("ldapsam_set_trusteddom_pw called for domain %s\n", domain));
    6368             : 
    6369             :         /*
    6370             :          * get the current entry (if there is one) in order to put the
    6371             :          * current password into the previous password attribute
    6372             :          */
    6373           0 :         if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
    6374           0 :                 return False;
    6375             :         }
    6376             : 
    6377           0 :         mods = NULL;
    6378           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "objectClass",
    6379             :                          LDAP_OBJ_TRUSTDOM_PASSWORD);
    6380           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaDomainName",
    6381             :                          domain);
    6382           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaSID",
    6383           0 :                          dom_sid_str_buf(sid, &buf));
    6384           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods, "sambaPwdLastSet",
    6385           0 :                          talloc_asprintf(talloc_tos(), "%li", (long int)time(NULL)));
    6386           0 :         smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
    6387             :                          "sambaClearTextPassword", pwd);
    6388             : 
    6389           0 :         if (entry != NULL) {
    6390           0 :                 prev_pwd = smbldap_talloc_single_attribute(priv2ld(ldap_state),
    6391             :                                 entry, "sambaClearTextPassword", talloc_tos());
    6392           0 :                 if (prev_pwd != NULL) {
    6393           0 :                         smbldap_make_mod(priv2ld(ldap_state), entry, &mods,
    6394             :                                          "sambaPreviousClearTextPassword",
    6395             :                                          prev_pwd);
    6396             :                 }
    6397             :         }
    6398             : 
    6399           0 :         smbldap_talloc_autofree_ldapmod(talloc_tos(), mods);
    6400             : 
    6401           0 :         trusted_dn = trusteddom_dn(ldap_state, domain);
    6402           0 :         if (trusted_dn == NULL) {
    6403           0 :                 return False;
    6404             :         }
    6405           0 :         if (entry == NULL) {
    6406           0 :                 rc = smbldap_add(ldap_state->smbldap_state, trusted_dn, mods);
    6407             :         } else {
    6408           0 :                 rc = smbldap_modify(ldap_state->smbldap_state, trusted_dn, mods);
    6409             :         }
    6410             : 
    6411           0 :         if (rc != LDAP_SUCCESS) {
    6412           0 :                 DEBUG(1, ("error writing trusted domain password!\n"));
    6413           0 :                 return False;
    6414             :         }
    6415             : 
    6416           0 :         return True;
    6417             : }
    6418             : 
    6419           0 : static bool ldapsam_del_trusteddom_pw(struct pdb_methods *methods,
    6420             :                                       const char *domain)
    6421             : {
    6422           0 :         int rc;
    6423           0 :         struct ldapsam_privates *ldap_state =
    6424             :                 (struct ldapsam_privates *)methods->private_data;
    6425           0 :         LDAPMessage *entry = NULL;
    6426           0 :         const char *trusted_dn;
    6427             : 
    6428           0 :         if (!get_trusteddom_pw_int(ldap_state, talloc_tos(), domain, &entry)) {
    6429           0 :                 return False;
    6430             :         }
    6431             : 
    6432           0 :         if (entry == NULL) {
    6433           0 :                 DEBUG(5, ("ldapsam_del_trusteddom_pw: no such trusted domain: "
    6434             :                           "%s\n", domain));
    6435           0 :                 return True;
    6436             :         }
    6437             : 
    6438           0 :         trusted_dn = smbldap_talloc_dn(talloc_tos(), priv2ld(ldap_state),
    6439             :                                        entry);
    6440           0 :         if (trusted_dn == NULL) {
    6441           0 :                 DEBUG(0,("ldapsam_del_trusteddom_pw: Out of memory!\n"));
    6442           0 :                 return False;
    6443             :         }
    6444             : 
    6445           0 :         rc = smbldap_delete(ldap_state->smbldap_state, trusted_dn);
    6446           0 :         if (rc != LDAP_SUCCESS) {
    6447           0 :                 return False;
    6448             :         }
    6449             : 
    6450           0 :         return True;
    6451             : }
    6452             : 
    6453           0 : static NTSTATUS ldapsam_enum_trusteddoms(struct pdb_methods *methods,
    6454             :                                          TALLOC_CTX *mem_ctx,
    6455             :                                          uint32_t *num_domains,
    6456             :                                          struct trustdom_info ***domains)
    6457             : {
    6458           0 :         int rc;
    6459           0 :         struct ldapsam_privates *ldap_state =
    6460             :                 (struct ldapsam_privates *)methods->private_data;
    6461           0 :         const char *filter;
    6462           0 :         int scope = LDAP_SCOPE_SUBTREE;
    6463           0 :         const char *attrs[] = { "sambaDomainName", "sambaSID", NULL };
    6464           0 :         int attrsonly = 0; /* 0: return values too */
    6465           0 :         LDAPMessage *result = NULL;
    6466           0 :         LDAPMessage *entry = NULL;
    6467             : 
    6468           0 :         filter = "(objectClass="LDAP_OBJ_TRUSTDOM_PASSWORD")";
    6469             : 
    6470           0 :         rc = smbldap_search(ldap_state->smbldap_state,
    6471           0 :                             ldap_state->domain_dn,
    6472             :                             scope,
    6473             :                             filter,
    6474             :                             attrs,
    6475             :                             attrsonly,
    6476             :                             &result);
    6477             : 
    6478           0 :         if (result != NULL) {
    6479           0 :                 smbldap_talloc_autofree_ldapmsg(mem_ctx, result);
    6480             :         }
    6481             : 
    6482           0 :         if (rc != LDAP_SUCCESS) {
    6483           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6484             :         }
    6485             : 
    6486           0 :         *num_domains = 0;
    6487           0 :         if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *, 1))) {
    6488           0 :                 DEBUG(1, ("talloc failed\n"));
    6489           0 :                 return NT_STATUS_NO_MEMORY;
    6490             :         }
    6491             : 
    6492           0 :         for (entry = ldap_first_entry(priv2ld(ldap_state), result);
    6493           0 :              entry != NULL;
    6494           0 :              entry = ldap_next_entry(priv2ld(ldap_state), entry))
    6495             :         {
    6496           0 :                 char *dom_name, *dom_sid_str;
    6497           0 :                 struct trustdom_info *dom_info;
    6498             : 
    6499           0 :                 dom_info = talloc(*domains, struct trustdom_info);
    6500           0 :                 if (dom_info == NULL) {
    6501           0 :                         DEBUG(1, ("talloc failed\n"));
    6502           0 :                         return NT_STATUS_NO_MEMORY;
    6503             :                 }
    6504             : 
    6505           0 :                 dom_name = smbldap_talloc_single_attribute(priv2ld(ldap_state),
    6506             :                                                            entry,
    6507             :                                                            "sambaDomainName",
    6508             :                                                            talloc_tos());
    6509           0 :                 if (dom_name == NULL) {
    6510           0 :                         DEBUG(1, ("talloc failed\n"));
    6511           0 :                         return NT_STATUS_NO_MEMORY;
    6512             :                 }
    6513           0 :                 dom_info->name = dom_name;
    6514             : 
    6515           0 :                 dom_sid_str = smbldap_talloc_single_attribute(
    6516             :                                         priv2ld(ldap_state), entry, "sambaSID",
    6517             :                                         talloc_tos());
    6518           0 :                 if (dom_sid_str == NULL) {
    6519           0 :                         DEBUG(1, ("talloc failed\n"));
    6520           0 :                         return NT_STATUS_NO_MEMORY;
    6521             :                 }
    6522           0 :                 if (!string_to_sid(&dom_info->sid, dom_sid_str)) {
    6523           0 :                         DEBUG(1, ("Error calling string_to_sid on SID %s\n",
    6524             :                                   dom_sid_str));
    6525           0 :                         return NT_STATUS_UNSUCCESSFUL;
    6526             :                 }
    6527             : 
    6528           0 :                 ADD_TO_ARRAY(*domains, struct trustdom_info *, dom_info,
    6529             :                              domains, num_domains);
    6530             : 
    6531           0 :                 if (*domains == NULL) {
    6532           0 :                         DEBUG(1, ("talloc failed\n"));
    6533           0 :                         return NT_STATUS_NO_MEMORY;
    6534             :                 }
    6535             :         }
    6536             : 
    6537           0 :         DEBUG(5, ("ldapsam_enum_trusteddoms: got %d domains\n", *num_domains));
    6538           0 :         return NT_STATUS_OK;
    6539             : }
    6540             : 
    6541             : 
    6542             : /**********************************************************************
    6543             :  Housekeeping
    6544             :  *********************************************************************/
    6545             : 
    6546           0 : static void free_private_data(void **vp)
    6547             : {
    6548           0 :         struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
    6549             : 
    6550           0 :         smbldap_free_struct(&(*ldap_state)->smbldap_state);
    6551             : 
    6552           0 :         if ((*ldap_state)->result != NULL) {
    6553           0 :                 ldap_msgfree((*ldap_state)->result);
    6554           0 :                 (*ldap_state)->result = NULL;
    6555             :         }
    6556           0 :         if ((*ldap_state)->domain_dn != NULL) {
    6557           0 :                 SAFE_FREE((*ldap_state)->domain_dn);
    6558             :         }
    6559             : 
    6560           0 :         *ldap_state = NULL;
    6561             : 
    6562             :         /* No need to free any further, as it is talloc()ed */
    6563           0 : }
    6564             : 
    6565             : /*********************************************************************
    6566             :  Initialise the parts of the pdb_methods structure that are common to
    6567             :  all pdb_ldap modes
    6568             : *********************************************************************/
    6569             : 
    6570           0 : static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const char *location)
    6571             : {
    6572           0 :         NTSTATUS nt_status;
    6573           0 :         struct ldapsam_privates *ldap_state;
    6574           0 :         char *bind_dn = NULL;
    6575           0 :         char *bind_secret = NULL;
    6576             : 
    6577           0 :         if (!NT_STATUS_IS_OK(nt_status = make_pdb_method( pdb_method ))) {
    6578           0 :                 return nt_status;
    6579             :         }
    6580             : 
    6581           0 :         (*pdb_method)->name = "ldapsam";
    6582             : 
    6583           0 :         (*pdb_method)->getsampwnam = ldapsam_getsampwnam;
    6584           0 :         (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
    6585           0 :         (*pdb_method)->add_sam_account = ldapsam_add_sam_account;
    6586           0 :         (*pdb_method)->update_sam_account = ldapsam_update_sam_account;
    6587           0 :         (*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
    6588           0 :         (*pdb_method)->rename_sam_account = ldapsam_rename_sam_account;
    6589             : 
    6590           0 :         (*pdb_method)->getgrsid = ldapsam_getgrsid;
    6591           0 :         (*pdb_method)->getgrgid = ldapsam_getgrgid;
    6592           0 :         (*pdb_method)->getgrnam = ldapsam_getgrnam;
    6593           0 :         (*pdb_method)->add_group_mapping_entry = ldapsam_add_group_mapping_entry;
    6594           0 :         (*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
    6595           0 :         (*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
    6596           0 :         (*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
    6597             : 
    6598           0 :         (*pdb_method)->get_account_policy = ldapsam_get_account_policy;
    6599           0 :         (*pdb_method)->set_account_policy = ldapsam_set_account_policy;
    6600             : 
    6601           0 :         (*pdb_method)->get_seq_num = ldapsam_get_seq_num;
    6602             : 
    6603           0 :         (*pdb_method)->capabilities = ldapsam_capabilities;
    6604           0 :         (*pdb_method)->new_rid = ldapsam_new_rid;
    6605             : 
    6606           0 :         (*pdb_method)->get_trusteddom_pw = ldapsam_get_trusteddom_pw;
    6607           0 :         (*pdb_method)->set_trusteddom_pw = ldapsam_set_trusteddom_pw;
    6608           0 :         (*pdb_method)->del_trusteddom_pw = ldapsam_del_trusteddom_pw;
    6609           0 :         (*pdb_method)->enum_trusteddoms = ldapsam_enum_trusteddoms;
    6610             : 
    6611             :         /* TODO: Setup private data and free */
    6612             : 
    6613           0 :         if ( !(ldap_state = talloc_zero(*pdb_method, struct ldapsam_privates)) ) {
    6614           0 :                 DEBUG(0, ("pdb_init_ldapsam_common: talloc() failed for ldapsam private_data!\n"));
    6615           0 :                 return NT_STATUS_NO_MEMORY;
    6616             :         }
    6617             : 
    6618           0 :         if (!fetch_ldap_pw(&bind_dn, &bind_secret)) {
    6619           0 :                 DEBUG(0, ("pdb_init_ldapsam_common: Failed to retrieve LDAP password from secrets.tdb\n"));
    6620           0 :                 return NT_STATUS_NO_MEMORY;
    6621             :         }
    6622             : 
    6623           0 :         nt_status = smbldap_init(*pdb_method, pdb_get_tevent_context(),
    6624             :                                  location, false, bind_dn, bind_secret,
    6625             :                                  &ldap_state->smbldap_state);
    6626           0 :         BURN_FREE_STR(bind_secret);
    6627           0 :         SAFE_FREE(bind_dn);
    6628           0 :         if ( !NT_STATUS_IS_OK(nt_status) ) {
    6629           0 :                 return nt_status;
    6630             :         }
    6631             : 
    6632           0 :         if ( !(ldap_state->domain_name = talloc_strdup(*pdb_method, get_global_sam_name()) ) ) {
    6633           0 :                 return NT_STATUS_NO_MEMORY;
    6634             :         }
    6635             : 
    6636           0 :         (*pdb_method)->private_data = ldap_state;
    6637             : 
    6638           0 :         (*pdb_method)->free_private_data = free_private_data;
    6639             : 
    6640           0 :         return NT_STATUS_OK;
    6641             : }
    6642             : 
    6643           0 : static bool ldapsam_is_responsible_for_wellknown(struct pdb_methods *m)
    6644             : {
    6645           0 :         return true;
    6646             : }
    6647             : 
    6648             : /**********************************************************************
    6649             :  Initialise the normal mode for pdb_ldap
    6650             :  *********************************************************************/
    6651             : 
    6652           0 : NTSTATUS pdb_ldapsam_init_common(struct pdb_methods **pdb_method,
    6653             :                                  const char *location)
    6654             : {
    6655           0 :         NTSTATUS nt_status;
    6656           0 :         struct ldapsam_privates *ldap_state = NULL;
    6657           0 :         uint32_t alg_rid_base;
    6658           0 :         char *alg_rid_base_string = NULL;
    6659           0 :         LDAPMessage *result = NULL;
    6660           0 :         LDAPMessage *entry = NULL;
    6661           0 :         struct dom_sid ldap_domain_sid;
    6662           0 :         struct dom_sid secrets_domain_sid;
    6663           0 :         char *domain_sid_string = NULL;
    6664           0 :         char *dn = NULL;
    6665           0 :         char *uri = talloc_strdup( NULL, location );
    6666             : 
    6667           0 :         trim_char( uri, '\"', '\"' );
    6668           0 :         nt_status = pdb_init_ldapsam_common(pdb_method, uri);
    6669             : 
    6670           0 :         TALLOC_FREE(uri);
    6671             : 
    6672           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    6673           0 :                 return nt_status;
    6674             :         }
    6675             : 
    6676           0 :         (*pdb_method)->name = "ldapsam";
    6677             : 
    6678           0 :         (*pdb_method)->add_aliasmem = ldapsam_add_aliasmem;
    6679           0 :         (*pdb_method)->del_aliasmem = ldapsam_del_aliasmem;
    6680           0 :         (*pdb_method)->enum_aliasmem = ldapsam_enum_aliasmem;
    6681           0 :         (*pdb_method)->enum_alias_memberships = ldapsam_alias_memberships;
    6682           0 :         (*pdb_method)->search_users = ldapsam_search_users;
    6683           0 :         (*pdb_method)->search_groups = ldapsam_search_groups;
    6684           0 :         (*pdb_method)->search_aliases = ldapsam_search_aliases;
    6685           0 :         (*pdb_method)->is_responsible_for_wellknown =
    6686             :                                         ldapsam_is_responsible_for_wellknown;
    6687             : 
    6688           0 :         if (lp_parm_bool(-1, "ldapsam", "trusted", False)) {
    6689           0 :                 (*pdb_method)->enum_group_members = ldapsam_enum_group_members;
    6690           0 :                 (*pdb_method)->enum_group_memberships =
    6691             :                         ldapsam_enum_group_memberships;
    6692           0 :                 (*pdb_method)->lookup_rids = ldapsam_lookup_rids;
    6693           0 :                 (*pdb_method)->sid_to_id = ldapsam_sid_to_id;
    6694           0 :                 (*pdb_method)->id_to_sid = ldapsam_id_to_sid;
    6695             : 
    6696           0 :                 if (lp_parm_bool(-1, "ldapsam", "editposix", False)) {
    6697           0 :                         (*pdb_method)->create_user = ldapsam_create_user;
    6698           0 :                         (*pdb_method)->delete_user = ldapsam_delete_user;
    6699           0 :                         (*pdb_method)->create_dom_group = ldapsam_create_dom_group;
    6700           0 :                         (*pdb_method)->delete_dom_group = ldapsam_delete_dom_group;
    6701           0 :                         (*pdb_method)->add_groupmem = ldapsam_add_groupmem;
    6702           0 :                         (*pdb_method)->del_groupmem = ldapsam_del_groupmem;
    6703           0 :                         (*pdb_method)->set_unix_primary_group = ldapsam_set_primary_group;
    6704             :                 }
    6705             :         }
    6706             : 
    6707           0 :         ldap_state = (struct ldapsam_privates *)((*pdb_method)->private_data);
    6708           0 :         ldap_state->schema_ver = SCHEMAVER_SAMBASAMACCOUNT;
    6709             : 
    6710             :         /* Try to setup the Domain Name, Domain SID, algorithmic rid base */
    6711             : 
    6712           0 :         nt_status = smbldap_search_domain_info(ldap_state->smbldap_state,
    6713             :                                                &result,
    6714             :                                                ldap_state->domain_name, True);
    6715             : 
    6716           0 :         if ( !NT_STATUS_IS_OK(nt_status) ) {
    6717           0 :                 DEBUG(0, ("pdb_init_ldapsam: WARNING: Could not get domain "
    6718             :                           "info, nor add one to the domain. "
    6719             :                           "We cannot work reliably without it.\n"));
    6720           0 :                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    6721             :         }
    6722             : 
    6723             :         /* Given that the above might fail, everything below this must be
    6724             :          * optional */
    6725             : 
    6726           0 :         entry = ldap_first_entry(smbldap_get_ldap(ldap_state->smbldap_state),
    6727             :                                  result);
    6728           0 :         if (!entry) {
    6729           0 :                 DEBUG(0, ("pdb_init_ldapsam: Could not get domain info "
    6730             :                           "entry\n"));
    6731           0 :                 ldap_msgfree(result);
    6732           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6733             :         }
    6734             : 
    6735           0 :         dn = smbldap_talloc_dn(talloc_tos(),
    6736             :                                smbldap_get_ldap(ldap_state->smbldap_state),
    6737             :                                entry);
    6738           0 :         if (!dn) {
    6739           0 :                 ldap_msgfree(result);
    6740           0 :                 return NT_STATUS_UNSUCCESSFUL;
    6741             :         }
    6742             : 
    6743           0 :         ldap_state->domain_dn = smb_xstrdup(dn);
    6744           0 :         TALLOC_FREE(dn);
    6745             : 
    6746           0 :         domain_sid_string = smbldap_talloc_single_attribute(
    6747             :                     smbldap_get_ldap(ldap_state->smbldap_state),
    6748             :                     entry,
    6749             :                     get_userattr_key2string(ldap_state->schema_ver,
    6750             :                                             LDAP_ATTR_USER_SID),
    6751             :                     talloc_tos());
    6752             : 
    6753           0 :         if (domain_sid_string) {
    6754           0 :                 bool found_sid;
    6755           0 :                 if (!string_to_sid(&ldap_domain_sid, domain_sid_string)) {
    6756           0 :                         DEBUG(1, ("pdb_init_ldapsam: SID [%s] could not be "
    6757             :                                   "read as a valid SID\n", domain_sid_string));
    6758           0 :                         ldap_msgfree(result);
    6759           0 :                         TALLOC_FREE(domain_sid_string);
    6760           0 :                         return NT_STATUS_INVALID_PARAMETER;
    6761             :                 }
    6762           0 :                 found_sid = PDB_secrets_fetch_domain_sid(ldap_state->domain_name,
    6763             :                                                      &secrets_domain_sid);
    6764           0 :                 if (!found_sid || !dom_sid_equal(&secrets_domain_sid,
    6765             :                                              &ldap_domain_sid)) {
    6766           0 :                         struct dom_sid_buf buf1, buf2;
    6767           0 :                         DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain "
    6768             :                                   "%s based on pdb_ldap results %s -> %s\n",
    6769             :                                   ldap_state->domain_name,
    6770             :                                   dom_sid_str_buf(&secrets_domain_sid, &buf1),
    6771             :                                   dom_sid_str_buf(&ldap_domain_sid, &buf2)));
    6772             : 
    6773             :                         /* reset secrets.tdb sid */
    6774           0 :                         PDB_secrets_store_domain_sid(ldap_state->domain_name,
    6775             :                                                  &ldap_domain_sid);
    6776           0 :                         DEBUG(1, ("New global sam SID: %s\n",
    6777             :                                   dom_sid_str_buf(get_global_sam_sid(),
    6778             :                                                   &buf1)));
    6779             :                 }
    6780           0 :                 sid_copy(&ldap_state->domain_sid, &ldap_domain_sid);
    6781           0 :                 TALLOC_FREE(domain_sid_string);
    6782             :         }
    6783             : 
    6784           0 :         alg_rid_base_string = smbldap_talloc_single_attribute(
    6785             :                     smbldap_get_ldap(ldap_state->smbldap_state),
    6786             :                     entry,
    6787             :                     get_attr_key2string( dominfo_attr_list,
    6788             :                                          LDAP_ATTR_ALGORITHMIC_RID_BASE ),
    6789             :                     talloc_tos());
    6790           0 :         if (alg_rid_base_string) {
    6791           0 :                 alg_rid_base = (uint32_t)atol(alg_rid_base_string);
    6792           0 :                 if (alg_rid_base != algorithmic_rid_base()) {
    6793           0 :                         DEBUG(0, ("The value of 'algorithmic RID base' has "
    6794             :                                   "changed since the LDAP\n"
    6795             :                                   "database was initialised.  Aborting. \n"));
    6796           0 :                         ldap_msgfree(result);
    6797           0 :                         TALLOC_FREE(alg_rid_base_string);
    6798           0 :                         return NT_STATUS_UNSUCCESSFUL;
    6799             :                 }
    6800           0 :                 TALLOC_FREE(alg_rid_base_string);
    6801             :         }
    6802           0 :         ldap_msgfree(result);
    6803             : 
    6804           0 :         return NT_STATUS_OK;
    6805             : }
    6806             : 
    6807        1674 : NTSTATUS pdb_ldapsam_init(TALLOC_CTX *ctx)
    6808             : {
    6809          16 :         NTSTATUS nt_status;
    6810             : 
    6811        1674 :         nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION,
    6812             :                                         "ldapsam",
    6813             :                                         pdb_ldapsam_init_common);
    6814        1674 :         if (!NT_STATUS_IS_OK(nt_status)) {
    6815           0 :                 return nt_status;
    6816             :         }
    6817             : 
    6818             :         /* Let pdb_nds register backends */
    6819        1674 :         pdb_nds_init(ctx);
    6820             : 
    6821        1674 :         return NT_STATUS_OK;
    6822             : }

Generated by: LCOV version 1.14