LCOV - code coverage report
Current view: top level - source3/passdb - passdb.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 595 1310 45.4 %
Date: 2024-04-21 15:09:00 Functions: 26 42 61.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Password and authentication handling
       4             :    Copyright (C) Jeremy Allison                 1996-2001
       5             :    Copyright (C) Luke Kenneth Casson Leighton   1996-1998
       6             :    Copyright (C) Gerald (Jerry) Carter          2000-2006
       7             :    Copyright (C) Andrew Bartlett                2001-2002
       8             :    Copyright (C) Simo Sorce                     2003
       9             :    Copyright (C) Volker Lendecke                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             : #include "includes.h"
      26             : #include "passdb.h"
      27             : #include "system/passwd.h"
      28             : #include "../libcli/auth/libcli_auth.h"
      29             : #include "secrets.h"
      30             : #include "../libcli/security/security.h"
      31             : #include "../lib/util/util_pw.h"
      32             : #include "util_tdb.h"
      33             : #include "auth/credentials/credentials.h"
      34             : #include "lib/param/param.h"
      35             : #include "lib/util/string_wrappers.h"
      36             : #include "source3/lib/substitute.h"
      37             : 
      38             : #undef DBGC_CLASS
      39             : #define DBGC_CLASS DBGC_PASSDB
      40             : 
      41             : /**********************************************************************
      42             : ***********************************************************************/
      43             : 
      44      106210 : static int samu_destroy(struct samu *user)
      45             : {
      46      106210 :         data_blob_clear_free( &user->lm_pw );
      47      106210 :         data_blob_clear_free( &user->nt_pw );
      48             : 
      49      106210 :         if ( user->plaintext_pw )
      50         576 :                 BURN_STR(user->plaintext_pw);
      51             : 
      52      106210 :         return 0;
      53             : }
      54             : 
      55             : /**********************************************************************
      56             :  generate a new struct samuser
      57             : ***********************************************************************/
      58             : 
      59      106217 : struct samu *samu_new( TALLOC_CTX *ctx )
      60             : {
      61         329 :         struct samu *user;
      62             : 
      63      106217 :         if ( !(user = talloc_zero( ctx, struct samu )) ) {
      64           0 :                 DEBUG(0,("samuser_new: Talloc failed!\n"));
      65           0 :                 return NULL;
      66             :         }
      67             : 
      68      106217 :         talloc_set_destructor( user, samu_destroy );
      69             : 
      70             :         /* no initial methods */
      71             : 
      72      106217 :         user->methods = NULL;
      73             : 
      74             :         /* Don't change these timestamp settings without a good reason.
      75             :            They are important for NT member server compatibility. */
      76             : 
      77      106217 :         user->logon_time            = (time_t)0;
      78      106217 :         user->pass_last_set_time    = (time_t)0;
      79      106217 :         user->pass_can_change_time  = (time_t)0;
      80      106217 :         user->logoff_time           = get_time_t_max();
      81      106217 :         user->kickoff_time          = get_time_t_max();
      82      106217 :         user->fields_present        = 0x00ffffff;
      83      106217 :         user->logon_divs = 168;      /* hours per week */
      84      106217 :         user->hours_len = 21;                /* 21 times 8 bits = 168 */
      85      106217 :         memset(user->hours, 0xff, user->hours_len); /* available at all hours */
      86      106217 :         user->bad_password_count = 0;
      87      106217 :         user->logon_count = 0;
      88      106217 :         user->unknown_6 = 0x000004ec; /* don't know */
      89             : 
      90             :         /* Some parts of samba strlen their pdb_get...() returns,
      91             :            so this keeps the interface unchanged for now. */
      92             : 
      93      106217 :         user->username = "";
      94      106217 :         user->domain = "";
      95      106217 :         user->nt_username = "";
      96      106217 :         user->full_name = "";
      97      106217 :         user->home_dir = "";
      98      106217 :         user->logon_script = "";
      99      106217 :         user->profile_path = "";
     100      106217 :         user->acct_desc = "";
     101      106217 :         user->workstations = "";
     102      106217 :         user->comment = "";
     103      106217 :         user->munged_dial = "";
     104             : 
     105      106217 :         user->plaintext_pw = NULL;
     106             : 
     107             :         /* Unless we know otherwise have a Account Control Bit
     108             :            value of 'normal user'.  This helps User Manager, which
     109             :            asks for a filtered list of users. */
     110             : 
     111      106217 :         user->acct_ctrl = ACB_NORMAL;
     112             : 
     113      106217 :         return user;
     114             : }
     115             : 
     116        2875 : static int count_commas(const char *str)
     117             : {
     118        2875 :         int num_commas = 0;
     119        2875 :         const char *comma = str;
     120             : 
     121        2875 :         while ((comma = strchr(comma, ',')) != NULL) {
     122           0 :                 comma += 1;
     123           0 :                 num_commas += 1;
     124             :         }
     125        2875 :         return num_commas;
     126             : }
     127             : 
     128             : /*********************************************************************
     129             :  Initialize a struct samu from a struct passwd including the user
     130             :  and group SIDs.  The *user structure is filled out with the Unix
     131             :  attributes and a user SID.
     132             : *********************************************************************/
     133             : 
     134        2875 : static NTSTATUS samu_set_unix_internal(struct pdb_methods *methods,
     135             :                                        struct samu *user, const struct passwd *pwd, bool create)
     136             : {
     137        2875 :         const char *guest_account = lp_guest_account();
     138        2875 :         const char *domain = lp_netbios_name();
     139           0 :         char *fullname;
     140           0 :         uint32_t urid;
     141           0 :         bool ok;
     142             : 
     143        2875 :         if ( !pwd ) {
     144           0 :                 return NT_STATUS_NO_SUCH_USER;
     145             :         }
     146             : 
     147             :         /* Basic properties based upon the Unix account information */
     148             : 
     149        2875 :         ok = pdb_set_username(user, pwd->pw_name, PDB_SET);
     150        2875 :         if (!ok) {
     151           0 :                 return NT_STATUS_NO_MEMORY;
     152             :         }
     153             : 
     154        2875 :         fullname = NULL;
     155             : 
     156        2875 :         if (count_commas(pwd->pw_gecos) == 3) {
     157             :                 /*
     158             :                  * Heuristic: This seems to be a gecos field that has been
     159             :                  * edited by chfn(1). Only use the part before the first
     160             :                  * comma. Fixes bug 5198.
     161             :                  */
     162           0 :                 fullname = talloc_strndup(
     163           0 :                         talloc_tos(), pwd->pw_gecos,
     164           0 :                         strchr(pwd->pw_gecos, ',') - pwd->pw_gecos);
     165           0 :                 if (fullname == NULL) {
     166           0 :                         return NT_STATUS_NO_MEMORY;
     167             :                 }
     168             :         }
     169             : 
     170        2875 :         if (fullname != NULL) {
     171           0 :                 ok = pdb_set_fullname(user, fullname, PDB_SET);
     172             :         } else {
     173        2875 :                 ok = pdb_set_fullname(user, pwd->pw_gecos, PDB_SET);
     174             :         }
     175        2875 :         TALLOC_FREE(fullname);
     176             : 
     177        2875 :         if (!ok) {
     178           0 :                 return NT_STATUS_NO_MEMORY;
     179             :         }
     180             : 
     181        2875 :         ok = pdb_set_domain(user, get_global_sam_name(), PDB_DEFAULT);
     182        2875 :         if (!ok) {
     183           0 :                 return NT_STATUS_NO_MEMORY;
     184             :         }
     185             : #if 0
     186             :         /* This can lead to a primary group of S-1-22-2-XX which
     187             :            will be rejected by other parts of the Samba code.
     188             :            Rely on pdb_get_group_sid() to "Do The Right Thing" (TM)
     189             :            --jerry */
     190             : 
     191             :         gid_to_sid(&group_sid, pwd->pw_gid);
     192             :         pdb_set_group_sid(user, &group_sid, PDB_SET);
     193             : #endif
     194             : 
     195             :         /* save the password structure for later use */
     196             : 
     197        2875 :         user->unix_pw = tcopy_passwd( user, pwd );
     198        2875 :         if (user->unix_pw == NULL) {
     199           0 :                 return NT_STATUS_NO_MEMORY;
     200             :         }
     201             : 
     202             :         /* Special case for the guest account which must have a RID of 501 */
     203             : 
     204        2875 :         if ( strequal( pwd->pw_name, guest_account ) ) {
     205          96 :                 if ( !pdb_set_user_sid_from_rid(user, DOMAIN_RID_GUEST, PDB_DEFAULT)) {
     206           0 :                         return NT_STATUS_NO_SUCH_USER;
     207             :                 }
     208          96 :                 return NT_STATUS_OK;
     209             :         }
     210             : 
     211             :         /* Non-guest accounts...Check for a workstation or user account */
     212             : 
     213        2779 :         if (pwd->pw_name[strlen(pwd->pw_name)-1] == '$') {
     214             :                 /* workstation */
     215             : 
     216          42 :                 if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_DEFAULT)) {
     217           0 :                         DEBUG(1, ("Failed to set 'workstation account' flags for user %s.\n",
     218             :                                 pwd->pw_name));
     219           0 :                         return NT_STATUS_INVALID_COMPUTER_NAME;
     220             :                 }
     221             :         }
     222             :         else {
     223             :                 /* user */
     224             : 
     225        2737 :                 if (!pdb_set_acct_ctrl(user, ACB_NORMAL, PDB_DEFAULT)) {
     226           0 :                         DEBUG(1, ("Failed to set 'normal account' flags for user %s.\n",
     227             :                                 pwd->pw_name));
     228           0 :                         return NT_STATUS_INVALID_ACCOUNT_NAME;
     229             :                 }
     230             : 
     231             :                 /* set some basic attributes */
     232             : 
     233        2737 :                 ok = pdb_set_profile_path(
     234             :                         user,
     235        2737 :                         talloc_sub_specified(
     236             :                                 user,
     237             :                                 lp_logon_path(),
     238        2737 :                                 pwd->pw_name,
     239             :                                 NULL,
     240             :                                 domain,
     241        2737 :                                 pwd->pw_uid,
     242        2737 :                                 pwd->pw_gid),
     243             :                         PDB_DEFAULT);
     244        2737 :                 ok &= pdb_set_homedir(
     245             :                         user,
     246        2737 :                         talloc_sub_specified(
     247             :                                 user,
     248             :                                 lp_logon_home(),
     249        2737 :                                 pwd->pw_name,
     250             :                                 NULL,
     251             :                                 domain,
     252        2737 :                                 pwd->pw_uid,
     253        2737 :                                 pwd->pw_gid),
     254             :                         PDB_DEFAULT);
     255        2737 :                 ok &= pdb_set_dir_drive(
     256             :                         user,
     257        2737 :                         talloc_sub_specified(
     258             :                                 user,
     259             :                                 lp_logon_drive(),
     260        2737 :                                 pwd->pw_name,
     261             :                                 NULL,
     262             :                                 domain,
     263        2737 :                                 pwd->pw_uid,
     264        2737 :                                 pwd->pw_gid),
     265             :                         PDB_DEFAULT);
     266        2737 :                 ok &= pdb_set_logon_script(
     267             :                         user,
     268        2737 :                         talloc_sub_specified(
     269             :                                 user,
     270             :                                 lp_logon_script(),
     271        2737 :                                 pwd->pw_name,
     272             :                                 NULL,
     273             :                                 domain,
     274        2737 :                                 pwd->pw_uid,
     275        2737 :                                 pwd->pw_gid),
     276             :                         PDB_DEFAULT);
     277        2737 :                 if (!ok) {
     278           0 :                         return NT_STATUS_NO_MEMORY;
     279             :                 }
     280             :         }
     281             : 
     282             :         /* Now deal with the user SID.  If we have a backend that can generate
     283             :            RIDs, then do so.  But sometimes the caller just wanted a structure
     284             :            initialized and will fill in these fields later (such as from a
     285             :            netr_SamInfo3 structure) */
     286             : 
     287        2779 :         if ( create && (methods->capabilities(methods) & PDB_CAP_STORE_RIDS)) {
     288           0 :                 uint32_t user_rid;
     289           0 :                 struct dom_sid user_sid;
     290             : 
     291         552 :                 if ( !methods->new_rid(methods, &user_rid) ) {
     292           0 :                         DEBUG(3, ("Could not allocate a new RID\n"));
     293           0 :                         return NT_STATUS_ACCESS_DENIED;
     294             :                 }
     295             : 
     296         552 :                 sid_compose(&user_sid, get_global_sam_sid(), user_rid);
     297             : 
     298         552 :                 if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
     299           0 :                         DEBUG(3, ("pdb_set_user_sid failed\n"));
     300           0 :                         return NT_STATUS_INTERNAL_ERROR;
     301             :                 }
     302             : 
     303         552 :                 return NT_STATUS_OK;
     304             :         }
     305             : 
     306             :         /* generate a SID for the user with the RID algorithm */
     307             : 
     308        2227 :         urid = algorithmic_pdb_uid_to_user_rid( user->unix_pw->pw_uid );
     309             : 
     310        2227 :         if ( !pdb_set_user_sid_from_rid( user, urid, PDB_SET) ) {
     311           0 :                 return NT_STATUS_INTERNAL_ERROR;
     312             :         }
     313             : 
     314        2227 :         return NT_STATUS_OK;
     315             : }
     316             : 
     317             : /********************************************************************
     318             :  Set the Unix user attributes
     319             : ********************************************************************/
     320             : 
     321        2323 : NTSTATUS samu_set_unix(struct samu *user, const struct passwd *pwd)
     322             : {
     323        2323 :         return samu_set_unix_internal( NULL, user, pwd, False );
     324             : }
     325             : 
     326         552 : NTSTATUS samu_alloc_rid_unix(struct pdb_methods *methods,
     327             :                              struct samu *user, const struct passwd *pwd)
     328             : {
     329         552 :         return samu_set_unix_internal( methods, user, pwd, True );
     330             : }
     331             : 
     332             : /**********************************************************
     333             :  Encode the account control bits into a string.
     334             :  length = length of string to encode into (including terminating
     335             :  null). length *MUST BE MORE THAN 2* !
     336             :  **********************************************************/
     337             : 
     338           9 : char *pdb_encode_acct_ctrl(uint32_t acct_ctrl, size_t length)
     339             : {
     340           0 :         fstring acct_str;
     341           0 :         char *result;
     342             : 
     343           9 :         size_t i = 0;
     344             : 
     345           9 :         SMB_ASSERT(length <= sizeof(acct_str));
     346             : 
     347           9 :         acct_str[i++] = '[';
     348             : 
     349           9 :         if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
     350           9 :         if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
     351           9 :         if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
     352           9 :         if (acct_ctrl & ACB_TEMPDUP  ) acct_str[i++] = 'T';
     353           9 :         if (acct_ctrl & ACB_NORMAL   ) acct_str[i++] = 'U';
     354           9 :         if (acct_ctrl & ACB_MNS      ) acct_str[i++] = 'M';
     355           9 :         if (acct_ctrl & ACB_WSTRUST  ) acct_str[i++] = 'W';
     356           9 :         if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
     357           9 :         if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
     358           9 :         if (acct_ctrl & ACB_PWNOEXP  ) acct_str[i++] = 'X';
     359           9 :         if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
     360             : 
     361          96 :         for ( ; i < length - 2 ; i++ )
     362          87 :                 acct_str[i] = ' ';
     363             : 
     364           9 :         i = length - 2;
     365           9 :         acct_str[i++] = ']';
     366           9 :         acct_str[i++] = '\0';
     367             : 
     368           9 :         result = talloc_strdup(talloc_tos(), acct_str);
     369           9 :         SMB_ASSERT(result != NULL);
     370           9 :         return result;
     371             : }
     372             : 
     373             : /**********************************************************
     374             :  Decode the account control bits from a string.
     375             :  **********************************************************/
     376             : 
     377           0 : uint32_t pdb_decode_acct_ctrl(const char *p)
     378             : {
     379           0 :         uint32_t acct_ctrl = 0;
     380           0 :         bool finished = false;
     381             : 
     382             :         /*
     383             :          * Check if the account type bits have been encoded after the
     384             :          * NT password (in the form [NDHTUWSLXI]).
     385             :          */
     386             : 
     387           0 :         if (*p != '[')
     388           0 :                 return 0;
     389             : 
     390           0 :         for (p++; *p && !finished; p++) {
     391           0 :                 switch (*p) {
     392           0 :                         case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
     393           0 :                         case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
     394           0 :                         case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
     395           0 :                         case 'T': { acct_ctrl |= ACB_TEMPDUP  ; break; /* 'T'emp account. */ }
     396           0 :                         case 'U': { acct_ctrl |= ACB_NORMAL   ; break; /* 'U'ser account (normal). */ }
     397           0 :                         case 'M': { acct_ctrl |= ACB_MNS      ; break; /* 'M'NS logon user account. What is this ? */ }
     398           0 :                         case 'W': { acct_ctrl |= ACB_WSTRUST  ; break; /* 'W'orkstation account. */ }
     399           0 :                         case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
     400           0 :                         case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
     401           0 :                         case 'X': { acct_ctrl |= ACB_PWNOEXP  ; break; /* No 'X'piry on password */ }
     402           0 :                         case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
     403           0 :             case ' ': { break; }
     404           0 :                         case ':':
     405             :                         case '\n':
     406             :                         case '\0':
     407             :                         case ']':
     408           0 :                         default:  { finished = true; }
     409             :                 }
     410             :         }
     411             : 
     412           0 :         return acct_ctrl;
     413             : }
     414             : 
     415             : /*************************************************************
     416             :  Routine to set 32 hex password characters from a 16 byte array.
     417             : **************************************************************/
     418             : 
     419           6 : void pdb_sethexpwd(char p[33], const unsigned char *pwd, uint32_t acct_ctrl)
     420             : {
     421           6 :         if (pwd != NULL) {
     422           5 :                 hex_encode_buf(p, pwd, 16);
     423             :         } else {
     424           1 :                 if (acct_ctrl & ACB_PWNOTREQ)
     425           0 :                         strlcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
     426             :                 else
     427           1 :                         strlcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
     428             :         }
     429           6 : }
     430             : 
     431             : /*************************************************************
     432             :  Routine to get the 32 hex characters and turn them
     433             :  into a 16 byte array.
     434             : **************************************************************/
     435             : 
     436           3 : bool pdb_gethexpwd(const char *p, unsigned char *pwd)
     437             : {
     438           0 :         int i;
     439           0 :         unsigned char   lonybble, hinybble;
     440           3 :         const char      *hexchars = "0123456789ABCDEF";
     441           0 :         char           *p1, *p2;
     442             : 
     443           3 :         if (!p)
     444           0 :                 return false;
     445             : 
     446          51 :         for (i = 0; i < 32; i += 2) {
     447          48 :                 hinybble = toupper_m(p[i]);
     448          48 :                 lonybble = toupper_m(p[i + 1]);
     449             : 
     450          48 :                 p1 = strchr(hexchars, hinybble);
     451          48 :                 p2 = strchr(hexchars, lonybble);
     452             : 
     453          48 :                 if (!p1 || !p2)
     454           0 :                         return false;
     455             : 
     456          48 :                 hinybble = PTR_DIFF(p1, hexchars);
     457          48 :                 lonybble = PTR_DIFF(p2, hexchars);
     458             : 
     459          48 :                 pwd[i / 2] = (hinybble << 4) | lonybble;
     460             :         }
     461           3 :         return true;
     462             : }
     463             : 
     464             : /*************************************************************
     465             :  Routine to set 42 hex hours characters from a 21 byte array.
     466             : **************************************************************/
     467             : 
     468          13 : void pdb_sethexhours(char *p, const unsigned char *hours)
     469             : {
     470          13 :         if (hours != NULL) {
     471          13 :                 hex_encode_buf(p, hours, 21);
     472             :         } else {
     473           0 :                 strlcpy(p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 44);
     474             :         }
     475          13 : }
     476             : 
     477             : /*************************************************************
     478             :  Routine to get the 42 hex characters and turn them
     479             :  into a 21 byte array.
     480             : **************************************************************/
     481             : 
     482           0 : bool pdb_gethexhours(const char *p, unsigned char *hours)
     483             : {
     484           0 :         int i;
     485           0 :         unsigned char   lonybble, hinybble;
     486           0 :         const char      *hexchars = "0123456789ABCDEF";
     487           0 :         char           *p1, *p2;
     488             : 
     489           0 :         if (!p) {
     490           0 :                 return (False);
     491             :         }
     492             : 
     493           0 :         for (i = 0; i < 42; i += 2) {
     494           0 :                 hinybble = toupper_m(p[i]);
     495           0 :                 lonybble = toupper_m(p[i + 1]);
     496             : 
     497           0 :                 p1 = strchr(hexchars, hinybble);
     498           0 :                 p2 = strchr(hexchars, lonybble);
     499             : 
     500           0 :                 if (!p1 || !p2) {
     501           0 :                         return (False);
     502             :                 }
     503             : 
     504           0 :                 hinybble = PTR_DIFF(p1, hexchars);
     505           0 :                 lonybble = PTR_DIFF(p2, hexchars);
     506             : 
     507           0 :                 hours[i / 2] = (hinybble << 4) | lonybble;
     508             :         }
     509           0 :         return (True);
     510             : }
     511             : 
     512             : /********************************************************************
     513             : ********************************************************************/
     514             : 
     515        2831 : int algorithmic_rid_base(void)
     516             : {
     517           0 :         int rid_offset;
     518             : 
     519        2831 :         rid_offset = lp_algorithmic_rid_base();
     520             : 
     521        2831 :         if (rid_offset < BASE_RID) {
     522             :                 /* Try to prevent admin foot-shooting, we can't put algorithmic
     523             :                    rids below 1000, that's the 'well known RIDs' on NT */
     524           0 :                 DEBUG(0, ("'algorithmic rid base' must be equal to or above %ld\n", BASE_RID));
     525           0 :                 rid_offset = BASE_RID;
     526             :         }
     527        2831 :         if (rid_offset & 1) {
     528           0 :                 DEBUG(0, ("algorithmic rid base must be even\n"));
     529           0 :                 rid_offset += 1;
     530             :         }
     531        2831 :         return rid_offset;
     532             : }
     533             : 
     534             : /*******************************************************************
     535             :  Converts NT user RID to a UNIX uid.
     536             :  ********************************************************************/
     537             : 
     538           0 : uid_t algorithmic_pdb_user_rid_to_uid(uint32_t user_rid)
     539             : {
     540           0 :         int rid_offset = algorithmic_rid_base();
     541           0 :         return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER);
     542             : }
     543             : 
     544           0 : uid_t max_algorithmic_uid(void)
     545             : {
     546           0 :         return algorithmic_pdb_user_rid_to_uid(0xfffffffe);
     547             : }
     548             : 
     549             : /*******************************************************************
     550             :  converts UNIX uid to an NT User RID.
     551             :  ********************************************************************/
     552             : 
     553        2227 : uint32_t algorithmic_pdb_uid_to_user_rid(uid_t uid)
     554             : {
     555        2227 :         int rid_offset = algorithmic_rid_base();
     556        2227 :         return (((((uint32_t)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
     557             : }
     558             : 
     559             : /*******************************************************************
     560             :  Converts NT group RID to a UNIX gid.
     561             :  ********************************************************************/
     562             : 
     563           0 : gid_t pdb_group_rid_to_gid(uint32_t group_rid)
     564             : {
     565           0 :         int rid_offset = algorithmic_rid_base();
     566           0 :         return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
     567             : }
     568             : 
     569           0 : gid_t max_algorithmic_gid(void)
     570             : {
     571           0 :         return pdb_group_rid_to_gid(0xffffffff);
     572             : }
     573             : 
     574             : /*******************************************************************
     575             :  converts NT Group RID to a UNIX uid.
     576             : 
     577             :  warning: you must not call that function only
     578             :  you must do a call to the group mapping first.
     579             :  there is not anymore a direct link between the gid and the rid.
     580             :  ********************************************************************/
     581             : 
     582           0 : uint32_t algorithmic_pdb_gid_to_group_rid(gid_t gid)
     583             : {
     584           0 :         int rid_offset = algorithmic_rid_base();
     585           0 :         return (((((uint32_t)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
     586             : }
     587             : 
     588             : /*******************************************************************
     589             :  Decides if a RID is a well known RID.
     590             :  ********************************************************************/
     591             : 
     592           0 : static bool rid_is_well_known(uint32_t rid)
     593             : {
     594             :         /* Not using rid_offset here, because this is the actual
     595             :            NT fixed value (1000) */
     596             : 
     597           0 :         return (rid < BASE_RID);
     598             : }
     599             : 
     600             : /*******************************************************************
     601             :  Decides if a RID is a user or group RID.
     602             :  ********************************************************************/
     603             : 
     604           0 : bool algorithmic_pdb_rid_is_user(uint32_t rid)
     605             : {
     606           0 :         if ( rid_is_well_known(rid) ) {
     607             :                 /*
     608             :                  * The only well known user RIDs are DOMAIN_RID_ADMINISTRATOR
     609             :                  * and DOMAIN_RID_GUEST.
     610             :                  */
     611           0 :                 if(rid == DOMAIN_RID_ADMINISTRATOR || rid == DOMAIN_RID_GUEST)
     612           0 :                         return True;
     613           0 :         } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
     614           0 :                 return True;
     615             :         }
     616           0 :         return False;
     617             : }
     618             : 
     619             : /*******************************************************************
     620             :  Convert a name into a SID. Used in the lookup name rpc.
     621             :  ********************************************************************/
     622             : 
     623        2940 : bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
     624             :                             enum lsa_SidType *type)
     625             : {
     626           0 :         GROUP_MAP *map;
     627           0 :         bool ret;
     628             : 
     629             :         /* Windows treats "MACHINE\None" as a special name for
     630             :            rid 513 on non-DCs.  You cannot create a user or group
     631             :            name "None" on Windows.  You will get an error that
     632             :            the group already exists. */
     633             : 
     634        2940 :         if ( strequal( name, "None" ) ) {
     635           0 :                 *rid = DOMAIN_RID_USERS;
     636           0 :                 *type = SID_NAME_DOM_GRP;
     637             : 
     638           0 :                 return True;
     639             :         }
     640             : 
     641             :         /* LOOKUP_NAME_GROUP is a hack to allow valid users = @foo to work
     642             :          * correctly in the case where foo also exists as a user. If the flag
     643             :          * is set, don't look for users at all. */
     644             : 
     645        2940 :         if ((flags & LOOKUP_NAME_GROUP) == 0) {
     646        2794 :                 struct samu *sam_account = NULL;
     647           0 :                 struct dom_sid user_sid;
     648             : 
     649        2794 :                 if ( !(sam_account = samu_new( NULL )) ) {
     650         943 :                         return False;
     651             :                 }
     652             : 
     653        2794 :                 become_root();
     654        2794 :                 ret =  pdb_getsampwnam(sam_account, name);
     655        2794 :                 unbecome_root();
     656             : 
     657        2794 :                 if (ret) {
     658         943 :                         sid_copy(&user_sid, pdb_get_user_sid(sam_account));
     659             :                 }
     660             : 
     661        2794 :                 TALLOC_FREE(sam_account);
     662             : 
     663        2794 :                 if (ret) {
     664         943 :                         if (!sid_check_is_in_our_sam(&user_sid)) {
     665           0 :                                 struct dom_sid_buf buf;
     666           0 :                                 DBG_ERR("User %s with invalid SID %s"
     667             :                                         " in passdb\n",
     668             :                                         name,
     669             :                                         dom_sid_str_buf(&user_sid, &buf));
     670           0 :                                 return False;
     671             :                         }
     672             : 
     673         943 :                         sid_peek_rid(&user_sid, rid);
     674         943 :                         *type = SID_NAME_USER;
     675         943 :                         return True;
     676             :                 }
     677             :         }
     678             : 
     679             :         /*
     680             :          * Maybe it is a group ?
     681             :          */
     682             : 
     683        1997 :         map = talloc_zero(NULL, GROUP_MAP);
     684        1997 :         if (!map) {
     685           0 :                 return false;
     686             :         }
     687             : 
     688        1997 :         become_root();
     689        1997 :         ret = pdb_getgrnam(map, name);
     690        1997 :         unbecome_root();
     691             : 
     692        1997 :         if (!ret) {
     693        1945 :                 TALLOC_FREE(map);
     694        1945 :                 return False;
     695             :         }
     696             : 
     697             :         /* BUILTIN groups are looked up elsewhere */
     698          52 :         if (!sid_check_is_in_our_sam(&map->sid)) {
     699           0 :                 struct dom_sid_buf buf;
     700           2 :                 DEBUG(10, ("Found group %s (%s) not in our domain -- "
     701             :                            "ignoring.\n",
     702             :                            name,
     703             :                            dom_sid_str_buf(&map->sid, &buf)));
     704           2 :                 TALLOC_FREE(map);
     705           2 :                 return False;
     706             :         }
     707             : 
     708             :         /* yes it's a mapped group */
     709          50 :         sid_peek_rid(&map->sid, rid);
     710          50 :         *type = map->sid_name_use;
     711          50 :         TALLOC_FREE(map);
     712          50 :         return True;
     713             : }
     714             : 
     715             : /*************************************************************
     716             :  Change a password entry in the local passdb backend.
     717             : 
     718             :  Assumptions:
     719             :   - always called as root
     720             :   - ignores the account type except when adding a new account
     721             :   - will create/delete the unix account if the relative
     722             :     add/delete user script is configured
     723             : 
     724             :  *************************************************************/
     725             : 
     726         508 : NTSTATUS local_password_change(const char *user_name,
     727             :                                 int local_flags,
     728             :                                 const char *new_passwd,
     729             :                                 char **pp_err_str,
     730             :                                 char **pp_msg_str)
     731             : {
     732           0 :         TALLOC_CTX *tosctx;
     733           0 :         struct samu *sam_pass;
     734           0 :         uint32_t acb;
     735           0 :         uint32_t rid;
     736           0 :         NTSTATUS result;
     737           0 :         bool user_exists;
     738         508 :         int ret = -1;
     739             : 
     740         508 :         *pp_err_str = NULL;
     741         508 :         *pp_msg_str = NULL;
     742             : 
     743         508 :         tosctx = talloc_tos();
     744             : 
     745         508 :         sam_pass = samu_new(tosctx);
     746         508 :         if (!sam_pass) {
     747           0 :                 result = NT_STATUS_NO_MEMORY;
     748           0 :                 goto done;
     749             :         }
     750             : 
     751             :         /* Get the smb passwd entry for this user */
     752         508 :         user_exists = pdb_getsampwnam(sam_pass, user_name);
     753             : 
     754             :         /* Check delete first, we don't need to do anything else if we
     755             :          * are going to delete the account */
     756         508 :         if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
     757             : 
     758           4 :                 result = pdb_delete_user(tosctx, sam_pass);
     759           4 :                 if (!NT_STATUS_IS_OK(result)) {
     760           0 :                         ret = asprintf(pp_err_str,
     761             :                                         "Failed to delete entry for user %s.\n",
     762             :                                         user_name);
     763           0 :                         if (ret < 0) {
     764           0 :                                 *pp_err_str = NULL;
     765             :                         }
     766           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     767             :                 } else {
     768           4 :                         ret = asprintf(pp_msg_str,
     769             :                                         "Deleted user %s.\n",
     770             :                                         user_name);
     771           4 :                         if (ret < 0) {
     772           0 :                                 *pp_msg_str = NULL;
     773             :                         }
     774             :                 }
     775           4 :                 goto done;
     776             :         }
     777             : 
     778         504 :         if (user_exists && (local_flags & LOCAL_ADD_USER)) {
     779             :                 /* the entry already existed */
     780           0 :                 local_flags &= ~LOCAL_ADD_USER;
     781             :         }
     782             : 
     783         504 :         if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
     784           0 :                 ret = asprintf(pp_err_str,
     785             :                                 "Failed to find entry for user %s.\n",
     786             :                                 user_name);
     787           0 :                 if (ret < 0) {
     788           0 :                         *pp_err_str = NULL;
     789             :                 }
     790           0 :                 result = NT_STATUS_NO_SUCH_USER;
     791           0 :                 goto done;
     792             :         }
     793             : 
     794             :         /* First thing add the new user if we are required to do so */
     795         504 :         if (local_flags & LOCAL_ADD_USER) {
     796             : 
     797         499 :                 if (local_flags & LOCAL_TRUST_ACCOUNT) {
     798           2 :                         acb = ACB_WSTRUST;
     799         497 :                 } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
     800           0 :                         acb = ACB_DOMTRUST;
     801             :                 } else {
     802         497 :                         acb = ACB_NORMAL;
     803             :                 }
     804             : 
     805         499 :                 result = pdb_create_user(tosctx, user_name, acb, &rid);
     806         499 :                 if (!NT_STATUS_IS_OK(result)) {
     807           0 :                         ret = asprintf(pp_err_str,
     808             :                                         "Failed to add entry for user %s.\n",
     809             :                                         user_name);
     810           0 :                         if (ret < 0) {
     811           0 :                                 *pp_err_str = NULL;
     812             :                         }
     813           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     814           0 :                         goto done;
     815             :                 }
     816             : 
     817         499 :                 sam_pass = samu_new(tosctx);
     818         499 :                 if (!sam_pass) {
     819           0 :                         result = NT_STATUS_NO_MEMORY;
     820           0 :                         goto done;
     821             :                 }
     822             : 
     823             :                 /* Now get back the smb passwd entry for this new user */
     824         499 :                 user_exists = pdb_getsampwnam(sam_pass, user_name);
     825         499 :                 if (!user_exists) {
     826           0 :                         ret = asprintf(pp_err_str,
     827             :                                         "Failed to add entry for user %s.\n",
     828             :                                         user_name);
     829           0 :                         if (ret < 0) {
     830           0 :                                 *pp_err_str = NULL;
     831             :                         }
     832           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     833           0 :                         goto done;
     834             :                 }
     835             :         }
     836             : 
     837         504 :         acb = pdb_get_acct_ctrl(sam_pass);
     838             : 
     839             :         /*
     840             :          * We are root - just write the new password
     841             :          * and the valid last change time.
     842             :          */
     843         504 :         if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
     844           0 :                 acb |= ACB_PWNOTREQ;
     845           0 :                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
     846           0 :                         ret = asprintf(pp_err_str,
     847             :                                         "Failed to set 'no password required' "
     848             :                                         "flag for user %s.\n", user_name);
     849           0 :                         if (ret < 0) {
     850           0 :                                 *pp_err_str = NULL;
     851             :                         }
     852           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     853           0 :                         goto done;
     854             :                 }
     855             :         }
     856             : 
     857         504 :         if (local_flags & LOCAL_SET_PASSWORD) {
     858             :                 /*
     859             :                  * If we're dealing with setting a completely empty user account
     860             :                  * ie. One with a password of 'XXXX', but not set disabled (like
     861             :                  * an account created from scratch) then if the old password was
     862             :                  * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
     863             :                  * We remove that as we're giving this user their first password
     864             :                  * and the decision hasn't really been made to disable them (ie.
     865             :                  * don't create them disabled). JRA.
     866             :                  */
     867         504 :                 if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
     868         502 :                     (acb & ACB_DISABLED)) {
     869         499 :                         acb &= (~ACB_DISABLED);
     870         499 :                         if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
     871           0 :                                 ret = asprintf(pp_err_str,
     872             :                                                 "Failed to unset 'disabled' "
     873             :                                                 "flag for user %s.\n",
     874             :                                                 user_name);
     875           0 :                                 if (ret < 0) {
     876           0 :                                         *pp_err_str = NULL;
     877             :                                 }
     878           0 :                                 result = NT_STATUS_UNSUCCESSFUL;
     879           0 :                                 goto done;
     880             :                         }
     881             :                 }
     882             : 
     883         504 :                 acb &= (~ACB_PWNOTREQ);
     884         504 :                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
     885           0 :                         ret = asprintf(pp_err_str,
     886             :                                         "Failed to unset 'no password required'"
     887             :                                         " flag for user %s.\n", user_name);
     888           0 :                         if (ret < 0) {
     889           0 :                                 *pp_err_str = NULL;
     890             :                         }
     891           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     892           0 :                         goto done;
     893             :                 }
     894             : 
     895         504 :                 if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
     896           0 :                         ret = asprintf(pp_err_str,
     897             :                                         "Failed to set password for "
     898             :                                         "user %s.\n", user_name);
     899           0 :                                 if (ret < 0) {
     900           0 :                                 *pp_err_str = NULL;
     901             :                         }
     902           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     903           0 :                         goto done;
     904             :                 }
     905             :         }
     906             : 
     907         504 :         if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
     908           0 :                 acb |= ACB_DISABLED;
     909           0 :                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
     910           0 :                         ret = asprintf(pp_err_str,
     911             :                                         "Failed to set 'disabled' flag for "
     912             :                                         "user %s.\n", user_name);
     913           0 :                         if (ret < 0) {
     914           0 :                                 *pp_err_str = NULL;
     915             :                         }
     916           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     917           0 :                         goto done;
     918             :                 }
     919             :         }
     920             : 
     921         504 :         if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
     922           0 :                 acb &= (~ACB_DISABLED);
     923           0 :                 if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
     924           0 :                         ret = asprintf(pp_err_str,
     925             :                                         "Failed to unset 'disabled' flag for "
     926             :                                         "user %s.\n", user_name);
     927           0 :                         if (ret < 0) {
     928           0 :                                 *pp_err_str = NULL;
     929             :                         }
     930           0 :                         result = NT_STATUS_UNSUCCESSFUL;
     931           0 :                         goto done;
     932             :                 }
     933             :         }
     934             : 
     935             :         /* now commit changes if any */
     936         504 :         result = pdb_update_sam_account(sam_pass);
     937         504 :         if (!NT_STATUS_IS_OK(result)) {
     938           0 :                 ret = asprintf(pp_err_str,
     939             :                                 "Failed to modify entry for user %s.\n",
     940             :                                 user_name);
     941           0 :                 if (ret < 0) {
     942           0 :                         *pp_err_str = NULL;
     943             :                 }
     944           0 :                 goto done;
     945             :         }
     946             : 
     947         504 :         if (local_flags & LOCAL_ADD_USER) {
     948         499 :                 ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
     949           5 :         } else if (local_flags & LOCAL_DISABLE_USER) {
     950           0 :                 ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
     951           5 :         } else if (local_flags & LOCAL_ENABLE_USER) {
     952           0 :                 ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
     953           5 :         } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
     954           0 :                 ret = asprintf(pp_msg_str,
     955             :                                 "User %s password set to none.\n", user_name);
     956             :         }
     957             : 
     958         504 :         if (ret < 0) {
     959           5 :                 *pp_msg_str = NULL;
     960             :         }
     961             : 
     962         504 :         result = NT_STATUS_OK;
     963             : 
     964         508 : done:
     965         508 :         TALLOC_FREE(sam_pass);
     966         508 :         return result;
     967             : }
     968             : 
     969             : /**********************************************************************
     970             :  Marshall/unmarshall struct samu structs.
     971             :  *********************************************************************/
     972             : 
     973             : #define SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
     974             : #define SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
     975             : #define SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
     976             : #define SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd"
     977             : /* nothing changed between V3 and V4 */
     978             : 
     979             : /*********************************************************************
     980             : *********************************************************************/
     981             : 
     982           0 : static bool init_samu_from_buffer_v0(struct samu *sampass, uint8_t *buf, uint32_t buflen)
     983             : {
     984             : 
     985             :         /* times are stored as 32bit integer
     986             :            take care on system with 64bit wide time_t
     987             :            --SSS */
     988           0 :         uint32_t        logon_time,
     989             :                 logoff_time,
     990             :                 kickoff_time,
     991             :                 pass_last_set_time,
     992             :                 pass_can_change_time,
     993             :                 pass_must_change_time;
     994           0 :         char *username = NULL;
     995           0 :         char *domain = NULL;
     996           0 :         char *nt_username = NULL;
     997           0 :         char *dir_drive = NULL;
     998           0 :         char *unknown_str = NULL;
     999           0 :         char *munged_dial = NULL;
    1000           0 :         char *fullname = NULL;
    1001           0 :         char *homedir = NULL;
    1002           0 :         char *logon_script = NULL;
    1003           0 :         char *profile_path = NULL;
    1004           0 :         char *acct_desc = NULL;
    1005           0 :         char *workstations = NULL;
    1006           0 :         uint32_t        username_len, domain_len, nt_username_len,
    1007             :                 dir_drive_len, unknown_str_len, munged_dial_len,
    1008             :                 fullname_len, homedir_len, logon_script_len,
    1009             :                 profile_path_len, acct_desc_len, workstations_len;
    1010             : 
    1011           0 :         uint32_t        user_rid, group_rid, remove_me, hours_len, unknown_6;
    1012           0 :         uint16_t        acct_ctrl, logon_divs;
    1013           0 :         uint16_t        bad_password_count, logon_count;
    1014           0 :         uint8_t *hours = NULL;
    1015           0 :         uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
    1016           0 :         uint32_t                len = 0;
    1017           0 :         uint32_t                lm_pw_len, nt_pw_len, hourslen;
    1018           0 :         bool ret = True;
    1019             : 
    1020           0 :         if(sampass == NULL || buf == NULL) {
    1021           0 :                 DEBUG(0, ("init_samu_from_buffer_v0: NULL parameters found!\n"));
    1022           0 :                 return False;
    1023             :         }
    1024             : 
    1025             : /* SAMU_BUFFER_FORMAT_V0       "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
    1026             : 
    1027             :         /* unpack the buffer into variables */
    1028           0 :         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V0,
    1029             :                 &logon_time,                                                /* d */
    1030             :                 &logoff_time,                                               /* d */
    1031             :                 &kickoff_time,                                              /* d */
    1032             :                 &pass_last_set_time,                                        /* d */
    1033             :                 &pass_can_change_time,                                      /* d */
    1034             :                 &pass_must_change_time,                                     /* d */
    1035             :                 &username_len, &username,                               /* B */
    1036             :                 &domain_len, &domain,                                   /* B */
    1037             :                 &nt_username_len, &nt_username,                         /* B */
    1038             :                 &fullname_len, &fullname,                               /* B */
    1039             :                 &homedir_len, &homedir,                                 /* B */
    1040             :                 &dir_drive_len, &dir_drive,                             /* B */
    1041             :                 &logon_script_len, &logon_script,                       /* B */
    1042             :                 &profile_path_len, &profile_path,                       /* B */
    1043             :                 &acct_desc_len, &acct_desc,                             /* B */
    1044             :                 &workstations_len, &workstations,                       /* B */
    1045             :                 &unknown_str_len, &unknown_str,                         /* B */
    1046             :                 &munged_dial_len, &munged_dial,                         /* B */
    1047             :                 &user_rid,                                          /* d */
    1048             :                 &group_rid,                                         /* d */
    1049             :                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
    1050             :                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
    1051             :                 &acct_ctrl,                                         /* w */
    1052             :                 &remove_me, /* remove on the next TDB_FORMAT upgrade */     /* d */
    1053             :                 &logon_divs,                                                /* w */
    1054             :                 &hours_len,                                         /* d */
    1055             :                 &hourslen, &hours,                                      /* B */
    1056             :                 &bad_password_count,                                        /* w */
    1057             :                 &logon_count,                                               /* w */
    1058             :                 &unknown_6);                                                /* d */
    1059             : 
    1060           0 :         if (len == (uint32_t) -1)  {
    1061           0 :                 ret = False;
    1062           0 :                 goto done;
    1063             :         }
    1064             : 
    1065           0 :         pdb_set_logon_time(sampass, logon_time, PDB_SET);
    1066           0 :         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
    1067           0 :         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
    1068           0 :         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
    1069           0 :         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
    1070             : 
    1071           0 :         pdb_set_username(sampass, username, PDB_SET);
    1072           0 :         pdb_set_domain(sampass, domain, PDB_SET);
    1073           0 :         pdb_set_nt_username(sampass, nt_username, PDB_SET);
    1074           0 :         pdb_set_fullname(sampass, fullname, PDB_SET);
    1075             : 
    1076           0 :         if (homedir) {
    1077           0 :                 pdb_set_homedir(sampass, homedir, PDB_SET);
    1078             :         }
    1079             :         else {
    1080           0 :                 pdb_set_homedir(sampass,
    1081           0 :                         talloc_sub_basic(sampass, username, domain,
    1082             :                                          lp_logon_home()),
    1083             :                         PDB_DEFAULT);
    1084             :         }
    1085             : 
    1086           0 :         if (dir_drive)
    1087           0 :                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
    1088             :         else {
    1089           0 :                 pdb_set_dir_drive(sampass,
    1090           0 :                         talloc_sub_basic(sampass, username, domain,
    1091             :                                          lp_logon_drive()),
    1092             :                         PDB_DEFAULT);
    1093             :         }
    1094             : 
    1095           0 :         if (logon_script)
    1096           0 :                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
    1097             :         else {
    1098           0 :                 pdb_set_logon_script(sampass,
    1099           0 :                         talloc_sub_basic(sampass, username, domain,
    1100             :                                          lp_logon_script()),
    1101             :                         PDB_DEFAULT);
    1102             :         }
    1103             : 
    1104           0 :         if (profile_path) {
    1105           0 :                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
    1106             :         } else {
    1107           0 :                 pdb_set_profile_path(sampass,
    1108           0 :                         talloc_sub_basic(sampass, username, domain,
    1109             :                                          lp_logon_path()),
    1110             :                         PDB_DEFAULT);
    1111             :         }
    1112             : 
    1113           0 :         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
    1114           0 :         pdb_set_workstations(sampass, workstations, PDB_SET);
    1115           0 :         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
    1116             : 
    1117           0 :         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
    1118           0 :                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
    1119           0 :                         ret = False;
    1120           0 :                         goto done;
    1121             :                 }
    1122             :         }
    1123             : 
    1124           0 :         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
    1125           0 :                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
    1126           0 :                         ret = False;
    1127           0 :                         goto done;
    1128             :                 }
    1129             :         }
    1130             : 
    1131           0 :         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
    1132           0 :         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
    1133           0 :         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
    1134           0 :         pdb_set_hours_len(sampass, hours_len, PDB_SET);
    1135           0 :         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
    1136           0 :         pdb_set_logon_count(sampass, logon_count, PDB_SET);
    1137           0 :         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
    1138           0 :         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
    1139           0 :         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
    1140           0 :         pdb_set_hours(sampass, hours, hours_len, PDB_SET);
    1141             : 
    1142           0 : done:
    1143             : 
    1144           0 :         SAFE_FREE(username);
    1145           0 :         SAFE_FREE(domain);
    1146           0 :         SAFE_FREE(nt_username);
    1147           0 :         SAFE_FREE(fullname);
    1148           0 :         SAFE_FREE(homedir);
    1149           0 :         SAFE_FREE(dir_drive);
    1150           0 :         SAFE_FREE(logon_script);
    1151           0 :         SAFE_FREE(profile_path);
    1152           0 :         SAFE_FREE(acct_desc);
    1153           0 :         SAFE_FREE(workstations);
    1154           0 :         SAFE_FREE(munged_dial);
    1155           0 :         SAFE_FREE(unknown_str);
    1156           0 :         SAFE_FREE(lm_pw_ptr);
    1157           0 :         SAFE_FREE(nt_pw_ptr);
    1158           0 :         SAFE_FREE(hours);
    1159             : 
    1160           0 :         return ret;
    1161             : }
    1162             : 
    1163             : /*********************************************************************
    1164             : *********************************************************************/
    1165             : 
    1166           0 : static bool init_samu_from_buffer_v1(struct samu *sampass, uint8_t *buf, uint32_t buflen)
    1167             : {
    1168             : 
    1169             :         /* times are stored as 32bit integer
    1170             :            take care on system with 64bit wide time_t
    1171             :            --SSS */
    1172           0 :         uint32_t        logon_time,
    1173             :                 logoff_time,
    1174             :                 kickoff_time,
    1175             :                 bad_password_time,
    1176             :                 pass_last_set_time,
    1177             :                 pass_can_change_time,
    1178             :                 pass_must_change_time;
    1179           0 :         char *username = NULL;
    1180           0 :         char *domain = NULL;
    1181           0 :         char *nt_username = NULL;
    1182           0 :         char *dir_drive = NULL;
    1183           0 :         char *unknown_str = NULL;
    1184           0 :         char *munged_dial = NULL;
    1185           0 :         char *fullname = NULL;
    1186           0 :         char *homedir = NULL;
    1187           0 :         char *logon_script = NULL;
    1188           0 :         char *profile_path = NULL;
    1189           0 :         char *acct_desc = NULL;
    1190           0 :         char *workstations = NULL;
    1191           0 :         uint32_t        username_len, domain_len, nt_username_len,
    1192             :                 dir_drive_len, unknown_str_len, munged_dial_len,
    1193             :                 fullname_len, homedir_len, logon_script_len,
    1194             :                 profile_path_len, acct_desc_len, workstations_len;
    1195             : 
    1196           0 :         uint32_t        user_rid, group_rid, remove_me, hours_len, unknown_6;
    1197           0 :         uint16_t        acct_ctrl, logon_divs;
    1198           0 :         uint16_t        bad_password_count, logon_count;
    1199           0 :         uint8_t *hours = NULL;
    1200           0 :         uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL;
    1201           0 :         uint32_t                len = 0;
    1202           0 :         uint32_t                lm_pw_len, nt_pw_len, hourslen;
    1203           0 :         bool ret = True;
    1204             : 
    1205           0 :         if(sampass == NULL || buf == NULL) {
    1206           0 :                 DEBUG(0, ("init_samu_from_buffer_v1: NULL parameters found!\n"));
    1207           0 :                 return False;
    1208             :         }
    1209             : 
    1210             : /* SAMU_BUFFER_FORMAT_V1       "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
    1211             : 
    1212             :         /* unpack the buffer into variables */
    1213           0 :         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V1,
    1214             :                 &logon_time,                                                /* d */
    1215             :                 &logoff_time,                                               /* d */
    1216             :                 &kickoff_time,                                              /* d */
    1217             :                 /* Change from V0 is addition of bad_password_time field. */
    1218             :                 &bad_password_time,                                 /* d */
    1219             :                 &pass_last_set_time,                                        /* d */
    1220             :                 &pass_can_change_time,                                      /* d */
    1221             :                 &pass_must_change_time,                                     /* d */
    1222             :                 &username_len, &username,                               /* B */
    1223             :                 &domain_len, &domain,                                   /* B */
    1224             :                 &nt_username_len, &nt_username,                         /* B */
    1225             :                 &fullname_len, &fullname,                               /* B */
    1226             :                 &homedir_len, &homedir,                                 /* B */
    1227             :                 &dir_drive_len, &dir_drive,                             /* B */
    1228             :                 &logon_script_len, &logon_script,                       /* B */
    1229             :                 &profile_path_len, &profile_path,                       /* B */
    1230             :                 &acct_desc_len, &acct_desc,                             /* B */
    1231             :                 &workstations_len, &workstations,                       /* B */
    1232             :                 &unknown_str_len, &unknown_str,                         /* B */
    1233             :                 &munged_dial_len, &munged_dial,                         /* B */
    1234             :                 &user_rid,                                          /* d */
    1235             :                 &group_rid,                                         /* d */
    1236             :                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
    1237             :                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
    1238             :                 &acct_ctrl,                                         /* w */
    1239             :                 &remove_me,                                         /* d */
    1240             :                 &logon_divs,                                                /* w */
    1241             :                 &hours_len,                                         /* d */
    1242             :                 &hourslen, &hours,                                      /* B */
    1243             :                 &bad_password_count,                                        /* w */
    1244             :                 &logon_count,                                               /* w */
    1245             :                 &unknown_6);                                                /* d */
    1246             : 
    1247           0 :         if (len == (uint32_t) -1)  {
    1248           0 :                 ret = False;
    1249           0 :                 goto done;
    1250             :         }
    1251             : 
    1252           0 :         pdb_set_logon_time(sampass, logon_time, PDB_SET);
    1253           0 :         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
    1254           0 :         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
    1255             : 
    1256             :         /* Change from V0 is addition of bad_password_time field. */
    1257           0 :         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
    1258           0 :         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
    1259           0 :         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
    1260             : 
    1261           0 :         pdb_set_username(sampass, username, PDB_SET);
    1262           0 :         pdb_set_domain(sampass, domain, PDB_SET);
    1263           0 :         pdb_set_nt_username(sampass, nt_username, PDB_SET);
    1264           0 :         pdb_set_fullname(sampass, fullname, PDB_SET);
    1265             : 
    1266           0 :         if (homedir) {
    1267           0 :                 pdb_set_homedir(sampass, homedir, PDB_SET);
    1268             :         }
    1269             :         else {
    1270           0 :                 pdb_set_homedir(sampass,
    1271           0 :                         talloc_sub_basic(sampass, username, domain,
    1272             :                                          lp_logon_home()),
    1273             :                         PDB_DEFAULT);
    1274             :         }
    1275             : 
    1276           0 :         if (dir_drive)
    1277           0 :                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
    1278             :         else {
    1279           0 :                 pdb_set_dir_drive(sampass,
    1280           0 :                         talloc_sub_basic(sampass, username, domain,
    1281             :                                          lp_logon_drive()),
    1282             :                         PDB_DEFAULT);
    1283             :         }
    1284             : 
    1285           0 :         if (logon_script)
    1286           0 :                 pdb_set_logon_script(sampass, logon_script, PDB_SET);
    1287             :         else {
    1288           0 :                 pdb_set_logon_script(sampass,
    1289           0 :                         talloc_sub_basic(sampass, username, domain,
    1290             :                                          lp_logon_script()),
    1291             :                         PDB_DEFAULT);
    1292             :         }
    1293             : 
    1294           0 :         if (profile_path) {
    1295           0 :                 pdb_set_profile_path(sampass, profile_path, PDB_SET);
    1296             :         } else {
    1297           0 :                 pdb_set_profile_path(sampass,
    1298           0 :                         talloc_sub_basic(sampass, username, domain,
    1299             :                                          lp_logon_path()),
    1300             :                         PDB_DEFAULT);
    1301             :         }
    1302             : 
    1303           0 :         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
    1304           0 :         pdb_set_workstations(sampass, workstations, PDB_SET);
    1305           0 :         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
    1306             : 
    1307           0 :         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
    1308           0 :                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
    1309           0 :                         ret = False;
    1310           0 :                         goto done;
    1311             :                 }
    1312             :         }
    1313             : 
    1314           0 :         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
    1315           0 :                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
    1316           0 :                         ret = False;
    1317           0 :                         goto done;
    1318             :                 }
    1319             :         }
    1320             : 
    1321           0 :         pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
    1322             : 
    1323           0 :         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
    1324           0 :         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
    1325           0 :         pdb_set_hours_len(sampass, hours_len, PDB_SET);
    1326           0 :         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
    1327           0 :         pdb_set_logon_count(sampass, logon_count, PDB_SET);
    1328           0 :         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
    1329           0 :         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
    1330           0 :         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
    1331           0 :         pdb_set_hours(sampass, hours, hours_len, PDB_SET);
    1332             : 
    1333           0 : done:
    1334             : 
    1335           0 :         SAFE_FREE(username);
    1336           0 :         SAFE_FREE(domain);
    1337           0 :         SAFE_FREE(nt_username);
    1338           0 :         SAFE_FREE(fullname);
    1339           0 :         SAFE_FREE(homedir);
    1340           0 :         SAFE_FREE(dir_drive);
    1341           0 :         SAFE_FREE(logon_script);
    1342           0 :         SAFE_FREE(profile_path);
    1343           0 :         SAFE_FREE(acct_desc);
    1344           0 :         SAFE_FREE(workstations);
    1345           0 :         SAFE_FREE(munged_dial);
    1346           0 :         SAFE_FREE(unknown_str);
    1347           0 :         SAFE_FREE(lm_pw_ptr);
    1348           0 :         SAFE_FREE(nt_pw_ptr);
    1349           0 :         SAFE_FREE(hours);
    1350             : 
    1351           0 :         return ret;
    1352             : }
    1353             : 
    1354           6 : static bool init_samu_from_buffer_v2(struct samu *sampass, uint8_t *buf, uint32_t buflen)
    1355             : {
    1356             : 
    1357             :         /* times are stored as 32bit integer
    1358             :            take care on system with 64bit wide time_t
    1359             :            --SSS */
    1360           6 :         uint32_t        logon_time,
    1361             :                 logoff_time,
    1362             :                 kickoff_time,
    1363             :                 bad_password_time,
    1364             :                 pass_last_set_time,
    1365             :                 pass_can_change_time,
    1366             :                 pass_must_change_time;
    1367           6 :         char *username = NULL;
    1368           6 :         char *domain = NULL;
    1369           6 :         char *nt_username = NULL;
    1370           6 :         char *dir_drive = NULL;
    1371           6 :         char *unknown_str = NULL;
    1372           6 :         char *munged_dial = NULL;
    1373           6 :         char *fullname = NULL;
    1374           6 :         char *homedir = NULL;
    1375           6 :         char *logon_script = NULL;
    1376           6 :         char *profile_path = NULL;
    1377           6 :         char *acct_desc = NULL;
    1378           6 :         char *workstations = NULL;
    1379           6 :         uint32_t        username_len, domain_len, nt_username_len,
    1380             :                 dir_drive_len, unknown_str_len, munged_dial_len,
    1381             :                 fullname_len, homedir_len, logon_script_len,
    1382             :                 profile_path_len, acct_desc_len, workstations_len;
    1383             : 
    1384           6 :         uint32_t        user_rid, group_rid, hours_len, unknown_6;
    1385           6 :         uint16_t        acct_ctrl, logon_divs;
    1386           6 :         uint16_t        bad_password_count, logon_count;
    1387           6 :         uint8_t *hours = NULL;
    1388           6 :         uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
    1389           6 :         uint32_t                len = 0;
    1390           6 :         uint32_t                lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
    1391           6 :         uint32_t pwHistLen = 0;
    1392           6 :         bool ret = True;
    1393           6 :         fstring tmp_string;
    1394           6 :         bool expand_explicit = lp_passdb_expand_explicit();
    1395             : 
    1396           6 :         if(sampass == NULL || buf == NULL) {
    1397           0 :                 DEBUG(0, ("init_samu_from_buffer_v2: NULL parameters found!\n"));
    1398           0 :                 return False;
    1399             :         }
    1400             : 
    1401             : /* SAMU_BUFFER_FORMAT_V2       "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
    1402             : 
    1403             :         /* unpack the buffer into variables */
    1404           6 :         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V2,
    1405             :                 &logon_time,                                                /* d */
    1406             :                 &logoff_time,                                               /* d */
    1407             :                 &kickoff_time,                                              /* d */
    1408             :                 &bad_password_time,                                 /* d */
    1409             :                 &pass_last_set_time,                                        /* d */
    1410             :                 &pass_can_change_time,                                      /* d */
    1411             :                 &pass_must_change_time,                                     /* d */
    1412             :                 &username_len, &username,                               /* B */
    1413             :                 &domain_len, &domain,                                   /* B */
    1414             :                 &nt_username_len, &nt_username,                         /* B */
    1415             :                 &fullname_len, &fullname,                               /* B */
    1416             :                 &homedir_len, &homedir,                                 /* B */
    1417             :                 &dir_drive_len, &dir_drive,                             /* B */
    1418             :                 &logon_script_len, &logon_script,                       /* B */
    1419             :                 &profile_path_len, &profile_path,                       /* B */
    1420             :                 &acct_desc_len, &acct_desc,                             /* B */
    1421             :                 &workstations_len, &workstations,                       /* B */
    1422             :                 &unknown_str_len, &unknown_str,                         /* B */
    1423             :                 &munged_dial_len, &munged_dial,                         /* B */
    1424             :                 &user_rid,                                          /* d */
    1425             :                 &group_rid,                                         /* d */
    1426             :                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
    1427             :                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
    1428             :                 /* Change from V1 is addition of password history field. */
    1429             :                 &nt_pw_hist_len, &nt_pw_hist_ptr,                       /* B */
    1430             :                 &acct_ctrl,                                         /* w */
    1431             :                 /* Also "remove_me" field was removed. */
    1432             :                 &logon_divs,                                                /* w */
    1433             :                 &hours_len,                                         /* d */
    1434             :                 &hourslen, &hours,                                      /* B */
    1435             :                 &bad_password_count,                                        /* w */
    1436             :                 &logon_count,                                               /* w */
    1437             :                 &unknown_6);                                                /* d */
    1438             : 
    1439           6 :         if (len == (uint32_t) -1)  {
    1440           0 :                 ret = False;
    1441           0 :                 goto done;
    1442             :         }
    1443             : 
    1444           6 :         pdb_set_logon_time(sampass, logon_time, PDB_SET);
    1445           6 :         pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
    1446           6 :         pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
    1447           6 :         pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
    1448           6 :         pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
    1449           6 :         pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
    1450             : 
    1451           6 :         pdb_set_username(sampass, username, PDB_SET);
    1452           6 :         pdb_set_domain(sampass, domain, PDB_SET);
    1453           6 :         pdb_set_nt_username(sampass, nt_username, PDB_SET);
    1454           6 :         pdb_set_fullname(sampass, fullname, PDB_SET);
    1455             : 
    1456           6 :         if (homedir) {
    1457           0 :                 fstrcpy( tmp_string, homedir );
    1458           0 :                 if (expand_explicit) {
    1459           0 :                         standard_sub_basic( username, domain, tmp_string,
    1460             :                                             sizeof(tmp_string) );
    1461             :                 }
    1462           0 :                 pdb_set_homedir(sampass, tmp_string, PDB_SET);
    1463             :         }
    1464             :         else {
    1465           6 :                 pdb_set_homedir(sampass,
    1466           6 :                         talloc_sub_basic(sampass, username, domain,
    1467             :                                          lp_logon_home()),
    1468             :                         PDB_DEFAULT);
    1469             :         }
    1470             : 
    1471           6 :         if (dir_drive)
    1472           0 :                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
    1473             :         else
    1474           6 :                 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
    1475             : 
    1476           6 :         if (logon_script) {
    1477           0 :                 fstrcpy( tmp_string, logon_script );
    1478           0 :                 if (expand_explicit) {
    1479           0 :                         standard_sub_basic( username, domain, tmp_string,
    1480             :                                             sizeof(tmp_string) );
    1481             :                 }
    1482           0 :                 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
    1483             :         }
    1484             :         else {
    1485           6 :                 pdb_set_logon_script(sampass,
    1486           6 :                         talloc_sub_basic(sampass, username, domain,
    1487             :                                          lp_logon_script()),
    1488             :                         PDB_DEFAULT);
    1489             :         }
    1490             : 
    1491           6 :         if (profile_path) {
    1492           0 :                 fstrcpy( tmp_string, profile_path );
    1493           0 :                 if (expand_explicit) {
    1494           0 :                         standard_sub_basic( username, domain, tmp_string,
    1495             :                                             sizeof(tmp_string) );
    1496             :                 }
    1497           0 :                 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
    1498             :         }
    1499             :         else {
    1500           6 :                 pdb_set_profile_path(sampass,
    1501           6 :                         talloc_sub_basic(sampass, username, domain,
    1502             :                                          lp_logon_path()),
    1503             :                         PDB_DEFAULT);
    1504             :         }
    1505             : 
    1506           6 :         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
    1507           6 :         pdb_set_workstations(sampass, workstations, PDB_SET);
    1508           6 :         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
    1509             : 
    1510           6 :         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
    1511           6 :                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
    1512           0 :                         ret = False;
    1513           0 :                         goto done;
    1514             :                 }
    1515             :         }
    1516             : 
    1517           6 :         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
    1518           6 :                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
    1519           0 :                         ret = False;
    1520           0 :                         goto done;
    1521             :                 }
    1522             :         }
    1523             : 
    1524             :         /* Change from V1 is addition of password history field. */
    1525           6 :         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
    1526           6 :         if (pwHistLen) {
    1527           0 :                 uint8_t *pw_hist = SMB_MALLOC_ARRAY(uint8_t, pwHistLen * PW_HISTORY_ENTRY_LEN);
    1528           0 :                 if (!pw_hist) {
    1529           0 :                         ret = False;
    1530           0 :                         goto done;
    1531             :                 }
    1532           0 :                 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
    1533           0 :                 if (nt_pw_hist_ptr && nt_pw_hist_len) {
    1534           0 :                         int i;
    1535           0 :                         SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
    1536           0 :                         nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
    1537           0 :                         for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
    1538           0 :                                 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
    1539           0 :                                         &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
    1540             :                                         PW_HISTORY_ENTRY_LEN);
    1541             :                         }
    1542             :                 }
    1543           0 :                 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
    1544           0 :                         SAFE_FREE(pw_hist);
    1545           0 :                         ret = False;
    1546           0 :                         goto done;
    1547             :                 }
    1548           0 :                 SAFE_FREE(pw_hist);
    1549             :         } else {
    1550           6 :                 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
    1551             :         }
    1552             : 
    1553           6 :         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
    1554           6 :         pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
    1555           6 :         pdb_set_hours_len(sampass, hours_len, PDB_SET);
    1556           6 :         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
    1557           6 :         pdb_set_logon_count(sampass, logon_count, PDB_SET);
    1558           6 :         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
    1559           6 :         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
    1560           6 :         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
    1561           6 :         pdb_set_hours(sampass, hours, hours_len, PDB_SET);
    1562             : 
    1563           6 : done:
    1564             : 
    1565           6 :         SAFE_FREE(username);
    1566           6 :         SAFE_FREE(domain);
    1567           6 :         SAFE_FREE(nt_username);
    1568           6 :         SAFE_FREE(fullname);
    1569           6 :         SAFE_FREE(homedir);
    1570           6 :         SAFE_FREE(dir_drive);
    1571           6 :         SAFE_FREE(logon_script);
    1572           6 :         SAFE_FREE(profile_path);
    1573           6 :         SAFE_FREE(acct_desc);
    1574           6 :         SAFE_FREE(workstations);
    1575           6 :         SAFE_FREE(munged_dial);
    1576           6 :         SAFE_FREE(unknown_str);
    1577           6 :         SAFE_FREE(lm_pw_ptr);
    1578           6 :         SAFE_FREE(nt_pw_ptr);
    1579           6 :         SAFE_FREE(nt_pw_hist_ptr);
    1580           6 :         SAFE_FREE(hours);
    1581             : 
    1582           0 :         return ret;
    1583             : }
    1584             : 
    1585             : /*********************************************************************
    1586             : *********************************************************************/
    1587             : 
    1588       93984 : static bool init_samu_from_buffer_v3(struct samu *sampass, uint8_t *buf, uint32_t buflen)
    1589             : {
    1590             : 
    1591             :         /* times are stored as 32bit integer
    1592             :            take care on system with 64bit wide time_t
    1593             :            --SSS */
    1594          34 :         uint32_t        logon_time,
    1595             :                 logoff_time,
    1596             :                 kickoff_time,
    1597             :                 bad_password_time,
    1598             :                 pass_last_set_time,
    1599             :                 pass_can_change_time,
    1600             :                 pass_must_change_time;
    1601       93984 :         char *username = NULL;
    1602       93984 :         char *domain = NULL;
    1603       93984 :         char *nt_username = NULL;
    1604       93984 :         char *dir_drive = NULL;
    1605       93984 :         char *comment = NULL;
    1606       93984 :         char *munged_dial = NULL;
    1607       93984 :         char *fullname = NULL;
    1608       93984 :         char *homedir = NULL;
    1609       93984 :         char *logon_script = NULL;
    1610       93984 :         char *profile_path = NULL;
    1611       93984 :         char *acct_desc = NULL;
    1612       93984 :         char *workstations = NULL;
    1613          34 :         uint32_t        username_len, domain_len, nt_username_len,
    1614             :                 dir_drive_len, comment_len, munged_dial_len,
    1615             :                 fullname_len, homedir_len, logon_script_len,
    1616             :                 profile_path_len, acct_desc_len, workstations_len;
    1617             : 
    1618          34 :         uint32_t        user_rid, group_rid, hours_len, unknown_6, acct_ctrl;
    1619          34 :         uint16_t  logon_divs;
    1620          34 :         uint16_t        bad_password_count, logon_count;
    1621       93984 :         uint8_t *hours = NULL;
    1622       93984 :         uint8_t *lm_pw_ptr = NULL, *nt_pw_ptr = NULL, *nt_pw_hist_ptr = NULL;
    1623       93984 :         uint32_t                len = 0;
    1624          34 :         uint32_t                lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
    1625       93984 :         uint32_t pwHistLen = 0;
    1626       93984 :         bool ret = True;
    1627          34 :         fstring tmp_string;
    1628       93984 :         bool expand_explicit = lp_passdb_expand_explicit();
    1629             : 
    1630       93984 :         if(sampass == NULL || buf == NULL) {
    1631           0 :                 DEBUG(0, ("init_samu_from_buffer_v3: NULL parameters found!\n"));
    1632           0 :                 return False;
    1633             :         }
    1634             : 
    1635             : /* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
    1636             : 
    1637             :         /* unpack the buffer into variables */
    1638       93984 :         len = tdb_unpack (buf, buflen, SAMU_BUFFER_FORMAT_V3,
    1639             :                 &logon_time,                                                /* d */
    1640             :                 &logoff_time,                                               /* d */
    1641             :                 &kickoff_time,                                              /* d */
    1642             :                 &bad_password_time,                                 /* d */
    1643             :                 &pass_last_set_time,                                        /* d */
    1644             :                 &pass_can_change_time,                                      /* d */
    1645             :                 &pass_must_change_time,                                     /* d */
    1646             :                 &username_len, &username,                               /* B */
    1647             :                 &domain_len, &domain,                                   /* B */
    1648             :                 &nt_username_len, &nt_username,                         /* B */
    1649             :                 &fullname_len, &fullname,                               /* B */
    1650             :                 &homedir_len, &homedir,                                 /* B */
    1651             :                 &dir_drive_len, &dir_drive,                             /* B */
    1652             :                 &logon_script_len, &logon_script,                       /* B */
    1653             :                 &profile_path_len, &profile_path,                       /* B */
    1654             :                 &acct_desc_len, &acct_desc,                             /* B */
    1655             :                 &workstations_len, &workstations,                       /* B */
    1656             :                 &comment_len, &comment,                                 /* B */
    1657             :                 &munged_dial_len, &munged_dial,                         /* B */
    1658             :                 &user_rid,                                          /* d */
    1659             :                 &group_rid,                                         /* d */
    1660             :                 &lm_pw_len, &lm_pw_ptr,                                 /* B */
    1661             :                 &nt_pw_len, &nt_pw_ptr,                                 /* B */
    1662             :                 /* Change from V1 is addition of password history field. */
    1663             :                 &nt_pw_hist_len, &nt_pw_hist_ptr,                       /* B */
    1664             :                 /* Change from V2 is the uint32_t acb_mask */
    1665             :                 &acct_ctrl,                                         /* d */
    1666             :                 /* Also "remove_me" field was removed. */
    1667             :                 &logon_divs,                                                /* w */
    1668             :                 &hours_len,                                         /* d */
    1669             :                 &hourslen, &hours,                                      /* B */
    1670             :                 &bad_password_count,                                        /* w */
    1671             :                 &logon_count,                                               /* w */
    1672             :                 &unknown_6);                                                /* d */
    1673             : 
    1674       93984 :         if (len == (uint32_t) -1)  {
    1675           0 :                 ret = False;
    1676           0 :                 goto done;
    1677             :         }
    1678             : 
    1679       93984 :         pdb_set_logon_time(sampass, convert_uint32_t_to_time_t(logon_time), PDB_SET);
    1680       93984 :         pdb_set_logoff_time(sampass, convert_uint32_t_to_time_t(logoff_time), PDB_SET);
    1681       93984 :         pdb_set_kickoff_time(sampass, convert_uint32_t_to_time_t(kickoff_time), PDB_SET);
    1682       93984 :         pdb_set_bad_password_time(sampass, convert_uint32_t_to_time_t(bad_password_time), PDB_SET);
    1683       93984 :         pdb_set_pass_can_change_time(sampass, convert_uint32_t_to_time_t(pass_can_change_time), PDB_SET);
    1684       93984 :         pdb_set_pass_last_set_time(sampass, convert_uint32_t_to_time_t(pass_last_set_time), PDB_SET);
    1685             : 
    1686       93984 :         pdb_set_username(sampass, username, PDB_SET);
    1687       93984 :         pdb_set_domain(sampass, domain, PDB_SET);
    1688       93984 :         pdb_set_nt_username(sampass, nt_username, PDB_SET);
    1689       93984 :         pdb_set_fullname(sampass, fullname, PDB_SET);
    1690             : 
    1691       93984 :         if (homedir) {
    1692          20 :                 fstrcpy( tmp_string, homedir );
    1693          20 :                 if (expand_explicit) {
    1694           0 :                         standard_sub_basic( username, domain, tmp_string,
    1695             :                                             sizeof(tmp_string) );
    1696             :                 }
    1697          20 :                 pdb_set_homedir(sampass, tmp_string, PDB_SET);
    1698             :         }
    1699             :         else {
    1700       93964 :                 pdb_set_homedir(sampass,
    1701       93964 :                         talloc_sub_basic(sampass, username, domain,
    1702             :                                          lp_logon_home()),
    1703             :                         PDB_DEFAULT);
    1704             :         }
    1705             : 
    1706       93984 :         if (dir_drive)
    1707         105 :                 pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
    1708             :         else
    1709       93879 :                 pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
    1710             : 
    1711       93984 :         if (logon_script) {
    1712          20 :                 fstrcpy( tmp_string, logon_script );
    1713          20 :                 if (expand_explicit) {
    1714           0 :                         standard_sub_basic( username, domain, tmp_string,
    1715             :                                             sizeof(tmp_string) );
    1716             :                 }
    1717          20 :                 pdb_set_logon_script(sampass, tmp_string, PDB_SET);
    1718             :         }
    1719             :         else {
    1720       93964 :                 pdb_set_logon_script(sampass,
    1721       93964 :                         talloc_sub_basic(sampass, username, domain,
    1722             :                                          lp_logon_script()),
    1723             :                         PDB_DEFAULT);
    1724             :         }
    1725             : 
    1726       93984 :         if (profile_path) {
    1727          20 :                 fstrcpy( tmp_string, profile_path );
    1728          20 :                 if (expand_explicit) {
    1729           0 :                         standard_sub_basic( username, domain, tmp_string,
    1730             :                                             sizeof(tmp_string) );
    1731             :                 }
    1732          20 :                 pdb_set_profile_path(sampass, tmp_string, PDB_SET);
    1733             :         }
    1734             :         else {
    1735       93964 :                 pdb_set_profile_path(sampass,
    1736       93964 :                         talloc_sub_basic(sampass, username, domain, lp_logon_path()),
    1737             :                         PDB_DEFAULT);
    1738             :         }
    1739             : 
    1740       93984 :         pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
    1741       93984 :         pdb_set_comment(sampass, comment, PDB_SET);
    1742       93984 :         pdb_set_workstations(sampass, workstations, PDB_SET);
    1743       93984 :         pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
    1744             : 
    1745       93984 :         if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
    1746       35263 :                 if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
    1747           0 :                         ret = False;
    1748           0 :                         goto done;
    1749             :                 }
    1750             :         }
    1751             : 
    1752       93984 :         if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
    1753       86895 :                 if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
    1754           0 :                         ret = False;
    1755           0 :                         goto done;
    1756             :                 }
    1757             :         }
    1758             : 
    1759       93984 :         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
    1760       93984 :         if (pwHistLen) {
    1761           0 :                 uint8_t *pw_hist = (uint8_t *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
    1762           0 :                 if (!pw_hist) {
    1763           0 :                         ret = False;
    1764           0 :                         goto done;
    1765             :                 }
    1766           0 :                 memset(pw_hist, '\0', pwHistLen * PW_HISTORY_ENTRY_LEN);
    1767           0 :                 if (nt_pw_hist_ptr && nt_pw_hist_len) {
    1768           0 :                         int i;
    1769           0 :                         SMB_ASSERT((nt_pw_hist_len % PW_HISTORY_ENTRY_LEN) == 0);
    1770           0 :                         nt_pw_hist_len /= PW_HISTORY_ENTRY_LEN;
    1771           0 :                         for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
    1772           0 :                                 memcpy(&pw_hist[i*PW_HISTORY_ENTRY_LEN],
    1773           0 :                                         &nt_pw_hist_ptr[i*PW_HISTORY_ENTRY_LEN],
    1774             :                                         PW_HISTORY_ENTRY_LEN);
    1775             :                         }
    1776             :                 }
    1777           0 :                 if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
    1778           0 :                         SAFE_FREE(pw_hist);
    1779           0 :                         ret = False;
    1780           0 :                         goto done;
    1781             :                 }
    1782           0 :                 SAFE_FREE(pw_hist);
    1783             :         } else {
    1784       93984 :                 pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
    1785             :         }
    1786             : 
    1787       93984 :         pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
    1788       93984 :         pdb_set_hours_len(sampass, hours_len, PDB_SET);
    1789       93984 :         pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
    1790       93984 :         pdb_set_logon_count(sampass, logon_count, PDB_SET);
    1791       93984 :         pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
    1792             :         /* Change from V2 is the uint32_t acct_ctrl */
    1793       93984 :         pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
    1794       93984 :         pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
    1795       93984 :         pdb_set_hours(sampass, hours, hours_len, PDB_SET);
    1796             : 
    1797       93984 : done:
    1798             : 
    1799       93984 :         SAFE_FREE(username);
    1800       93984 :         SAFE_FREE(domain);
    1801       93984 :         SAFE_FREE(nt_username);
    1802       93984 :         SAFE_FREE(fullname);
    1803       93984 :         SAFE_FREE(homedir);
    1804       93984 :         SAFE_FREE(dir_drive);
    1805       93984 :         SAFE_FREE(logon_script);
    1806       93984 :         SAFE_FREE(profile_path);
    1807       93984 :         SAFE_FREE(acct_desc);
    1808       93984 :         SAFE_FREE(workstations);
    1809       93984 :         SAFE_FREE(munged_dial);
    1810       93984 :         SAFE_FREE(comment);
    1811       93984 :         SAFE_FREE(lm_pw_ptr);
    1812       93984 :         SAFE_FREE(nt_pw_ptr);
    1813       93984 :         SAFE_FREE(nt_pw_hist_ptr);
    1814       93984 :         SAFE_FREE(hours);
    1815             : 
    1816       93950 :         return ret;
    1817             : }
    1818             : 
    1819             : /*********************************************************************
    1820             : *********************************************************************/
    1821             : 
    1822       44418 : static uint32_t init_buffer_from_samu_v3 (uint8_t **buf, struct samu *sampass, bool size_only)
    1823             : {
    1824           6 :         size_t len, buflen;
    1825             : 
    1826             :         /* times are stored as 32bit integer
    1827             :            take care on system with 64bit wide time_t
    1828             :            --SSS */
    1829           6 :         uint32_t        logon_time,
    1830             :                 logoff_time,
    1831             :                 kickoff_time,
    1832             :                 bad_password_time,
    1833             :                 pass_last_set_time,
    1834             :                 pass_can_change_time,
    1835             :                 pass_must_change_time;
    1836             : 
    1837           6 :         uint32_t  user_rid, group_rid;
    1838             : 
    1839           6 :         const char *username;
    1840           6 :         const char *domain;
    1841           6 :         const char *nt_username;
    1842           6 :         const char *dir_drive;
    1843           6 :         const char *comment;
    1844           6 :         const char *munged_dial;
    1845           6 :         const char *fullname;
    1846           6 :         const char *homedir;
    1847           6 :         const char *logon_script;
    1848           6 :         const char *profile_path;
    1849           6 :         const char *acct_desc;
    1850           6 :         const char *workstations;
    1851           6 :         uint32_t        username_len, domain_len, nt_username_len,
    1852             :                 dir_drive_len, comment_len, munged_dial_len,
    1853             :                 fullname_len, homedir_len, logon_script_len,
    1854             :                 profile_path_len, acct_desc_len, workstations_len;
    1855             : 
    1856           6 :         const uint8_t *lm_pw;
    1857           6 :         const uint8_t *nt_pw;
    1858           6 :         const uint8_t *nt_pw_hist;
    1859       44418 :         uint32_t        lm_pw_len = 16;
    1860       44418 :         uint32_t        nt_pw_len = 16;
    1861           6 :         uint32_t  nt_pw_hist_len;
    1862       44418 :         uint32_t pwHistLen = 0;
    1863             : 
    1864       44418 :         *buf = NULL;
    1865       44418 :         buflen = 0;
    1866             : 
    1867       44418 :         logon_time = convert_time_t_to_uint32_t(pdb_get_logon_time(sampass));
    1868       44418 :         logoff_time = convert_time_t_to_uint32_t(pdb_get_logoff_time(sampass));
    1869       44418 :         kickoff_time = convert_time_t_to_uint32_t(pdb_get_kickoff_time(sampass));
    1870       44418 :         bad_password_time = convert_time_t_to_uint32_t(pdb_get_bad_password_time(sampass));
    1871       44418 :         pass_can_change_time = convert_time_t_to_uint32_t(pdb_get_pass_can_change_time_noncalc(sampass));
    1872       44418 :         pass_must_change_time = convert_time_t_to_uint32_t(pdb_get_pass_must_change_time(sampass));
    1873       44418 :         pass_last_set_time = convert_time_t_to_uint32_t(pdb_get_pass_last_set_time(sampass));
    1874             : 
    1875       44418 :         user_rid = pdb_get_user_rid(sampass);
    1876       44418 :         group_rid = pdb_get_group_rid(sampass);
    1877             : 
    1878       44418 :         username = pdb_get_username(sampass);
    1879       44418 :         if (username) {
    1880       44418 :                 username_len = strlen(username) +1;
    1881             :         } else {
    1882           0 :                 username_len = 0;
    1883             :         }
    1884             : 
    1885       44418 :         domain = pdb_get_domain(sampass);
    1886       44418 :         if (domain) {
    1887       44418 :                 domain_len = strlen(domain) +1;
    1888             :         } else {
    1889           0 :                 domain_len = 0;
    1890             :         }
    1891             : 
    1892       44418 :         nt_username = pdb_get_nt_username(sampass);
    1893       44418 :         if (nt_username) {
    1894       44418 :                 nt_username_len = strlen(nt_username) +1;
    1895             :         } else {
    1896           0 :                 nt_username_len = 0;
    1897             :         }
    1898             : 
    1899       44418 :         fullname = pdb_get_fullname(sampass);
    1900       44418 :         if (fullname) {
    1901       44418 :                 fullname_len = strlen(fullname) +1;
    1902             :         } else {
    1903           0 :                 fullname_len = 0;
    1904             :         }
    1905             : 
    1906             :         /*
    1907             :          * Only updates fields which have been set (not defaults from smb.conf)
    1908             :          */
    1909             : 
    1910       44418 :         if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
    1911          61 :                 dir_drive = pdb_get_dir_drive(sampass);
    1912             :         } else {
    1913       44351 :                 dir_drive = NULL;
    1914             :         }
    1915       44412 :         if (dir_drive) {
    1916          61 :                 dir_drive_len = strlen(dir_drive) +1;
    1917             :         } else {
    1918       44351 :                 dir_drive_len = 0;
    1919             :         }
    1920             : 
    1921       44418 :         if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
    1922          12 :                 homedir = pdb_get_homedir(sampass);
    1923             :         } else {
    1924       44400 :                 homedir = NULL;
    1925             :         }
    1926       44412 :         if (homedir) {
    1927          12 :                 homedir_len = strlen(homedir) +1;
    1928             :         } else {
    1929       44400 :                 homedir_len = 0;
    1930             :         }
    1931             : 
    1932       44418 :         if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
    1933          12 :                 logon_script = pdb_get_logon_script(sampass);
    1934             :         } else {
    1935       44400 :                 logon_script = NULL;
    1936             :         }
    1937       44412 :         if (logon_script) {
    1938          12 :                 logon_script_len = strlen(logon_script) +1;
    1939             :         } else {
    1940       44400 :                 logon_script_len = 0;
    1941             :         }
    1942             : 
    1943       44418 :         if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
    1944          12 :                 profile_path = pdb_get_profile_path(sampass);
    1945             :         } else {
    1946       44400 :                 profile_path = NULL;
    1947             :         }
    1948       44412 :         if (profile_path) {
    1949          12 :                 profile_path_len = strlen(profile_path) +1;
    1950             :         } else {
    1951       44400 :                 profile_path_len = 0;
    1952             :         }
    1953             : 
    1954       44418 :         lm_pw = pdb_get_lanman_passwd(sampass);
    1955       44418 :         if (!lm_pw) {
    1956       26892 :                 lm_pw_len = 0;
    1957             :         }
    1958             : 
    1959       44418 :         nt_pw = pdb_get_nt_passwd(sampass);
    1960       44418 :         if (!nt_pw) {
    1961        1051 :                 nt_pw_len = 0;
    1962             :         }
    1963             : 
    1964       44418 :         pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
    1965       44418 :         nt_pw_hist =  pdb_get_pw_history(sampass, &nt_pw_hist_len);
    1966       44418 :         if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
    1967           0 :                 nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
    1968             :         } else {
    1969       44418 :                 nt_pw_hist_len = 0;
    1970             :         }
    1971             : 
    1972       44418 :         acct_desc = pdb_get_acct_desc(sampass);
    1973       44418 :         if (acct_desc) {
    1974       44418 :                 acct_desc_len = strlen(acct_desc) +1;
    1975             :         } else {
    1976           0 :                 acct_desc_len = 0;
    1977             :         }
    1978             : 
    1979       44418 :         workstations = pdb_get_workstations(sampass);
    1980       44418 :         if (workstations) {
    1981       44418 :                 workstations_len = strlen(workstations) +1;
    1982             :         } else {
    1983           0 :                 workstations_len = 0;
    1984             :         }
    1985             : 
    1986       44418 :         comment = pdb_get_comment(sampass);
    1987       44418 :         if (comment) {
    1988       44418 :                 comment_len = strlen(comment) +1;
    1989             :         } else {
    1990           0 :                 comment_len = 0;
    1991             :         }
    1992             : 
    1993       44418 :         munged_dial = pdb_get_munged_dial(sampass);
    1994       44418 :         if (munged_dial) {
    1995       44418 :                 munged_dial_len = strlen(munged_dial) +1;
    1996             :         } else {
    1997           0 :                 munged_dial_len = 0;
    1998             :         }
    1999             : 
    2000             : /* SAMU_BUFFER_FORMAT_V3       "dddddddBBBBBBBBBBBBddBBBdwdBwwd" */
    2001             : 
    2002             :         /* one time to get the size needed */
    2003      133254 :         len = tdb_pack(NULL, 0,  SAMU_BUFFER_FORMAT_V3,
    2004             :                 logon_time,                             /* d */
    2005             :                 logoff_time,                            /* d */
    2006             :                 kickoff_time,                           /* d */
    2007             :                 bad_password_time,                      /* d */
    2008             :                 pass_last_set_time,                     /* d */
    2009             :                 pass_can_change_time,                   /* d */
    2010             :                 pass_must_change_time,                  /* d */
    2011             :                 username_len, username,                 /* B */
    2012             :                 domain_len, domain,                     /* B */
    2013             :                 nt_username_len, nt_username,           /* B */
    2014             :                 fullname_len, fullname,                 /* B */
    2015             :                 homedir_len, homedir,                   /* B */
    2016             :                 dir_drive_len, dir_drive,               /* B */
    2017             :                 logon_script_len, logon_script,         /* B */
    2018             :                 profile_path_len, profile_path,         /* B */
    2019             :                 acct_desc_len, acct_desc,               /* B */
    2020             :                 workstations_len, workstations,         /* B */
    2021             :                 comment_len, comment,                   /* B */
    2022             :                 munged_dial_len, munged_dial,           /* B */
    2023             :                 user_rid,                               /* d */
    2024             :                 group_rid,                              /* d */
    2025             :                 lm_pw_len, lm_pw,                       /* B */
    2026             :                 nt_pw_len, nt_pw,                       /* B */
    2027             :                 nt_pw_hist_len, nt_pw_hist,             /* B */
    2028             :                 pdb_get_acct_ctrl(sampass),             /* d */
    2029       44418 :                 pdb_get_logon_divs(sampass),            /* w */
    2030             :                 pdb_get_hours_len(sampass),             /* d */
    2031             :                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
    2032       44418 :                 pdb_get_bad_password_count(sampass),    /* w */
    2033       44418 :                 pdb_get_logon_count(sampass),           /* w */
    2034             :                 pdb_get_unknown_6(sampass));            /* d */
    2035             : 
    2036       44418 :         if (size_only) {
    2037           0 :                 return buflen;
    2038             :         }
    2039             : 
    2040             :         /* malloc the space needed */
    2041       44418 :         if ( (*buf=(uint8_t*)SMB_MALLOC(len)) == NULL) {
    2042           0 :                 DEBUG(0,("init_buffer_from_samu_v3: Unable to malloc() memory for buffer!\n"));
    2043           0 :                 return (-1);
    2044             :         }
    2045             : 
    2046             :         /* now for the real call to tdb_pack() */
    2047      133254 :         buflen = tdb_pack(*buf, len,  SAMU_BUFFER_FORMAT_V3,
    2048             :                 logon_time,                             /* d */
    2049             :                 logoff_time,                            /* d */
    2050             :                 kickoff_time,                           /* d */
    2051             :                 bad_password_time,                      /* d */
    2052             :                 pass_last_set_time,                     /* d */
    2053             :                 pass_can_change_time,                   /* d */
    2054             :                 pass_must_change_time,                  /* d */
    2055             :                 username_len, username,                 /* B */
    2056             :                 domain_len, domain,                     /* B */
    2057             :                 nt_username_len, nt_username,           /* B */
    2058             :                 fullname_len, fullname,                 /* B */
    2059             :                 homedir_len, homedir,                   /* B */
    2060             :                 dir_drive_len, dir_drive,               /* B */
    2061             :                 logon_script_len, logon_script,         /* B */
    2062             :                 profile_path_len, profile_path,         /* B */
    2063             :                 acct_desc_len, acct_desc,               /* B */
    2064             :                 workstations_len, workstations,         /* B */
    2065             :                 comment_len, comment,                   /* B */
    2066             :                 munged_dial_len, munged_dial,           /* B */
    2067             :                 user_rid,                               /* d */
    2068             :                 group_rid,                              /* d */
    2069             :                 lm_pw_len, lm_pw,                       /* B */
    2070             :                 nt_pw_len, nt_pw,                       /* B */
    2071             :                 nt_pw_hist_len, nt_pw_hist,             /* B */
    2072             :                 pdb_get_acct_ctrl(sampass),             /* d */
    2073       44418 :                 pdb_get_logon_divs(sampass),            /* w */
    2074             :                 pdb_get_hours_len(sampass),             /* d */
    2075             :                 MAX_HOURS_LEN, pdb_get_hours(sampass),  /* B */
    2076       44418 :                 pdb_get_bad_password_count(sampass),    /* w */
    2077       44418 :                 pdb_get_logon_count(sampass),           /* w */
    2078             :                 pdb_get_unknown_6(sampass));            /* d */
    2079             : 
    2080             :         /* check to make sure we got it correct */
    2081       44418 :         if (buflen != len) {
    2082           0 :                 DEBUG(0, ("init_buffer_from_samu_v3: something odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
    2083             :                           (unsigned long)buflen, (unsigned long)len));
    2084             :                 /* error */
    2085           0 :                 SAFE_FREE (*buf);
    2086           0 :                 return (-1);
    2087             :         }
    2088             : 
    2089       44418 :         return (buflen);
    2090             : }
    2091             : 
    2092       93984 : static bool init_samu_from_buffer_v4(struct samu *sampass, uint8_t *buf, uint32_t buflen)
    2093             : {
    2094             :         /* nothing changed between V3 and V4 */
    2095       93984 :         return init_samu_from_buffer_v3(sampass, buf, buflen);
    2096             : }
    2097             : 
    2098       44418 : static uint32_t init_buffer_from_samu_v4(uint8_t **buf, struct samu *sampass, bool size_only)
    2099             : {
    2100             :         /* nothing changed between V3 and V4 */
    2101       44418 :         return init_buffer_from_samu_v3(buf, sampass, size_only);
    2102             : }
    2103             : 
    2104             : /**********************************************************************
    2105             :  Initialize a struct samu struct from a BYTE buffer of size len
    2106             :  *********************************************************************/
    2107             : 
    2108       93990 : bool init_samu_from_buffer(struct samu *sampass, uint32_t level,
    2109             :                            uint8_t *buf, uint32_t buflen)
    2110             : {
    2111       93990 :         switch (level) {
    2112           0 :         case SAMU_BUFFER_V0:
    2113           0 :                 return init_samu_from_buffer_v0(sampass, buf, buflen);
    2114           0 :         case SAMU_BUFFER_V1:
    2115           0 :                 return init_samu_from_buffer_v1(sampass, buf, buflen);
    2116           6 :         case SAMU_BUFFER_V2:
    2117           6 :                 return init_samu_from_buffer_v2(sampass, buf, buflen);
    2118           0 :         case SAMU_BUFFER_V3:
    2119           0 :                 return init_samu_from_buffer_v3(sampass, buf, buflen);
    2120       93950 :         case SAMU_BUFFER_V4:
    2121       93984 :                 return init_samu_from_buffer_v4(sampass, buf, buflen);
    2122             :         }
    2123             : 
    2124           0 :         return false;
    2125             : }
    2126             : 
    2127             : /**********************************************************************
    2128             :  Initialize a BYTE buffer from a struct samu struct
    2129             :  *********************************************************************/
    2130             : 
    2131       44418 : uint32_t init_buffer_from_samu (uint8_t **buf, struct samu *sampass, bool size_only)
    2132             : {
    2133       44418 :         return init_buffer_from_samu_v4(buf, sampass, size_only);
    2134             : }
    2135             : 
    2136             : /*********************************************************************
    2137             : *********************************************************************/
    2138             : 
    2139       43058 : bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
    2140             : {
    2141       43058 :         uint8_t *buf = NULL;
    2142           0 :         int len;
    2143             : 
    2144       43058 :         len = init_buffer_from_samu(&buf, src, False);
    2145       43058 :         if (len == -1 || !buf) {
    2146           0 :                 SAFE_FREE(buf);
    2147           0 :                 return False;
    2148             :         }
    2149             : 
    2150       43058 :         if (!init_samu_from_buffer( dst, SAMU_BUFFER_LATEST, buf, len )) {
    2151           0 :                 free(buf);
    2152           0 :                 return False;
    2153             :         }
    2154             : 
    2155       43058 :         dst->methods = src->methods;
    2156             : 
    2157       43058 :         if ( src->unix_pw ) {
    2158       43041 :                 dst->unix_pw = tcopy_passwd( dst, src->unix_pw );
    2159       43041 :                 if (!dst->unix_pw) {
    2160           0 :                         free(buf);
    2161           0 :                         return False;
    2162             :                 }
    2163             :         }
    2164             : 
    2165       43058 :         if (src->group_sid) {
    2166       43058 :                 pdb_set_group_sid(dst, src->group_sid, PDB_SET);
    2167             :         }
    2168             : 
    2169       43058 :         free(buf);
    2170       43058 :         return True;
    2171             : }
    2172             : 
    2173             : /*********************************************************************
    2174             :  Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
    2175             : *********************************************************************/
    2176             : 
    2177          11 : bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
    2178             : {
    2179           0 :         time_t LastBadPassword;
    2180           0 :         uint16_t BadPasswordCount;
    2181           0 :         uint32_t resettime;
    2182           0 :         bool res;
    2183             : 
    2184          11 :         BadPasswordCount = pdb_get_bad_password_count(sampass);
    2185          11 :         if (!BadPasswordCount) {
    2186          11 :                 DEBUG(9, ("No bad password attempts.\n"));
    2187          11 :                 return True;
    2188             :         }
    2189             : 
    2190           0 :         become_root();
    2191           0 :         res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
    2192           0 :         unbecome_root();
    2193             : 
    2194           0 :         if (!res) {
    2195           0 :                 DEBUG(0, ("pdb_update_bad_password_count: pdb_get_account_policy failed.\n"));
    2196           0 :                 return False;
    2197             :         }
    2198             : 
    2199             :         /* First, check if there is a reset time to compare */
    2200           0 :         if ((resettime == (uint32_t) -1) || (resettime == 0)) {
    2201           0 :                 DEBUG(9, ("No reset time, can't reset bad pw count\n"));
    2202           0 :                 return True;
    2203             :         }
    2204             : 
    2205           0 :         LastBadPassword = pdb_get_bad_password_time(sampass);
    2206           0 :         DEBUG(7, ("LastBadPassword=%d, resettime=%d, current time=%d.\n",
    2207             :                    (uint32_t) LastBadPassword, resettime, (uint32_t)time(NULL)));
    2208           0 :         if (time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(resettime)*60)){
    2209           0 :                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
    2210           0 :                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
    2211           0 :                 if (updated) {
    2212           0 :                         *updated = True;
    2213             :                 }
    2214             :         }
    2215             : 
    2216           0 :         return True;
    2217             : }
    2218             : 
    2219             : /*********************************************************************
    2220             :  Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
    2221             : *********************************************************************/
    2222             : 
    2223           6 : bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
    2224             : {
    2225           0 :         uint32_t duration;
    2226           0 :         time_t LastBadPassword;
    2227           0 :         bool res;
    2228             : 
    2229           6 :         if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
    2230           6 :                 DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
    2231             :                         pdb_get_username(sampass)));
    2232           6 :                 return True;
    2233             :         }
    2234             : 
    2235           0 :         become_root();
    2236           0 :         res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
    2237           0 :         unbecome_root();
    2238             : 
    2239           0 :         if (!res) {
    2240           0 :                 DEBUG(0, ("pdb_update_autolock_flag: pdb_get_account_policy failed.\n"));
    2241           0 :                 return False;
    2242             :         }
    2243             : 
    2244             :         /* First, check if there is a duration to compare */
    2245           0 :         if ((duration == (uint32_t) -1)  || (duration == 0)) {
    2246           0 :                 DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
    2247           0 :                 return True;
    2248             :         }
    2249             : 
    2250           0 :         LastBadPassword = pdb_get_bad_password_time(sampass);
    2251           0 :         DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
    2252             :                   pdb_get_username(sampass), (uint32_t)LastBadPassword, duration*60, (uint32_t)time(NULL)));
    2253             : 
    2254           0 :         if (LastBadPassword == (time_t)0) {
    2255           0 :                 DEBUG(1,("pdb_update_autolock_flag: Account %s "
    2256             :                          "administratively locked out with no bad password "
    2257             :                          "time. Leaving locked out.\n",
    2258             :                          pdb_get_username(sampass) ));
    2259           0 :                 return True;
    2260             :         }
    2261             : 
    2262           0 :         if ((time(NULL) > (LastBadPassword + convert_uint32_t_to_time_t(duration) * 60))) {
    2263           0 :                 pdb_set_acct_ctrl(sampass,
    2264           0 :                                   pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
    2265             :                                   PDB_CHANGED);
    2266           0 :                 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
    2267           0 :                 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
    2268           0 :                 if (updated) {
    2269           0 :                         *updated = True;
    2270             :                 }
    2271             :         }
    2272             : 
    2273           0 :         return True;
    2274             : }
    2275             : 
    2276             : /*********************************************************************
    2277             :  Increment the bad_password_count
    2278             : *********************************************************************/
    2279             : 
    2280         152 : bool pdb_increment_bad_password_count(struct samu *sampass)
    2281             : {
    2282           0 :         uint32_t account_policy_lockout;
    2283         152 :         bool autolock_updated = False, badpw_updated = False;
    2284           0 :         bool ret;
    2285             : 
    2286             :         /* Retrieve the account lockout policy */
    2287         152 :         become_root();
    2288         152 :         ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
    2289         152 :         unbecome_root();
    2290         152 :         if ( !ret ) {
    2291           0 :                 DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
    2292           0 :                 return False;
    2293             :         }
    2294             : 
    2295             :         /* If there is no policy, we don't need to continue checking */
    2296         152 :         if (!account_policy_lockout) {
    2297         152 :                 DEBUG(9, ("No lockout policy, don't track bad passwords\n"));
    2298         152 :                 return True;
    2299             :         }
    2300             : 
    2301             :         /* Check if the autolock needs to be cleared */
    2302           0 :         if (!pdb_update_autolock_flag(sampass, &autolock_updated))
    2303           0 :                 return False;
    2304             : 
    2305             :         /* Check if the badpw count needs to be reset */
    2306           0 :         if (!pdb_update_bad_password_count(sampass, &badpw_updated))
    2307           0 :                 return False;
    2308             : 
    2309             :         /*
    2310             :           Ok, now we can assume that any resetting that needs to be
    2311             :           done has been done, and just get on with incrementing
    2312             :           and autolocking if necessary
    2313             :         */
    2314             : 
    2315           0 :         pdb_set_bad_password_count(sampass,
    2316           0 :                                    pdb_get_bad_password_count(sampass)+1,
    2317             :                                    PDB_CHANGED);
    2318           0 :         pdb_set_bad_password_time(sampass, time(NULL), PDB_CHANGED);
    2319             : 
    2320             : 
    2321           0 :         if (pdb_get_bad_password_count(sampass) < account_policy_lockout)
    2322           0 :                 return True;
    2323             : 
    2324           0 :         if (!pdb_set_acct_ctrl(sampass,
    2325           0 :                                pdb_get_acct_ctrl(sampass) | ACB_AUTOLOCK,
    2326             :                                PDB_CHANGED)) {
    2327           0 :                 DEBUG(1, ("pdb_increment_bad_password_count:failed to set 'autolock' flag. \n"));
    2328           0 :                 return False;
    2329             :         }
    2330             : 
    2331           0 :         return True;
    2332             : }
    2333             : 
    2334           0 : bool is_dc_trusted_domain_situation(const char *domain_name)
    2335             : {
    2336           0 :         return IS_DC && !strequal(domain_name, lp_workgroup());
    2337             : }
    2338             : 
    2339             : /*******************************************************************
    2340             :  Wrapper around retrieving the clear text trust account password.
    2341             :  appropriate account name is stored in account_name.
    2342             :  Caller must free password, but not account_name.
    2343             : *******************************************************************/
    2344             : 
    2345           0 : static bool get_trust_pw_clear2(const char *domain,
    2346             :                                 const char **account_name,
    2347             :                                 enum netr_SchannelType *channel,
    2348             :                                 char **cur_pw,
    2349             :                                 time_t *_last_set_time,
    2350             :                                 char **prev_pw)
    2351             : {
    2352           0 :         char *pwd;
    2353           0 :         time_t last_set_time;
    2354             : 
    2355           0 :         if (cur_pw != NULL) {
    2356           0 :                 *cur_pw = NULL;
    2357             :         }
    2358           0 :         if (_last_set_time != NULL) {
    2359           0 :                 *_last_set_time = 0;
    2360             :         }
    2361           0 :         if (prev_pw != NULL) {
    2362           0 :                 *prev_pw = NULL;
    2363             :         }
    2364             : 
    2365             :         /* if we are a DC and this is not our domain, then lookup an account
    2366             :          * for the domain trust */
    2367             : 
    2368           0 :         if (is_dc_trusted_domain_situation(domain)) {
    2369           0 :                 if (!lp_allow_trusted_domains()) {
    2370           0 :                         return false;
    2371             :                 }
    2372             : 
    2373           0 :                 if (!pdb_get_trusteddom_pw(domain, cur_pw, NULL,
    2374             :                                            &last_set_time))
    2375             :                 {
    2376           0 :                         DEBUG(0, ("get_trust_pw: could not fetch trust "
    2377             :                                 "account password for trusted domain %s\n",
    2378             :                                 domain));
    2379           0 :                         return false;
    2380             :                 }
    2381             : 
    2382           0 :                 if (channel != NULL) {
    2383           0 :                         *channel = SEC_CHAN_DOMAIN;
    2384             :                 }
    2385             : 
    2386           0 :                 if (account_name != NULL) {
    2387           0 :                         *account_name = lp_workgroup();
    2388             :                 }
    2389             : 
    2390           0 :                 if (_last_set_time != NULL) {
    2391           0 :                         *_last_set_time = last_set_time;
    2392             :                 }
    2393             : 
    2394           0 :                 return true;
    2395             :         }
    2396             : 
    2397             :         /*
    2398             :          * Since we can only be member of one single domain, we are now
    2399             :          * in a member situation:
    2400             :          *
    2401             :          *  -  Either we are a DC (selfjoined) and the domain is our
    2402             :          *     own domain.
    2403             :          *  -  Or we are on a member and the domain is our own or some
    2404             :          *     other (potentially trusted) domain.
    2405             :          *
    2406             :          * In both cases, we can only get the machine account password
    2407             :          * for our own domain to connect to our own dc. (For a member,
    2408             :          * request to trusted domains are performed through our dc.)
    2409             :          *
    2410             :          * So we simply use our own domain name to retrieve the
    2411             :          * machine account password and ignore the request domain here.
    2412             :          */
    2413             : 
    2414           0 :         pwd = secrets_fetch_machine_password(lp_workgroup(), &last_set_time, channel);
    2415             : 
    2416           0 :         if (pwd != NULL) {
    2417           0 :                 struct timeval expire;
    2418             : 
    2419           0 :                 *cur_pw = pwd;
    2420             : 
    2421           0 :                 if (account_name != NULL) {
    2422           0 :                         *account_name = lp_netbios_name();
    2423             :                 }
    2424             : 
    2425           0 :                 if (_last_set_time != NULL) {
    2426           0 :                         *_last_set_time = last_set_time;
    2427             :                 }
    2428             : 
    2429           0 :                 if (prev_pw == NULL) {
    2430           0 :                         return true;
    2431             :                 }
    2432             : 
    2433           0 :                 ZERO_STRUCT(expire);
    2434           0 :                 expire.tv_sec = lp_machine_password_timeout();
    2435           0 :                 expire.tv_sec /= 2;
    2436           0 :                 expire.tv_sec += last_set_time;
    2437           0 :                 if (timeval_expired(&expire)) {
    2438           0 :                         return true;
    2439             :                 }
    2440             : 
    2441           0 :                 pwd = secrets_fetch_prev_machine_password(lp_workgroup());
    2442           0 :                 if (pwd != NULL) {
    2443           0 :                         *prev_pw = pwd;
    2444             :                 }
    2445             : 
    2446           0 :                 return true;
    2447             :         }
    2448             : 
    2449           0 :         DEBUG(5, ("get_trust_pw_clear2: could not fetch clear text trust "
    2450             :                   "account password for domain %s\n", domain));
    2451           0 :         return false;
    2452             : }
    2453             : 
    2454           0 : bool get_trust_pw_clear(const char *domain, char **ret_pwd,
    2455             :                         const char **account_name,
    2456             :                         enum netr_SchannelType *channel)
    2457             : {
    2458           0 :         return get_trust_pw_clear2(domain,
    2459             :                                    account_name,
    2460             :                                    channel,
    2461             :                                    ret_pwd,
    2462             :                                    NULL,
    2463             :                                    NULL);
    2464             : }
    2465             : 
    2466             : /*******************************************************************
    2467             :  Wrapper around retrieving the trust account password.
    2468             :  appropriate account name is stored in account_name.
    2469             : *******************************************************************/
    2470             : 
    2471           0 : static bool get_trust_pw_hash2(const char *domain,
    2472             :                                const char **account_name,
    2473             :                                enum netr_SchannelType *channel,
    2474             :                                struct samr_Password *current_nt_hash,
    2475             :                                time_t *last_set_time,
    2476             :                                struct samr_Password **_previous_nt_hash)
    2477             : {
    2478           0 :         char *cur_pw = NULL;
    2479           0 :         char *prev_pw = NULL;
    2480           0 :         char **_prev_pw = NULL;
    2481           0 :         bool ok;
    2482             : 
    2483           0 :         if (_previous_nt_hash != NULL) {
    2484           0 :                 *_previous_nt_hash = NULL;
    2485           0 :                 _prev_pw = &prev_pw;
    2486             :         }
    2487             : 
    2488           0 :         ok = get_trust_pw_clear2(domain, account_name, channel,
    2489             :                                  &cur_pw, last_set_time, _prev_pw);
    2490           0 :         if (ok) {
    2491           0 :                 struct samr_Password *previous_nt_hash = NULL;
    2492             : 
    2493           0 :                 E_md4hash(cur_pw, current_nt_hash->hash);
    2494           0 :                 BURN_FREE_STR(cur_pw);
    2495             : 
    2496           0 :                 if (prev_pw == NULL) {
    2497           0 :                         return true;
    2498             :                 }
    2499             : 
    2500           0 :                 previous_nt_hash = SMB_MALLOC_P(struct samr_Password);
    2501           0 :                 if (previous_nt_hash == NULL) {
    2502           0 :                         return false;
    2503             :                 }
    2504             : 
    2505           0 :                 E_md4hash(prev_pw, previous_nt_hash->hash);
    2506           0 :                 BURN_FREE_STR(prev_pw);
    2507             : 
    2508           0 :                 *_previous_nt_hash = previous_nt_hash;
    2509           0 :                 return true;
    2510           0 :         } else if (is_dc_trusted_domain_situation(domain)) {
    2511           0 :                 return false;
    2512             :         }
    2513             : 
    2514             :         /* as a fallback, try to get the hashed pwd directly from the tdb... */
    2515             : 
    2516           0 :         if (secrets_fetch_trust_account_password_legacy(domain,
    2517           0 :                                                         current_nt_hash->hash,
    2518             :                                                         last_set_time,
    2519             :                                                         channel))
    2520             :         {
    2521           0 :                 if (account_name != NULL) {
    2522           0 :                         *account_name = lp_netbios_name();
    2523             :                 }
    2524             : 
    2525           0 :                 return true;
    2526             :         }
    2527             : 
    2528           0 :         DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
    2529             :                 "password for domain %s\n", domain));
    2530           0 :         return False;
    2531             : }
    2532             : 
    2533           0 : bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
    2534             :                        const char **account_name,
    2535             :                        enum netr_SchannelType *channel)
    2536             : {
    2537           0 :         struct samr_Password current_nt_hash;
    2538           0 :         bool ok;
    2539             : 
    2540           0 :         ok = get_trust_pw_hash2(domain, account_name, channel,
    2541             :                                 &current_nt_hash, NULL, NULL);
    2542           0 :         if (!ok) {
    2543           0 :                 return false;
    2544             :         }
    2545             : 
    2546           0 :         memcpy(ret_pwd, current_nt_hash.hash, sizeof(current_nt_hash.hash));
    2547           0 :         return true;
    2548             : }
    2549             : 
    2550         129 : NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
    2551             :                                    const char *dns_domain, /* optional */
    2552             :                                    TALLOC_CTX *mem_ctx,
    2553             :                                    struct cli_credentials **_creds)
    2554             : {
    2555         129 :         TALLOC_CTX *frame = talloc_stackframe();
    2556           0 :         NTSTATUS status;
    2557           0 :         struct loadparm_context *lp_ctx;
    2558           0 :         enum netr_SchannelType channel;
    2559           0 :         time_t last_set_time;
    2560           0 :         const char *_account_name;
    2561           0 :         const char *account_name;
    2562         129 :         char *cur_pw = NULL;
    2563         129 :         char *prev_pw = NULL;
    2564           0 :         struct samr_Password cur_nt_hash;
    2565         129 :         struct cli_credentials *creds = NULL;
    2566           0 :         bool ok;
    2567             : 
    2568             :         /*
    2569             :          * If this is our primary trust relationship, use the common
    2570             :          * code to read the secrets.ldb or secrets.tdb file.
    2571             :          */
    2572         129 :         if (strequal(netbios_domain, lp_workgroup())) {
    2573         129 :                 struct db_context *db_ctx = secrets_db_ctx();
    2574         129 :                 if (db_ctx == NULL) {
    2575           0 :                         DEBUG(1, ("failed to open secrets.tdb to obtain our trust credentials for %s\n",
    2576             :                                   netbios_domain));
    2577           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    2578           0 :                         goto fail;
    2579             :                 }
    2580             : 
    2581         129 :                 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
    2582         129 :                 if (lp_ctx == NULL) {
    2583           0 :                         DEBUG(1, ("loadparm_init_s3 failed\n"));
    2584           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    2585           0 :                         goto fail;
    2586             :                 }
    2587             : 
    2588         129 :                 creds = cli_credentials_init(mem_ctx);
    2589         129 :                 if (creds == NULL) {
    2590           0 :                         status = NT_STATUS_NO_MEMORY;
    2591           0 :                         goto fail;
    2592             :                 }
    2593             : 
    2594         129 :                 ok = cli_credentials_set_conf(creds, lp_ctx);
    2595         129 :                 if (!ok) {
    2596           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    2597           0 :                         goto fail;
    2598             :                 }
    2599             : 
    2600         129 :                 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
    2601         129 :                 if (!ok) {
    2602           0 :                         status = NT_STATUS_NO_MEMORY;
    2603           0 :                         goto fail;
    2604             :                 }
    2605             : 
    2606         129 :                 status = cli_credentials_set_machine_account_db_ctx(creds,
    2607             :                                                                     lp_ctx,
    2608             :                                                                     db_ctx);
    2609         129 :                 if (!NT_STATUS_IS_OK(status)) {
    2610           0 :                         goto fail;
    2611             :                 }
    2612         129 :                 goto done;
    2613           0 :         } else if (!IS_DC) {
    2614           0 :                 DEBUG(1, ("Refusing to get trust account info for %s, "
    2615             :                           "which is not our primary domain %s, "
    2616             :                           "as we are not a DC\n",
    2617             :                           netbios_domain, lp_workgroup()));
    2618           0 :                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    2619           0 :                 goto fail;
    2620             :         }
    2621             : 
    2622           0 :         status = pdb_get_trusteddom_creds(netbios_domain, mem_ctx, &creds);
    2623           0 :         if (NT_STATUS_IS_OK(status)) {
    2624           0 :                 goto done;
    2625             :         }
    2626           0 :         if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
    2627           0 :                 goto fail;
    2628             :         }
    2629             : 
    2630           0 :         ok = get_trust_pw_clear2(netbios_domain,
    2631             :                                  &_account_name,
    2632             :                                  &channel,
    2633             :                                  &cur_pw,
    2634             :                                  &last_set_time,
    2635             :                                  &prev_pw);
    2636           0 :         if (!ok) {
    2637           0 :                 ok = get_trust_pw_hash2(netbios_domain,
    2638             :                                         &_account_name,
    2639             :                                         &channel,
    2640             :                                         &cur_nt_hash,
    2641             :                                         &last_set_time,
    2642             :                                         NULL);
    2643           0 :                 if (!ok) {
    2644           0 :                         DEBUG(1, ("get_trust_pw_*2 failed for domain[%s]\n",
    2645             :                                   netbios_domain));
    2646           0 :                         status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    2647           0 :                         goto fail;
    2648             :                 }
    2649             :         }
    2650             : 
    2651           0 :         account_name = talloc_asprintf(frame, "%s$", _account_name);
    2652           0 :         if (account_name == NULL) {
    2653           0 :                 status = NT_STATUS_NO_MEMORY;
    2654           0 :                 goto fail;
    2655             :         }
    2656             : 
    2657           0 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
    2658           0 :         if (lp_ctx == NULL) {
    2659           0 :                 DEBUG(1, ("loadparm_init_s3 failed\n"));
    2660           0 :                 status = NT_STATUS_INTERNAL_ERROR;
    2661           0 :                 goto fail;
    2662             :         }
    2663             : 
    2664           0 :         creds = cli_credentials_init(mem_ctx);
    2665           0 :         if (creds == NULL) {
    2666           0 :                 status = NT_STATUS_NO_MEMORY;
    2667           0 :                 goto fail;
    2668             :         }
    2669             : 
    2670           0 :         ok = cli_credentials_set_conf(creds, lp_ctx);
    2671           0 :         if (!ok) {
    2672           0 :                 status = NT_STATUS_INTERNAL_ERROR;
    2673           0 :                 goto fail;
    2674             :         }
    2675             : 
    2676           0 :         cli_credentials_set_secure_channel_type(creds, channel);
    2677           0 :         cli_credentials_set_password_last_changed_time(creds, last_set_time);
    2678             : 
    2679           0 :         ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
    2680           0 :         if (!ok) {
    2681           0 :                 status = NT_STATUS_NO_MEMORY;
    2682           0 :                 goto fail;
    2683             :         }
    2684             : 
    2685           0 :         if (dns_domain != NULL) {
    2686           0 :                 ok = cli_credentials_set_realm(creds, dns_domain, CRED_SPECIFIED);
    2687           0 :                 if (!ok) {
    2688           0 :                         status = NT_STATUS_NO_MEMORY;
    2689           0 :                         goto fail;
    2690             :                 }
    2691             : 
    2692             :                 /*
    2693             :                  * It's not possible to use NTLMSSP with a domain trust account.
    2694             :                  */
    2695           0 :                 cli_credentials_set_kerberos_state(creds,
    2696             :                                                    CRED_USE_KERBEROS_REQUIRED,
    2697             :                                                    CRED_SPECIFIED);
    2698             :         } else {
    2699             :                 /*
    2700             :                  * We can't use kerberos against an NT4 domain.
    2701             :                  *
    2702             :                  * We should have a mode that also disallows NTLMSSP here,
    2703             :                  * as only NETLOGON SCHANNEL is possible.
    2704             :                  */
    2705           0 :                 cli_credentials_set_kerberos_state(creds,
    2706             :                                                    CRED_USE_KERBEROS_DISABLED,
    2707             :                                                    CRED_SPECIFIED);
    2708             :         }
    2709             : 
    2710           0 :         ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
    2711           0 :         if (!ok) {
    2712           0 :                 status = NT_STATUS_NO_MEMORY;
    2713           0 :                 goto fail;
    2714             :         }
    2715             : 
    2716           0 :         if (cur_pw == NULL) {
    2717           0 :                 ok = cli_credentials_set_nt_hash(creds, &cur_nt_hash, CRED_SPECIFIED);
    2718           0 :                 if (!ok) {
    2719           0 :                         status = NT_STATUS_NO_MEMORY;
    2720           0 :                         goto fail;
    2721             :                 }
    2722             :                 /*
    2723             :                  * We currently can't do kerberos just with an NTHASH.
    2724             :                  */
    2725           0 :                 cli_credentials_set_kerberos_state(creds,
    2726             :                                                    CRED_USE_KERBEROS_DISABLED,
    2727             :                                                    CRED_SPECIFIED);
    2728           0 :                 goto done;
    2729             :         }
    2730             : 
    2731           0 :         ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
    2732           0 :         if (!ok) {
    2733           0 :                 status = NT_STATUS_NO_MEMORY;
    2734           0 :                 goto fail;
    2735             :         }
    2736             : 
    2737           0 :         if (prev_pw != NULL) {
    2738           0 :                 ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
    2739           0 :                 if (!ok) {
    2740           0 :                         status = NT_STATUS_NO_MEMORY;
    2741           0 :                         goto fail;
    2742             :                 }
    2743             :         }
    2744             : 
    2745           0 :  done:
    2746         129 :         *_creds = creds;
    2747         129 :         creds = NULL;
    2748         129 :         status = NT_STATUS_OK;
    2749         129 :  fail:
    2750         129 :         TALLOC_FREE(creds);
    2751         129 :         SAFE_FREE(cur_pw);
    2752         129 :         SAFE_FREE(prev_pw);
    2753         129 :         TALLOC_FREE(frame);
    2754         129 :         return status;
    2755             : }

Generated by: LCOV version 1.14