LCOV - code coverage report
Current view: top level - source3/passdb - passdb.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 633 1212 52.2 %
Date: 2021-09-23 10:06:22 Functions: 30 42 71.4 %

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

Generated by: LCOV version 1.13