root/source3/torture/pdbtest.c

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

DEFINITIONS

This source file includes following definitions.
  1. samu_correct
  2. main

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    passdb testing utility
   4    
   5    Copyright (C) Wilco Baan Hofman 2006
   6    Copyright (C) Jelmer Vernooij 2006
   7 
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 3 of the License, or
  11    (at your option) any later version.
  12    
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17    
  18    You should have received a copy of the GNU General Public License
  19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 
  23 #include "includes.h"
  24 
  25 static bool samu_correct(struct samu *s1, struct samu *s2)
     /* [<][>][^][v][top][bottom][index][help] */
  26 {
  27         bool ret = True;
  28         uint32 s1_len, s2_len;
  29         const char *s1_buf, *s2_buf;
  30         const uint8 *d1_buf, *d2_buf;
  31                 
  32         /* Check Unix username */
  33         s1_buf = pdb_get_username(s1);
  34         s2_buf = pdb_get_username(s2);
  35         if (s2_buf == NULL && s1_buf != NULL) {
  36                 DEBUG(0, ("Username is not set\n"));
  37                 ret = False;
  38         } else if (s1_buf == NULL) {
  39                 /* Do nothing */
  40         } else if (strcmp(s1_buf,s2_buf)) {
  41                 DEBUG(0, ("Username not written correctly, want %s, got \"%s\"\n",
  42                                         pdb_get_username(s1),
  43                                         pdb_get_username(s2)));
  44                 ret = False;
  45         }
  46 
  47         /* Check NT username */
  48         s1_buf = pdb_get_nt_username(s1);
  49         s2_buf = pdb_get_nt_username(s2);
  50         if (s2_buf == NULL && s1_buf != NULL) {
  51                 DEBUG(0, ("NT Username is not set\n"));
  52                 ret = False;
  53         } else if (s1_buf == NULL) {
  54                 /* Do nothing */
  55         } else if (strcmp(s1_buf, s2_buf)) {
  56                 DEBUG(0, ("NT Username not written correctly, want \"%s\", got \"%s\"\n",
  57                                         pdb_get_nt_username(s1),
  58                                         pdb_get_nt_username(s2)));
  59                 ret = False;
  60         }
  61 
  62         /* Check acct ctrl */
  63         if (pdb_get_acct_ctrl(s1) != pdb_get_acct_ctrl(s2)) {
  64                 DEBUG(0, ("Acct ctrl field not written correctly, want %d (0x%X), got %d (0x%X)\n",
  65                                         pdb_get_acct_ctrl(s1),
  66                                         pdb_get_acct_ctrl(s1),
  67                                         pdb_get_acct_ctrl(s2),
  68                                         pdb_get_acct_ctrl(s2)));
  69                 ret = False;
  70         }
  71 
  72         /* Check NT password */
  73         d1_buf = pdb_get_nt_passwd(s1);
  74         d2_buf = pdb_get_nt_passwd(s2);
  75         if (d2_buf == NULL && d1_buf != NULL) {
  76                 DEBUG(0, ("NT password is not set\n"));
  77                 ret = False;
  78         } else if (d1_buf == NULL) {
  79                 /* Do nothing */
  80         } else if (memcmp(d1_buf, d2_buf, NT_HASH_LEN)) {
  81                 DEBUG(0, ("NT password not written correctly\n"));
  82                 ret = False;
  83         }
  84 
  85         /* Check lanman password */
  86         d1_buf = pdb_get_lanman_passwd(s1);
  87         d2_buf = pdb_get_lanman_passwd(s2);
  88         if (d2_buf == NULL && d1_buf != NULL) {
  89                 DEBUG(0, ("Lanman password is not set\n"));
  90         } else if (d1_buf == NULL) {
  91                 /* Do nothing */
  92         } else if (memcmp(d1_buf, d2_buf, NT_HASH_LEN)) {
  93                 DEBUG(0, ("Lanman password not written correctly\n"));
  94                 ret = False;
  95         }
  96 
  97         /* Check password history */
  98         d1_buf = pdb_get_pw_history(s1, &s1_len);
  99         d2_buf = pdb_get_pw_history(s2, &s2_len);
 100         if (d2_buf == NULL && d1_buf != NULL) {
 101                 DEBUG(0, ("Password history is not set\n"));
 102         } else if (d1_buf == NULL) {
 103                 /* Do nothing */
 104         } else if (s1_len != s1_len) {
 105                 DEBUG(0, ("Password history not written correctly, lengths differ, want %d, got %d\n",
 106                                         s1_len, s2_len));
 107                 ret = False;
 108         } else if (strncmp(s1_buf, s2_buf, s1_len)) {
 109                 DEBUG(0, ("Password history not written correctly\n"));
 110                 ret = False;
 111         }
 112 
 113         /* Check logon time */
 114         if (pdb_get_logon_time(s1) != pdb_get_logon_time(s2)) {
 115                 DEBUG(0, ("Logon time is not written correctly\n"));
 116                 ret = False;
 117         }
 118 
 119         /* Check logoff time */
 120         if (pdb_get_logoff_time(s1) != pdb_get_logoff_time(s2)) {
 121                 DEBUG(0, ("Logoff time is not written correctly\n"));
 122                 ret = False;
 123         }
 124         
 125         /* Check kickoff time */
 126         if (pdb_get_kickoff_time(s1) != pdb_get_logoff_time(s2)) {
 127                 DEBUG(0, ("Kickoff time is not written correctly\n"));
 128                 ret = False;
 129         }
 130         
 131         /* Check bad password time */
 132         if (pdb_get_bad_password_time(s1) != pdb_get_bad_password_time(s2)) {
 133                 DEBUG(0, ("Bad password time is not written correctly\n"));
 134                 ret = False;
 135         }
 136         
 137         /* Check password last set time */
 138         if (pdb_get_pass_last_set_time(s1) != pdb_get_pass_last_set_time(s2)) {
 139                 DEBUG(0, ("Password last set time is not written correctly\n"));
 140                 ret = False;
 141         }
 142         
 143         /* Check password can change time */
 144         if (pdb_get_pass_can_change_time(s1) != pdb_get_pass_can_change_time(s2)) {
 145                 DEBUG(0, ("Password can change time is not written correctly\n"));
 146                 ret = False;
 147         }
 148         
 149         /* Check password must change time */
 150         if (pdb_get_pass_must_change_time(s1) != pdb_get_pass_must_change_time(s2)) {
 151                 DEBUG(0, ("Password must change time is not written correctly\n"));
 152                 ret = False;
 153         }
 154         
 155         /* Check logon divs */
 156         if (pdb_get_logon_divs(s1) != pdb_get_logon_divs(s2)) {
 157                 DEBUG(0, ("Logon divs not written correctly\n"));
 158                 ret = False;
 159         }
 160         
 161         /* Check logon hours */
 162         if (pdb_get_hours_len(s1) != pdb_get_hours_len(s2)) {
 163                 DEBUG(0, ("Logon hours length not written correctly\n"));
 164                 ret = False;
 165         } else if (pdb_get_hours_len(s1) != 0) {
 166                 d1_buf = pdb_get_hours(s1);
 167                 d2_buf = pdb_get_hours(s2);
 168                 if (d2_buf == NULL && d2_buf != NULL) {
 169                         DEBUG(0, ("Logon hours is not set\n"));
 170                         ret = False;
 171                 } else if (d1_buf == NULL) {
 172                         /* Do nothing */
 173                 } else if (memcmp(d1_buf, d2_buf, MAX_HOURS_LEN)) {
 174                         DEBUG(0, ("Logon hours is not written correctly\n"));
 175                         ret = False;
 176                 }
 177         }
 178         
 179         /* Check profile path */
 180         s1_buf = pdb_get_profile_path(s1);
 181         s2_buf = pdb_get_profile_path(s2);
 182         if (s2_buf == NULL && s1_buf != NULL) {
 183                 DEBUG(0, ("Profile path is not set\n"));
 184                 ret = False;
 185         } else if (s1_buf == NULL) {
 186                 /* Do nothing */
 187         } else if (strcmp(s1_buf, s2_buf)) {
 188                 DEBUG(0, ("Profile path is not written correctly\n"));
 189                 ret = False;
 190         }
 191 
 192         /* Check home dir */
 193         s1_buf = pdb_get_homedir(s1);
 194         s2_buf = pdb_get_homedir(s2);
 195         if (s2_buf == NULL && s1_buf != NULL) {
 196                 DEBUG(0, ("Home dir is not set\n"));
 197                 ret = False;
 198         } else if (s1_buf == NULL) {
 199                 /* Do nothing */
 200         } else if (strcmp(s1_buf, s2_buf)) {
 201                 DEBUG(0, ("Home dir is not written correctly\n"));
 202                 ret = False;
 203         }
 204         
 205         /* Check logon script */
 206         s1_buf = pdb_get_logon_script(s1);
 207         s2_buf = pdb_get_logon_script(s2);
 208         if (s2_buf == NULL && s1_buf != NULL) {
 209                 DEBUG(0, ("Logon script not set\n"));
 210                 ret = False;
 211         } else if (s1_buf == NULL) {
 212                 /* Do nothing */
 213         } else if (strcmp(s1_buf, s2_buf)) {
 214                 DEBUG(0, ("Logon script is not written correctly\n"));
 215                 ret = False;
 216         }
 217         
 218         /* TODO Check user and group sids */
 219                 
 220         return ret;     
 221 }
 222 
 223 
 224 int main(int argc, char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 225 {
 226         TALLOC_CTX *ctx;
 227         struct samu *out = NULL;
 228         struct samu *in = NULL;
 229         NTSTATUS rv;
 230         int i;
 231         struct timeval tv;
 232         bool error = False;
 233         struct passwd *pwd;
 234         uint8 *buf;
 235         uint32 expire, min_age, history;
 236         struct pdb_methods *pdb;
 237         poptContext pc;
 238         static const char *backend = NULL;
 239         static const char *unix_user = "nobody";
 240         struct poptOption long_options[] = {
 241                 {"username", 'u', POPT_ARG_STRING, &unix_user, 0, "Unix user to use for testing", "USERNAME" },
 242                 {"backend", 'b', POPT_ARG_STRING, &backend, 0, "Backend to use if not default", "BACKEND[:SETTINGS]" },
 243                 POPT_AUTOHELP
 244                 POPT_COMMON_SAMBA
 245                 POPT_TABLEEND
 246         };
 247 
 248         load_case_tables();
 249 
 250         pc = poptGetContext("vfstest", argc, (const char **) argv,
 251                             long_options, 0);
 252 
 253         poptSetOtherOptionHelp(pc, "backend[:settings] username");
 254         
 255         while(poptGetNextOpt(pc) != -1);
 256 
 257         poptFreeContext(pc);
 258 
 259         /* Load configuration */
 260         lp_load(get_dyn_CONFIGFILE(), False, False, True, True);
 261         setup_logging("pdbtest", True);
 262 
 263         if (backend == NULL) {
 264                 backend = lp_passdb_backend();
 265         }
 266 
 267         rv = make_pdb_method_name(&pdb, backend);
 268         if (NT_STATUS_IS_ERR(rv)) {
 269                 fprintf(stderr, "Error initializing '%s': %s\n", backend, get_friendly_nt_error_msg(rv));
 270                 exit(1);
 271         }
 272         
 273         ctx = talloc_init("PDBTEST");
 274         
 275         if (!(out = samu_new(ctx))) {
 276                 fprintf(stderr, "Can't create samu structure.\n");
 277                 exit(1);
 278         }
 279         
 280         if ((pwd = getpwnam_alloc(ctx, unix_user)) == NULL) {
 281                 fprintf(stderr, "Error getting user information for %s\n", unix_user);
 282                 exit(1);
 283         }
 284         
 285         samu_set_unix(out, pwd);
 286 
 287         pdb_set_profile_path(out, "\\\\torture\\profile", PDB_SET);
 288         pdb_set_homedir(out, "\\\\torture\\home", PDB_SET);
 289         pdb_set_logon_script(out, "torture_script.cmd", PDB_SET);
 290 
 291         pdb_get_account_policy(AP_PASSWORD_HISTORY, &history);
 292         if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) {
 293                 buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN);
 294         } else {
 295                 buf = (uint8 *)TALLOC(ctx, history * PW_HISTORY_ENTRY_LEN);
 296         }
 297 
 298         /* Generate some random hashes */
 299         GetTimeOfDay(&tv);
 300         srand(tv.tv_usec);
 301         for (i = 0; i < NT_HASH_LEN; i++) {
 302                 buf[i] = (uint8) rand();
 303         }
 304         pdb_set_nt_passwd(out, buf, PDB_SET);
 305         for (i = 0; i < LM_HASH_LEN; i++) {
 306                 buf[i] = (uint8) rand();
 307         }
 308         pdb_set_lanman_passwd(out, buf, PDB_SET);
 309         for (i = 0; i < history * PW_HISTORY_ENTRY_LEN; i++) {
 310                 buf[i] = (uint8) rand();
 311         }
 312         pdb_set_pw_history(out, buf, history, PDB_SET);
 313 
 314         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire);
 315         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age);
 316         pdb_set_pass_last_set_time(out, time(NULL), PDB_SET);
 317         
 318         if (expire == 0 || expire == (uint32)-1) {
 319                 pdb_set_pass_must_change_time(out, get_time_t_max(), PDB_SET);
 320         } else {
 321                 pdb_set_pass_must_change_time(out, time(NULL)+expire, PDB_SET);
 322         }
 323 
 324         if (min_age == (uint32)-1) {
 325                 pdb_set_pass_can_change_time(out, 0, PDB_SET);
 326         } else {
 327                 pdb_set_pass_can_change_time(out, time(NULL)+min_age, PDB_SET);
 328         }
 329         
 330         /* Create account */
 331         if (!NT_STATUS_IS_OK(rv = pdb->add_sam_account(pdb, out))) {
 332                 fprintf(stderr, "Error in add_sam_account: %s\n", 
 333                                 get_friendly_nt_error_msg(rv));
 334                 exit(1);
 335         }
 336 
 337         if (!(in = samu_new(ctx))) {
 338                 fprintf(stderr, "Can't create samu structure.\n");
 339                 exit(1);
 340         }
 341         
 342         /* Get account information through getsampwnam() */
 343         if (NT_STATUS_IS_ERR(pdb->getsampwnam(pdb, in, out->username))) {
 344                 fprintf(stderr, "Error getting sampw of added user %s.\n",
 345                                 out->username);
 346                 if (!NT_STATUS_IS_OK(rv = pdb->delete_sam_account(pdb, out))) {
 347                         fprintf(stderr, "Error in delete_sam_account %s\n", 
 348                                         get_friendly_nt_error_msg(rv));
 349                 }
 350                 TALLOC_FREE(ctx);
 351         }
 352         
 353         /* Verify integrity */
 354         if (samu_correct(out, in)) {
 355                 printf("User info written correctly\n");
 356         } else {
 357                 printf("User info NOT written correctly\n");
 358                 error = True;
 359         }
 360         
 361         /* Delete account */
 362         if (!NT_STATUS_IS_OK(rv = pdb->delete_sam_account(pdb, out))) {
 363                 fprintf(stderr, "Error in delete_sam_account %s\n", 
 364                                         get_friendly_nt_error_msg(rv));
 365         }
 366 
 367         TALLOC_FREE(ctx);
 368 
 369         if (error) {
 370                 return 1;
 371         }
 372         return 0;
 373 }

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