Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
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;
}