root/source3/passdb/pdb_get_set.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pdb_get_acct_ctrl
  2. pdb_get_logon_time
  3. pdb_get_logoff_time
  4. pdb_get_kickoff_time
  5. pdb_get_bad_password_time
  6. pdb_get_pass_last_set_time
  7. pdb_get_pass_can_change_time
  8. pdb_get_pass_can_change_time_noncalc
  9. pdb_get_pass_must_change_time
  10. pdb_get_pass_can_change
  11. pdb_get_logon_divs
  12. pdb_get_hours_len
  13. pdb_get_hours
  14. pdb_get_nt_passwd
  15. pdb_get_lanman_passwd
  16. pdb_get_pw_history
  17. pdb_get_plaintext_passwd
  18. pdb_get_user_sid
  19. pdb_get_group_sid
  20. pdb_get_init_flags
  21. pdb_get_username
  22. pdb_get_domain
  23. pdb_get_nt_username
  24. pdb_get_fullname
  25. pdb_get_homedir
  26. pdb_get_dir_drive
  27. pdb_get_logon_script
  28. pdb_get_profile_path
  29. pdb_get_acct_desc
  30. pdb_get_workstations
  31. pdb_get_comment
  32. pdb_get_munged_dial
  33. pdb_get_bad_password_count
  34. pdb_get_logon_count
  35. pdb_get_unknown_6
  36. pdb_get_backend_private_data
  37. pdb_set_acct_ctrl
  38. pdb_set_logon_time
  39. pdb_set_logoff_time
  40. pdb_set_kickoff_time
  41. pdb_set_bad_password_time
  42. pdb_set_pass_can_change_time
  43. pdb_set_pass_must_change_time
  44. pdb_set_pass_last_set_time
  45. pdb_set_hours_len
  46. pdb_set_logon_divs
  47. pdb_set_init_flags
  48. pdb_set_user_sid
  49. pdb_set_user_sid_from_string
  50. pdb_set_group_sid
  51. pdb_set_username
  52. pdb_set_domain
  53. pdb_set_nt_username
  54. pdb_set_fullname
  55. pdb_set_logon_script
  56. pdb_set_profile_path
  57. pdb_set_dir_drive
  58. pdb_set_homedir
  59. pdb_set_acct_desc
  60. pdb_set_workstations
  61. pdb_set_comment
  62. pdb_set_munged_dial
  63. pdb_set_nt_passwd
  64. pdb_set_lanman_passwd
  65. pdb_set_pw_history
  66. pdb_set_plaintext_pw_only
  67. pdb_set_bad_password_count
  68. pdb_set_logon_count
  69. pdb_set_unknown_6
  70. pdb_set_hours
  71. pdb_set_backend_private_data
  72. pdb_set_pass_can_change
  73. pdb_set_plaintext_passwd
  74. pdb_build_fields_present

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    struct samu access routines
   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) Stefan (metze) Metzmacher      2002
   9 
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 3 of the License, or
  13    (at your option) any later version.
  14 
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19 
  20    You should have received a copy of the GNU General Public License
  21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  22 */
  23 
  24 #include "includes.h"
  25 
  26 #undef DBGC_CLASS
  27 #define DBGC_CLASS DBGC_PASSDB
  28 
  29 /**
  30  * @todo Redefine this to NULL, but this changes the API because
  31  *       much of samba assumes that the pdb_get...() funtions 
  32  *       return strings.  (ie not null-pointers).
  33  *       See also pdb_fill_default_sam().
  34  */
  35 
  36 #define PDB_NOT_QUITE_NULL ""
  37 
  38 /*********************************************************************
  39  Collection of get...() functions for struct samu.
  40  ********************************************************************/
  41 
  42 uint32 pdb_get_acct_ctrl(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         return sampass->acct_ctrl;
  45 }
  46 
  47 time_t pdb_get_logon_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         return sampass->logon_time;
  50 }
  51 
  52 time_t pdb_get_logoff_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  53 {
  54         return sampass->logoff_time;
  55 }
  56 
  57 time_t pdb_get_kickoff_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59         return sampass->kickoff_time;
  60 }
  61 
  62 time_t pdb_get_bad_password_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  63 {
  64         return sampass->bad_password_time;
  65 }
  66 
  67 time_t pdb_get_pass_last_set_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  68 {
  69         return sampass->pass_last_set_time;
  70 }
  71 
  72 time_t pdb_get_pass_can_change_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
  73 {
  74         uint32 allow;
  75 
  76         /* if the last set time is zero, it means the user cannot 
  77            change their password, and this time must be zero.   jmcd 
  78         */
  79         if (sampass->pass_last_set_time == 0)
  80                 return (time_t) 0;
  81 
  82         /* if the time is max, and the field has been changed,
  83            we're trying to update this real value from the sampass
  84            to indicate that the user cannot change their password.  jmcd
  85         */
  86         if (sampass->pass_can_change_time == get_time_t_max() &&
  87             pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
  88                 return sampass->pass_can_change_time;
  89 
  90         if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
  91                 allow = 0;
  92 
  93         /* in normal cases, just calculate it from policy */
  94         return sampass->pass_last_set_time + allow;
  95 }
  96 
  97 /* we need this for loading from the backend, so that we don't overwrite
  98    non-changed max times, otherwise the pass_can_change checking won't work */
  99 time_t pdb_get_pass_can_change_time_noncalc(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101         return sampass->pass_can_change_time;
 102 }
 103 
 104 time_t pdb_get_pass_must_change_time(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 105 {
 106         uint32 expire;
 107 
 108         if (sampass->pass_last_set_time == 0)
 109                 return (time_t) 0;
 110 
 111         if (sampass->acct_ctrl & ACB_PWNOEXP)
 112                 return get_time_t_max();
 113 
 114         if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
 115             || expire == (uint32)-1 || expire == 0) 
 116                 return get_time_t_max();
 117 
 118         return sampass->pass_last_set_time + expire;
 119 }
 120 
 121 bool pdb_get_pass_can_change(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 122 {
 123         if (sampass->pass_can_change_time == get_time_t_max() &&
 124             sampass->pass_last_set_time != 0)
 125                 return False;
 126         return True;
 127 }
 128 
 129 uint16 pdb_get_logon_divs(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 130 {
 131         return sampass->logon_divs;
 132 }
 133 
 134 uint32 pdb_get_hours_len(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         return sampass->hours_len;
 137 }
 138 
 139 const uint8 *pdb_get_hours(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 140 {
 141         return (sampass->hours);
 142 }
 143 
 144 const uint8 *pdb_get_nt_passwd(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146         SMB_ASSERT((!sampass->nt_pw.data) 
 147                    || sampass->nt_pw.length == NT_HASH_LEN);
 148         return (uint8 *)sampass->nt_pw.data;
 149 }
 150 
 151 const uint8 *pdb_get_lanman_passwd(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 152 {
 153         SMB_ASSERT((!sampass->lm_pw.data) 
 154                    || sampass->lm_pw.length == LM_HASH_LEN);
 155         return (uint8 *)sampass->lm_pw.data;
 156 }
 157 
 158 const uint8 *pdb_get_pw_history(const struct samu *sampass, uint32 *current_hist_len)
     /* [<][>][^][v][top][bottom][index][help] */
 159 {
 160         SMB_ASSERT((!sampass->nt_pw_his.data) 
 161            || ((sampass->nt_pw_his.length % PW_HISTORY_ENTRY_LEN) == 0));
 162         *current_hist_len = sampass->nt_pw_his.length / PW_HISTORY_ENTRY_LEN;
 163         return (uint8 *)sampass->nt_pw_his.data;
 164 }
 165 
 166 /* Return the plaintext password if known.  Most of the time
 167    it isn't, so don't assume anything magic about this function.
 168 
 169    Used to pass the plaintext to passdb backends that might 
 170    want to store more than just the NTLM hashes.
 171 */
 172 const char *pdb_get_plaintext_passwd(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 173 {
 174         return sampass->plaintext_pw;
 175 }
 176 
 177 const DOM_SID *pdb_get_user_sid(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 178 {
 179         return &sampass->user_sid;
 180 }
 181 
 182 const DOM_SID *pdb_get_group_sid(struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 183 {
 184         DOM_SID *gsid;
 185         struct passwd *pwd;
 186 
 187         /* Return the cached group SID if we have that */
 188         if ( sampass->group_sid ) {
 189                 return sampass->group_sid;
 190         }
 191 
 192         /* generate the group SID from the user's primary Unix group */
 193 
 194         if ( !(gsid  = TALLOC_P( sampass, DOM_SID )) ) {
 195                 return NULL;
 196         }
 197 
 198         /* No algorithmic mapping, meaning that we have to figure out the
 199            primary group SID according to group mapping and the user SID must
 200            be a newly allocated one.  We rely on the user's Unix primary gid.
 201            We have no choice but to fail if we can't find it. */
 202 
 203         if ( sampass->unix_pw ) {
 204                 pwd = sampass->unix_pw;
 205         } else {
 206                 pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
 207         }
 208 
 209         if ( !pwd ) {
 210                 DEBUG(0,("pdb_get_group_sid: Failed to find Unix account for %s\n", pdb_get_username(sampass) ));
 211                 return NULL;
 212         }
 213 
 214         if ( pdb_gid_to_sid(pwd->pw_gid, gsid) ) {
 215                 enum lsa_SidType type = SID_NAME_UNKNOWN;
 216                 TALLOC_CTX *mem_ctx = talloc_init("pdb_get_group_sid");
 217                 bool lookup_ret;
 218 
 219                 if (!mem_ctx) {
 220                         return NULL;
 221                 }
 222 
 223                 /* Now check that it's actually a domain group and not something else */
 224 
 225                 lookup_ret = lookup_sid(mem_ctx, gsid, NULL, NULL, &type);
 226 
 227                 TALLOC_FREE( mem_ctx );
 228 
 229                 if ( lookup_ret && (type == SID_NAME_DOM_GRP) ) {
 230                         sampass->group_sid = gsid;
 231                         return sampass->group_sid;
 232                 }
 233 
 234                 DEBUG(3, ("Primary group for user %s is a %s and not a domain group\n", 
 235                         pwd->pw_name, sid_type_lookup(type)));
 236         }
 237 
 238         /* Just set it to the 'Domain Users' RID of 512 which will 
 239            always resolve to a name */
 240 
 241         sid_copy( gsid, get_global_sam_sid() );
 242         sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
 243 
 244         sampass->group_sid = gsid;
 245 
 246         return sampass->group_sid;
 247 }       
 248 
 249 /**
 250  * Get flags showing what is initalised in the struct samu
 251  * @param sampass the struct samu in question
 252  * @return the flags indicating the members initialised in the struct.
 253  **/
 254 
 255 enum pdb_value_state pdb_get_init_flags(const struct samu *sampass, enum pdb_elements element)
     /* [<][>][^][v][top][bottom][index][help] */
 256 {
 257         enum pdb_value_state ret = PDB_DEFAULT;
 258 
 259         if (!sampass->change_flags || !sampass->set_flags)
 260                 return ret;
 261 
 262         if (bitmap_query(sampass->set_flags, element)) {
 263                 DEBUG(11, ("element %d: SET\n", element)); 
 264                 ret = PDB_SET;
 265         }
 266 
 267         if (bitmap_query(sampass->change_flags, element)) {
 268                 DEBUG(11, ("element %d: CHANGED\n", element)); 
 269                 ret = PDB_CHANGED;
 270         }
 271 
 272         if (ret == PDB_DEFAULT) {
 273                 DEBUG(11, ("element %d: DEFAULT\n", element)); 
 274         }
 275 
 276         return ret;
 277 }
 278 
 279 const char *pdb_get_username(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 280 {
 281         return sampass->username;
 282 }
 283 
 284 const char *pdb_get_domain(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 285 {
 286         return sampass->domain;
 287 }
 288 
 289 const char *pdb_get_nt_username(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 290 {
 291         return sampass->nt_username;
 292 }
 293 
 294 const char *pdb_get_fullname(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 295 {
 296         return sampass->full_name;
 297 }
 298 
 299 const char *pdb_get_homedir(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 300 {
 301         return sampass->home_dir;
 302 }
 303 
 304 const char *pdb_get_dir_drive(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 305 {
 306         return sampass->dir_drive;
 307 }
 308 
 309 const char *pdb_get_logon_script(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 310 {
 311         return sampass->logon_script;
 312 }
 313 
 314 const char *pdb_get_profile_path(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 315 {
 316         return sampass->profile_path;
 317 }
 318 
 319 const char *pdb_get_acct_desc(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 320 {
 321         return sampass->acct_desc;
 322 }
 323 
 324 const char *pdb_get_workstations(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 325 {
 326         return sampass->workstations;
 327 }
 328 
 329 const char *pdb_get_comment(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 330 {
 331         return sampass->comment;
 332 }
 333 
 334 const char *pdb_get_munged_dial(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 335 {
 336         return sampass->munged_dial;
 337 }
 338 
 339 uint16 pdb_get_bad_password_count(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 340 {
 341         return sampass->bad_password_count;
 342 }
 343 
 344 uint16 pdb_get_logon_count(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 345 {
 346         return sampass->logon_count;
 347 }
 348 
 349 uint32 pdb_get_unknown_6(const struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
 350 {
 351         return sampass->unknown_6;
 352 }
 353 
 354 void *pdb_get_backend_private_data(const struct samu *sampass, const struct pdb_methods *my_methods)
     /* [<][>][^][v][top][bottom][index][help] */
 355 {
 356         if (my_methods == sampass->backend_private_methods) {
 357                 return sampass->backend_private_data;
 358         } else {
 359                 return NULL;
 360         }
 361 }
 362 
 363 /*********************************************************************
 364  Collection of set...() functions for struct samu.
 365  ********************************************************************/
 366 
 367 bool pdb_set_acct_ctrl(struct samu *sampass, uint32 acct_ctrl, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 368 {
 369         sampass->acct_ctrl = acct_ctrl;
 370         return pdb_set_init_flags(sampass, PDB_ACCTCTRL, flag);
 371 }
 372 
 373 bool pdb_set_logon_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 374 {
 375         sampass->logon_time = mytime;
 376         return pdb_set_init_flags(sampass, PDB_LOGONTIME, flag);
 377 }
 378 
 379 bool pdb_set_logoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 380 {
 381         sampass->logoff_time = mytime;
 382         return pdb_set_init_flags(sampass, PDB_LOGOFFTIME, flag);
 383 }
 384 
 385 bool pdb_set_kickoff_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 386 {
 387         sampass->kickoff_time = mytime;
 388         return pdb_set_init_flags(sampass, PDB_KICKOFFTIME, flag);
 389 }
 390 
 391 bool pdb_set_bad_password_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 392 {
 393         sampass->bad_password_time = mytime;
 394         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_TIME, flag);
 395 }
 396 
 397 bool pdb_set_pass_can_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 398 {
 399         sampass->pass_can_change_time = mytime;
 400         return pdb_set_init_flags(sampass, PDB_CANCHANGETIME, flag);
 401 }
 402 
 403 bool pdb_set_pass_must_change_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 404 {
 405         sampass->pass_must_change_time = mytime;
 406         return pdb_set_init_flags(sampass, PDB_MUSTCHANGETIME, flag);
 407 }
 408 
 409 bool pdb_set_pass_last_set_time(struct samu *sampass, time_t mytime, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 410 {
 411         sampass->pass_last_set_time = mytime;
 412         return pdb_set_init_flags(sampass, PDB_PASSLASTSET, flag);
 413 }
 414 
 415 bool pdb_set_hours_len(struct samu *sampass, uint32 len, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 416 {
 417         sampass->hours_len = len;
 418         return pdb_set_init_flags(sampass, PDB_HOURSLEN, flag);
 419 }
 420 
 421 bool pdb_set_logon_divs(struct samu *sampass, uint16 hours, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 422 {
 423         sampass->logon_divs = hours;
 424         return pdb_set_init_flags(sampass, PDB_LOGONDIVS, flag);
 425 }
 426 
 427 /**
 428  * Set flags showing what is initalised in the struct samu
 429  * @param sampass the struct samu in question
 430  * @param flag The *new* flag to be set.  Old flags preserved
 431  *             this flag is only added.  
 432  **/
 433 
 434 bool pdb_set_init_flags(struct samu *sampass, enum pdb_elements element, enum pdb_value_state value_flag)
     /* [<][>][^][v][top][bottom][index][help] */
 435 {
 436         if (!sampass->set_flags) {
 437                 if ((sampass->set_flags = 
 438                         bitmap_talloc(sampass, 
 439                                         PDB_COUNT))==NULL) {
 440                         DEBUG(0,("bitmap_talloc failed\n"));
 441                         return False;
 442                 }
 443         }
 444         if (!sampass->change_flags) {
 445                 if ((sampass->change_flags = 
 446                         bitmap_talloc(sampass, 
 447                                         PDB_COUNT))==NULL) {
 448                         DEBUG(0,("bitmap_talloc failed\n"));
 449                         return False;
 450                 }
 451         }
 452 
 453         switch(value_flag) {
 454                 case PDB_CHANGED:
 455                         if (!bitmap_set(sampass->change_flags, element)) {
 456                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
 457                                 return False;
 458                         }
 459                         if (!bitmap_set(sampass->set_flags, element)) {
 460                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
 461                                 return False;
 462                         }
 463                         DEBUG(11, ("element %d -> now CHANGED\n", element)); 
 464                         break;
 465                 case PDB_SET:
 466                         if (!bitmap_clear(sampass->change_flags, element)) {
 467                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
 468                                 return False;
 469                         }
 470                         if (!bitmap_set(sampass->set_flags, element)) {
 471                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
 472                                 return False;
 473                         }
 474                         DEBUG(11, ("element %d -> now SET\n", element)); 
 475                         break;
 476                 case PDB_DEFAULT:
 477                 default:
 478                         if (!bitmap_clear(sampass->change_flags, element)) {
 479                                 DEBUG(0,("Can't set flag: %d in change_flags.\n",element));
 480                                 return False;
 481                         }
 482                         if (!bitmap_clear(sampass->set_flags, element)) {
 483                                 DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
 484                                 return False;
 485                         }
 486                         DEBUG(11, ("element %d -> now DEFAULT\n", element)); 
 487                         break;
 488         }
 489 
 490         return True;
 491 }
 492 
 493 bool pdb_set_user_sid(struct samu *sampass, const DOM_SID *u_sid, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 494 {
 495         if (!u_sid)
 496                 return False;
 497 
 498         sid_copy(&sampass->user_sid, u_sid);
 499 
 500         DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n", 
 501                     sid_string_dbg(&sampass->user_sid)));
 502 
 503         return pdb_set_init_flags(sampass, PDB_USERSID, flag);
 504 }
 505 
 506 bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 507 {
 508         DOM_SID new_sid;
 509 
 510         if (!u_sid)
 511                 return False;
 512 
 513         DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
 514                    u_sid));
 515 
 516         if (!string_to_sid(&new_sid, u_sid)) { 
 517                 DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
 518                 return False;
 519         }
 520 
 521         if (!pdb_set_user_sid(sampass, &new_sid, flag)) {
 522                 DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on struct samu!\n", u_sid));
 523                 return False;
 524         }
 525 
 526         return True;
 527 }
 528 
 529 /********************************************************************
 530  We never fill this in from a passdb backend but rather set is 
 531  based on the user's primary group membership.  However, the 
 532  struct samu* is overloaded and reused in domain memship code 
 533  as well and built from the netr_SamInfo3 or PAC so we
 534  have to allow the explicitly setting of a group SID here.
 535 ********************************************************************/
 536 
 537 bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 538 {
 539         gid_t gid;
 540 
 541         if (!g_sid)
 542                 return False;
 543 
 544         if ( !(sampass->group_sid = TALLOC_P( sampass, DOM_SID )) ) {
 545                 return False;
 546         }
 547 
 548         /* if we cannot resolve the SID to gid, then just ignore it and 
 549            store DOMAIN_USERS as the primary groupSID */
 550 
 551         if ( sid_to_gid( g_sid, &gid ) ) {
 552                 sid_copy(sampass->group_sid, g_sid);
 553         } else {
 554                 sid_copy( sampass->group_sid, get_global_sam_sid() );
 555                 sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
 556         }
 557 
 558         DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n", 
 559                    sid_string_dbg(sampass->group_sid)));
 560 
 561         return pdb_set_init_flags(sampass, PDB_GROUPSID, flag);
 562 }
 563 
 564 /*********************************************************************
 565  Set the user's UNIX name.
 566  ********************************************************************/
 567 
 568 bool pdb_set_username(struct samu *sampass, const char *username, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 569 {
 570         if (username) { 
 571                 DEBUG(10, ("pdb_set_username: setting username %s, was %s\n", username,
 572                         (sampass->username)?(sampass->username):"NULL"));
 573 
 574                 sampass->username = talloc_strdup(sampass, username);
 575 
 576                 if (!sampass->username) {
 577                         DEBUG(0, ("pdb_set_username: talloc_strdup() failed!\n"));
 578                         return False;
 579                 }
 580         } else {
 581                 sampass->username = PDB_NOT_QUITE_NULL;
 582         }
 583 
 584         return pdb_set_init_flags(sampass, PDB_USERNAME, flag);
 585 }
 586 
 587 /*********************************************************************
 588  Set the domain name.
 589  ********************************************************************/
 590 
 591 bool pdb_set_domain(struct samu *sampass, const char *domain, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 592 {
 593         if (domain) { 
 594                 DEBUG(10, ("pdb_set_domain: setting domain %s, was %s\n", domain,
 595                         (sampass->domain)?(sampass->domain):"NULL"));
 596 
 597                 sampass->domain = talloc_strdup(sampass, domain);
 598 
 599                 if (!sampass->domain) {
 600                         DEBUG(0, ("pdb_set_domain: talloc_strdup() failed!\n"));
 601                         return False;
 602                 }
 603         } else {
 604                 sampass->domain = PDB_NOT_QUITE_NULL;
 605         }
 606 
 607         return pdb_set_init_flags(sampass, PDB_DOMAIN, flag);
 608 }
 609 
 610 /*********************************************************************
 611  Set the user's NT name.
 612  ********************************************************************/
 613 
 614 bool pdb_set_nt_username(struct samu *sampass, const char *nt_username, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 615 {
 616         if (nt_username) { 
 617                 DEBUG(10, ("pdb_set_nt_username: setting nt username %s, was %s\n", nt_username,
 618                         (sampass->nt_username)?(sampass->nt_username):"NULL"));
 619  
 620                 sampass->nt_username = talloc_strdup(sampass, nt_username);
 621 
 622                 if (!sampass->nt_username) {
 623                         DEBUG(0, ("pdb_set_nt_username: talloc_strdup() failed!\n"));
 624                         return False;
 625                 }
 626         } else {
 627                 sampass->nt_username = PDB_NOT_QUITE_NULL;
 628         }
 629 
 630         return pdb_set_init_flags(sampass, PDB_NTUSERNAME, flag);
 631 }
 632 
 633 /*********************************************************************
 634  Set the user's full name.
 635  ********************************************************************/
 636 
 637 bool pdb_set_fullname(struct samu *sampass, const char *full_name, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 638 {
 639         if (full_name) { 
 640                 DEBUG(10, ("pdb_set_full_name: setting full name %s, was %s\n", full_name,
 641                         (sampass->full_name)?(sampass->full_name):"NULL"));
 642 
 643                 sampass->full_name = talloc_strdup(sampass, full_name);
 644 
 645                 if (!sampass->full_name) {
 646                         DEBUG(0, ("pdb_set_fullname: talloc_strdup() failed!\n"));
 647                         return False;
 648                 }
 649         } else {
 650                 sampass->full_name = PDB_NOT_QUITE_NULL;
 651         }
 652 
 653         return pdb_set_init_flags(sampass, PDB_FULLNAME, flag);
 654 }
 655 
 656 /*********************************************************************
 657  Set the user's logon script.
 658  ********************************************************************/
 659 
 660 bool pdb_set_logon_script(struct samu *sampass, const char *logon_script, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 661 {
 662         if (logon_script) { 
 663                 DEBUG(10, ("pdb_set_logon_script: setting logon script %s, was %s\n", logon_script,
 664                         (sampass->logon_script)?(sampass->logon_script):"NULL"));
 665 
 666                 sampass->logon_script = talloc_strdup(sampass, logon_script);
 667 
 668                 if (!sampass->logon_script) {
 669                         DEBUG(0, ("pdb_set_logon_script: talloc_strdup() failed!\n"));
 670                         return False;
 671                 }
 672         } else {
 673                 sampass->logon_script = PDB_NOT_QUITE_NULL;
 674         }
 675 
 676         return pdb_set_init_flags(sampass, PDB_LOGONSCRIPT, flag);
 677 }
 678 
 679 /*********************************************************************
 680  Set the user's profile path.
 681  ********************************************************************/
 682 
 683 bool pdb_set_profile_path(struct samu *sampass, const char *profile_path, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 684 {
 685         if (profile_path) { 
 686                 DEBUG(10, ("pdb_set_profile_path: setting profile path %s, was %s\n", profile_path,
 687                         (sampass->profile_path)?(sampass->profile_path):"NULL"));
 688 
 689                 sampass->profile_path = talloc_strdup(sampass, profile_path);
 690 
 691                 if (!sampass->profile_path) {
 692                         DEBUG(0, ("pdb_set_profile_path: talloc_strdup() failed!\n"));
 693                         return False;
 694                 }
 695         } else {
 696                 sampass->profile_path = PDB_NOT_QUITE_NULL;
 697         }
 698 
 699         return pdb_set_init_flags(sampass, PDB_PROFILE, flag);
 700 }
 701 
 702 /*********************************************************************
 703  Set the user's directory drive.
 704  ********************************************************************/
 705 
 706 bool pdb_set_dir_drive(struct samu *sampass, const char *dir_drive, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 707 {
 708         if (dir_drive) { 
 709                 DEBUG(10, ("pdb_set_dir_drive: setting dir drive %s, was %s\n", dir_drive,
 710                         (sampass->dir_drive)?(sampass->dir_drive):"NULL"));
 711 
 712                 sampass->dir_drive = talloc_strdup(sampass, dir_drive);
 713 
 714                 if (!sampass->dir_drive) {
 715                         DEBUG(0, ("pdb_set_dir_drive: talloc_strdup() failed!\n"));
 716                         return False;
 717                 }
 718 
 719         } else {
 720                 sampass->dir_drive = PDB_NOT_QUITE_NULL;
 721         }
 722 
 723         return pdb_set_init_flags(sampass, PDB_DRIVE, flag);
 724 }
 725 
 726 /*********************************************************************
 727  Set the user's home directory.
 728  ********************************************************************/
 729 
 730 bool pdb_set_homedir(struct samu *sampass, const char *home_dir, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 731 {
 732         if (home_dir) { 
 733                 DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", home_dir,
 734                         (sampass->home_dir)?(sampass->home_dir):"NULL"));
 735 
 736                 sampass->home_dir = talloc_strdup(sampass, home_dir);
 737 
 738                 if (!sampass->home_dir) {
 739                         DEBUG(0, ("pdb_set_home_dir: talloc_strdup() failed!\n"));
 740                         return False;
 741                 }
 742         } else {
 743                 sampass->home_dir = PDB_NOT_QUITE_NULL;
 744         }
 745 
 746         return pdb_set_init_flags(sampass, PDB_SMBHOME, flag);
 747 }
 748 
 749 /*********************************************************************
 750  Set the user's account description.
 751  ********************************************************************/
 752 
 753 bool pdb_set_acct_desc(struct samu *sampass, const char *acct_desc, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 754 {
 755         if (acct_desc) { 
 756                 sampass->acct_desc = talloc_strdup(sampass, acct_desc);
 757 
 758                 if (!sampass->acct_desc) {
 759                         DEBUG(0, ("pdb_set_acct_desc: talloc_strdup() failed!\n"));
 760                         return False;
 761                 }
 762         } else {
 763                 sampass->acct_desc = PDB_NOT_QUITE_NULL;
 764         }
 765 
 766         return pdb_set_init_flags(sampass, PDB_ACCTDESC, flag);
 767 }
 768 
 769 /*********************************************************************
 770  Set the user's workstation allowed list.
 771  ********************************************************************/
 772 
 773 bool pdb_set_workstations(struct samu *sampass, const char *workstations, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 774 {
 775         if (workstations) { 
 776                 DEBUG(10, ("pdb_set_workstations: setting workstations %s, was %s\n", workstations,
 777                         (sampass->workstations)?(sampass->workstations):"NULL"));
 778 
 779                 sampass->workstations = talloc_strdup(sampass, workstations);
 780 
 781                 if (!sampass->workstations) {
 782                         DEBUG(0, ("pdb_set_workstations: talloc_strdup() failed!\n"));
 783                         return False;
 784                 }
 785         } else {
 786                 sampass->workstations = PDB_NOT_QUITE_NULL;
 787         }
 788 
 789         return pdb_set_init_flags(sampass, PDB_WORKSTATIONS, flag);
 790 }
 791 
 792 /*********************************************************************
 793  ********************************************************************/
 794 
 795 bool pdb_set_comment(struct samu *sampass, const char *comment, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 796 {
 797         if (comment) { 
 798                 sampass->comment = talloc_strdup(sampass, comment);
 799 
 800                 if (!sampass->comment) {
 801                         DEBUG(0, ("pdb_set_comment: talloc_strdup() failed!\n"));
 802                         return False;
 803                 }
 804         } else {
 805                 sampass->comment = PDB_NOT_QUITE_NULL;
 806         }
 807 
 808         return pdb_set_init_flags(sampass, PDB_COMMENT, flag);
 809 }
 810 
 811 /*********************************************************************
 812  Set the user's dial string.
 813  ********************************************************************/
 814 
 815 bool pdb_set_munged_dial(struct samu *sampass, const char *munged_dial, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 816 {
 817         if (munged_dial) { 
 818                 sampass->munged_dial = talloc_strdup(sampass, munged_dial);
 819 
 820                 if (!sampass->munged_dial) {
 821                         DEBUG(0, ("pdb_set_munged_dial: talloc_strdup() failed!\n"));
 822                         return False;
 823                 }
 824         } else {
 825                 sampass->munged_dial = PDB_NOT_QUITE_NULL;
 826         }
 827 
 828         return pdb_set_init_flags(sampass, PDB_MUNGEDDIAL, flag);
 829 }
 830 
 831 /*********************************************************************
 832  Set the user's NT hash.
 833  ********************************************************************/
 834 
 835 bool pdb_set_nt_passwd(struct samu *sampass, const uint8 pwd[NT_HASH_LEN], enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 836 {
 837         data_blob_clear_free(&sampass->nt_pw);
 838 
 839        if (pwd) {
 840                sampass->nt_pw =
 841                        data_blob_talloc(sampass, pwd, NT_HASH_LEN);
 842        } else {
 843                sampass->nt_pw = data_blob_null;
 844        }
 845 
 846         return pdb_set_init_flags(sampass, PDB_NTPASSWD, flag);
 847 }
 848 
 849 /*********************************************************************
 850  Set the user's LM hash.
 851  ********************************************************************/
 852 
 853 bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 854 {
 855         data_blob_clear_free(&sampass->lm_pw);
 856 
 857         /* on keep the password if we are allowing LANMAN authentication */
 858 
 859         if (pwd && lp_lanman_auth() ) {
 860                 sampass->lm_pw = data_blob_talloc(sampass, pwd, LM_HASH_LEN);
 861         } else {
 862                 sampass->lm_pw = data_blob_null;
 863         }
 864 
 865         return pdb_set_init_flags(sampass, PDB_LMPASSWD, flag);
 866 }
 867 
 868 /*********************************************************************
 869  Set the user's password history hash. historyLen is the number of 
 870  PW_HISTORY_SALT_LEN+SALTED_MD5_HASH_LEN length
 871  entries to store in the history - this must match the size of the uint8 array
 872  in pwd.
 873 ********************************************************************/
 874 
 875 bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 876 {
 877         if (historyLen && pwd){
 878                 sampass->nt_pw_his = data_blob_talloc(sampass,
 879                                                 pwd, historyLen*PW_HISTORY_ENTRY_LEN);
 880                 if (!sampass->nt_pw_his.length) {
 881                         DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
 882                         return False;
 883                 }
 884         } else {
 885                 sampass->nt_pw_his = data_blob_talloc(sampass, NULL, 0);
 886         }
 887 
 888         return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
 889 }
 890 
 891 /*********************************************************************
 892  Set the user's plaintext password only (base procedure, see helper
 893  below)
 894  ********************************************************************/
 895 
 896 bool pdb_set_plaintext_pw_only(struct samu *sampass, const char *password, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 897 {
 898         if (password) { 
 899                 if (sampass->plaintext_pw!=NULL) 
 900                         memset(sampass->plaintext_pw,'\0',strlen(sampass->plaintext_pw)+1);
 901 
 902                 sampass->plaintext_pw = talloc_strdup(sampass, password);
 903 
 904                 if (!sampass->plaintext_pw) {
 905                         DEBUG(0, ("pdb_set_unknown_str: talloc_strdup() failed!\n"));
 906                         return False;
 907                 }
 908         } else {
 909                 sampass->plaintext_pw = NULL;
 910         }
 911 
 912         return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
 913 }
 914 
 915 bool pdb_set_bad_password_count(struct samu *sampass, uint16 bad_password_count, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 916 {
 917         sampass->bad_password_count = bad_password_count;
 918         return pdb_set_init_flags(sampass, PDB_BAD_PASSWORD_COUNT, flag);
 919 }
 920 
 921 bool pdb_set_logon_count(struct samu *sampass, uint16 logon_count, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 922 {
 923         sampass->logon_count = logon_count;
 924         return pdb_set_init_flags(sampass, PDB_LOGON_COUNT, flag);
 925 }
 926 
 927 bool pdb_set_unknown_6(struct samu *sampass, uint32 unkn, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 928 {
 929         sampass->unknown_6 = unkn;
 930         return pdb_set_init_flags(sampass, PDB_UNKNOWN6, flag);
 931 }
 932 
 933 bool pdb_set_hours(struct samu *sampass, const uint8 *hours, enum pdb_value_state flag)
     /* [<][>][^][v][top][bottom][index][help] */
 934 {
 935         if (!hours) {
 936                 memset ((char *)sampass->hours, 0, MAX_HOURS_LEN);
 937         } else {
 938                 memcpy (sampass->hours, hours, MAX_HOURS_LEN);
 939         }
 940 
 941         return pdb_set_init_flags(sampass, PDB_HOURS, flag);
 942 }
 943 
 944 bool pdb_set_backend_private_data(struct samu *sampass, void *private_data, 
     /* [<][>][^][v][top][bottom][index][help] */
 945                                    void (*free_fn)(void **), 
 946                                    const struct pdb_methods *my_methods, 
 947                                    enum pdb_value_state flag)
 948 {
 949         if (sampass->backend_private_data &&
 950             sampass->backend_private_data_free_fn) {
 951                 sampass->backend_private_data_free_fn(
 952                         &sampass->backend_private_data);
 953         }
 954 
 955         sampass->backend_private_data = private_data;
 956         sampass->backend_private_data_free_fn = free_fn;
 957         sampass->backend_private_methods = my_methods;
 958 
 959         return pdb_set_init_flags(sampass, PDB_BACKEND_PRIVATE_DATA, flag);
 960 }
 961 
 962 
 963 /* Helpful interfaces to the above */
 964 
 965 bool pdb_set_pass_can_change(struct samu *sampass, bool canchange)
     /* [<][>][^][v][top][bottom][index][help] */
 966 {
 967         return pdb_set_pass_can_change_time(sampass, 
 968                                      canchange ? 0 : get_time_t_max(),
 969                                      PDB_CHANGED);
 970 }
 971 
 972 
 973 /*********************************************************************
 974  Set the user's PLAINTEXT password.  Used as an interface to the above.
 975  Also sets the last change time to NOW.
 976  ********************************************************************/
 977 
 978 bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
     /* [<][>][^][v][top][bottom][index][help] */
 979 {
 980         uchar new_lanman_p16[LM_HASH_LEN];
 981         uchar new_nt_p16[NT_HASH_LEN];
 982 
 983         if (!plaintext)
 984                 return False;
 985 
 986         /* Calculate the MD4 hash (NT compatible) of the password */
 987         E_md4hash(plaintext, new_nt_p16);
 988 
 989         if (!pdb_set_nt_passwd (sampass, new_nt_p16, PDB_CHANGED)) 
 990                 return False;
 991 
 992         if (!E_deshash(plaintext, new_lanman_p16)) {
 993                 /* E_deshash returns false for 'long' passwords (> 14
 994                    DOS chars).  This allows us to match Win2k, which
 995                    does not store a LM hash for these passwords (which
 996                    would reduce the effective password length to 14 */
 997 
 998                 if (!pdb_set_lanman_passwd (sampass, NULL, PDB_CHANGED)) 
 999                         return False;
1000         } else {
1001                 if (!pdb_set_lanman_passwd (sampass, new_lanman_p16, PDB_CHANGED)) 
1002                         return False;
1003         }
1004 
1005         if (!pdb_set_plaintext_pw_only (sampass, plaintext, PDB_CHANGED)) 
1006                 return False;
1007 
1008         if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
1009                 return False;
1010 
1011         /* Store the password history. */
1012         if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
1013                 uchar *pwhistory;
1014                 uint32 pwHistLen;
1015                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
1016                 if (pwHistLen != 0){
1017                         uint32 current_history_len;
1018                         /* We need to make sure we don't have a race condition here - the
1019                            account policy history length can change between when the pw_history
1020                            was first loaded into the struct samu struct and now.... JRA. */
1021                         pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
1022 
1023                         if (current_history_len != pwHistLen) {
1024                                 /* After closing and reopening struct samu the history
1025                                         values will sync up. We can't do this here. */
1026 
1027                                 /* current_history_len > pwHistLen is not a problem - we
1028                                         have more history than we need. */
1029 
1030                                 if (current_history_len < pwHistLen) {
1031                                         /* Ensure we have space for the needed history. */
1032                                         uchar *new_history = (uchar *)TALLOC(sampass,
1033                                                                 pwHistLen*PW_HISTORY_ENTRY_LEN);
1034                                         if (!new_history) {
1035                                                 return False;
1036                                         }
1037 
1038                                         /* And copy it into the new buffer. */
1039                                         if (current_history_len) {
1040                                                 memcpy(new_history, pwhistory,
1041                                                         current_history_len*PW_HISTORY_ENTRY_LEN);
1042                                         }
1043                                         /* Clearing out any extra space. */
1044                                         memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
1045                                                 '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
1046                                         /* Finally replace it. */
1047                                         pwhistory = new_history;
1048                                 }
1049                         }
1050                         if (pwhistory && pwHistLen){
1051                                 /* Make room for the new password in the history list. */
1052                                 if (pwHistLen > 1) {
1053                                         memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
1054                                                 pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
1055                                 }
1056                                 /* Create the new salt as the first part of the history entry. */
1057                                 generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
1058 
1059                                 /* Generate the md5 hash of the salt+new password as the second
1060                                         part of the history entry. */
1061 
1062                                 E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
1063                                 pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
1064                         } else {
1065                                 DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
1066                         }
1067                 } else {
1068                         /* Set the history length to zero. */
1069                         pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
1070                 }
1071         }
1072 
1073         return True;
1074 }
1075 
1076 /* check for any PDB_SET/CHANGED field and fill the appropriate mask bit */
1077 uint32 pdb_build_fields_present(struct samu *sampass)
     /* [<][>][^][v][top][bottom][index][help] */
1078 {
1079         /* value set to all for testing */
1080         return 0x00ffffff;
1081 }

/* [<][>][^][v][top][bottom][index][help] */