int main(int argc, char **argv) { TALLOC_CTX *ctx; struct samu *out = NULL; struct samu *in = NULL; NTSTATUS rv; int i; struct timeval tv; BOOL error = False; struct passwd *pwd; uint8 *buf; uint32 expire, min_age, history; struct pdb_methods *pdb; poptContext pc; static const char *backend = NULL; static const char *unix_user = "******"; struct poptOption long_options[] = { {"username", 'u', POPT_ARG_STRING, &unix_user, 0, "Unix user to use for testing", "USERNAME" }, {"backend", 'b', POPT_ARG_STRING, &backend, 0, "Backend to use if not default", "BACKEND[:SETTINGS]" }, POPT_AUTOHELP POPT_COMMON_SAMBA POPT_TABLEEND }; load_case_tables(); pc = poptGetContext("vfstest", argc, (const char **) argv, long_options, 0); poptSetOtherOptionHelp(pc, "backend[:settings] username"); while(poptGetNextOpt(pc) != -1); poptFreeContext(pc); /* Load configuration */ lp_load(dyn_CONFIGFILE, False, False, True, True); setup_logging("pdbtest", True); if (backend == NULL) { backend = lp_passdb_backend(); } rv = make_pdb_method_name(&pdb, backend); if (NT_STATUS_IS_ERR(rv)) { fprintf(stderr, "Error initializing '%s': %s\n", backend, get_friendly_nt_error_msg(rv)); exit(1); } ctx = talloc_init("PDBTEST"); if (!(out = samu_new(ctx))) { fprintf(stderr, "Can't create samu structure.\n"); exit(1); } if ((pwd = getpwnam_alloc(ctx, unix_user)) == NULL) { fprintf(stderr, "Error getting user information for %s\n", unix_user); exit(1); } samu_set_unix(out, pwd); pdb_set_profile_path(out, "\\\\torture\\profile", PDB_SET); pdb_set_homedir(out, "\\\\torture\\home", PDB_SET); pdb_set_logon_script(out, "torture_script.cmd", PDB_SET); pdb_get_account_policy(AP_PASSWORD_HISTORY, &history); if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) { buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN); } else { buf = (uint8 *)TALLOC(ctx, history * PW_HISTORY_ENTRY_LEN); } /* Generate some random hashes */ GetTimeOfDay(&tv); srand(tv.tv_usec); for (i = 0; i < NT_HASH_LEN; i++) { buf[i] = (uint8) rand(); } pdb_set_nt_passwd(out, buf, PDB_SET); for (i = 0; i < LM_HASH_LEN; i++) { buf[i] = (uint8) rand(); } pdb_set_lanman_passwd(out, buf, PDB_SET); for (i = 0; i < history * PW_HISTORY_ENTRY_LEN; i++) { buf[i] = (uint8) rand(); } pdb_set_pw_history(out, buf, history, PDB_SET); pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire); pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age); pdb_set_pass_last_set_time(out, time(NULL), PDB_SET); if (expire == 0 || expire == (uint32)-1) { pdb_set_pass_must_change_time(out, get_time_t_max(), PDB_SET); } else { pdb_set_pass_must_change_time(out, time(NULL)+expire, PDB_SET); } if (min_age == (uint32)-1) { pdb_set_pass_can_change_time(out, 0, PDB_SET); } else { pdb_set_pass_can_change_time(out, time(NULL)+min_age, PDB_SET); } /* Create account */ if (!NT_STATUS_IS_OK(rv = pdb->add_sam_account(pdb, out))) { fprintf(stderr, "Error in add_sam_account: %s\n", get_friendly_nt_error_msg(rv)); exit(1); } if (!(in = samu_new(ctx))) { fprintf(stderr, "Can't create samu structure.\n"); exit(1); } /* Get account information through getsampwnam() */ if (NT_STATUS_IS_ERR(pdb->getsampwnam(pdb, in, out->username))) { fprintf(stderr, "Error getting sampw of added user %s.\n", out->username); if (!NT_STATUS_IS_OK(rv = pdb->delete_sam_account(pdb, out))) { fprintf(stderr, "Error in delete_sam_account %s\n", get_friendly_nt_error_msg(rv)); } TALLOC_FREE(ctx); } /* Verify integrity */ if (samu_correct(out, in)) { printf("User info written correctly\n"); } else { printf("User info NOT written correctly\n"); error = True; } /* Delete account */ if (!NT_STATUS_IS_OK(rv = pdb->delete_sam_account(pdb, out))) { fprintf(stderr, "Error in delete_sam_account %s\n", get_friendly_nt_error_msg(rv)); } pdb->setsampwent(pdb, False, 0); while (NT_STATUS_IS_OK(pdb->getsampwent(pdb, out))) { if (pdb_get_username(out) == NULL) { fprintf(stderr, "Got bad username through getsampwent()\n"); error = True; break; } if (NT_STATUS_IS_ERR(pdb->getsampwnam(pdb, in, pdb_get_username(out)))) { fprintf(stderr, "Error getting samu through getsampwnam() of an account we got through getsampwent!\n"); error = True; continue; } if (!samu_correct(out, in)) { printf("Record gotten through getsampwnam() differs from same record through getsampwent()\n"); } } pdb->endsampwent(pdb); TALLOC_FREE(ctx); if (error) { return 1; } return 0; }
NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info, char *unix_username, struct passwd *pwd) { NTSTATUS status; struct samu *sampass = NULL; char *qualified_name = NULL; TALLOC_CTX *mem_ctx = NULL; struct dom_sid u_sid; enum lsa_SidType type; struct auth_serversupplied_info *result; /* * The SID returned in server_info->sam_account is based * on our SAM sid even though for a pure UNIX account this should * not be the case as it doesn't really exist in the SAM db. * This causes lookups on "[in]valid users" to fail as they * will lookup this name as a "Unix User" SID to check against * the user token. Fix this by adding the "Unix User"\unix_username * SID to the sid array. The correct fix should probably be * changing the server_info->sam_account user SID to be a * S-1-22 Unix SID, but this might break old configs where * plaintext passwords were used with no SAM backend. */ mem_ctx = talloc_init("make_server_info_pw_tmp"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } qualified_name = talloc_asprintf(mem_ctx, "%s\\%s", unix_users_domain_name(), unix_username ); if (!qualified_name) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_MEMORY; } if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL, NULL, NULL, &u_sid, &type)) { TALLOC_FREE(mem_ctx); return NT_STATUS_NO_SUCH_USER; } TALLOC_FREE(mem_ctx); if (type != SID_NAME_USER) { return NT_STATUS_NO_SUCH_USER; } if ( !(sampass = samu_new( NULL )) ) { return NT_STATUS_NO_MEMORY; } status = samu_set_unix( sampass, pwd ); if (!NT_STATUS_IS_OK(status)) { return status; } /* In pathological cases the above call can set the account * name to the DOMAIN\username form. Reset the account name * using unix_username */ pdb_set_username(sampass, unix_username, PDB_SET); /* set the user sid to be the calculated u_sid */ pdb_set_user_sid(sampass, &u_sid, PDB_SET); result = make_server_info(NULL); if (result == NULL) { TALLOC_FREE(sampass); return NT_STATUS_NO_MEMORY; } status = samu_to_SamInfo3(result, sampass, global_myname(), &result->info3, &result->extra); TALLOC_FREE(sampass); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("Failed to convert samu to info3: %s\n", nt_errstr(status))); TALLOC_FREE(result); return status; } result->unix_name = talloc_strdup(result, unix_username); result->sanitized_username = sanitize_username(result, unix_username); if ((result->unix_name == NULL) || (result->sanitized_username == NULL)) { TALLOC_FREE(result); return NT_STATUS_NO_MEMORY; } result->utok.uid = pwd->pw_uid; result->utok.gid = pwd->pw_gid; *server_info = result; return NT_STATUS_OK; }
static int new_machine (struct pdb_methods *in, const char *machine_in) { struct samu *sam_pwent=NULL; fstring machinename; fstring machineaccount; struct passwd *pwd = NULL; get_global_sam_sid(); if (strlen(machine_in) == 0) { fprintf(stderr, "No machine name given\n"); return -1; } fstrcpy(machinename, machine_in); machinename[15]= '\0'; if (machinename[strlen (machinename) -1] == '$') machinename[strlen (machinename) -1] = '\0'; strlower_m(machinename); fstrcpy(machineaccount, machinename); fstrcat(machineaccount, "$"); if ((pwd = getpwnam_alloc(NULL, machineaccount))) { if ( (sam_pwent = samu_new( NULL )) == NULL ) { fprintf(stderr, "Memory allocation error!\n"); TALLOC_FREE(pwd); return -1; } if ( !NT_STATUS_IS_OK(samu_set_unix(sam_pwent, pwd )) ) { fprintf(stderr, "Could not init sam from pw\n"); TALLOC_FREE(pwd); return -1; } TALLOC_FREE(pwd); } else { if ( (sam_pwent = samu_new( NULL )) == NULL ) { fprintf(stderr, "Could not init sam from pw\n"); return -1; } } pdb_set_plaintext_passwd (sam_pwent, machinename); pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED); pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED); if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { print_user_info (in, machineaccount, True, False); } else { fprintf (stderr, "Unable to add machine! (does it already exist?)\n"); TALLOC_FREE(sam_pwent); return -1; } TALLOC_FREE(sam_pwent); return 0; }