示例#1
0
文件: pdbedit.c 项目: OPSF/uClinux
/*********************************************************
 List Users
**********************************************************/
static int print_users_list (struct pdb_methods *in, BOOL verbosity, BOOL smbpwdstyle)
{
	struct samu *sam_pwent=NULL;
	BOOL check;
	
	check = NT_STATUS_IS_OK(in->setsampwent(in, False, 0));
	if (!check) {
		return 1;
	}

	check = True;
	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		return 1;
	}

	while (check && NT_STATUS_IS_OK(in->getsampwent (in, sam_pwent))) {
		if (verbosity)
			printf ("---------------\n");
		print_sam_info (sam_pwent, verbosity, smbpwdstyle);
		TALLOC_FREE(sam_pwent);
		
		if ( (sam_pwent = samu_new( NULL )) == NULL ) {
			check = False;
		}
	}
	if (check) 
		TALLOC_FREE(sam_pwent);
	
	in->endsampwent(in);
	return 0;
}
示例#2
0
文件: pdbedit.c 项目: OPSF/uClinux
static int delete_machine_entry (struct pdb_methods *in, const char *machinename)
{
	fstring name;
	struct samu *samaccount = NULL;

	if (strlen(machinename) == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}
	
	fstrcpy(name, machinename);
	name[15] = '\0';
	if (name[strlen(name)-1] != '$')
		fstrcat (name, "$");

	if ( (samaccount = samu_new( NULL )) == NULL ) {
		return -1;
	}

	if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, name))) {
		fprintf (stderr, "machine %s does not exist in the passdb\n", name);
		return -1;
	}

	if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
		fprintf (stderr, "Unable to delete machine %s\n", name);
		return -1;
	}

	return 0;
}
示例#3
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int delete_user_entry(const char *username)
{
	struct samu *samaccount;

	samaccount = samu_new(NULL);
	if (!samaccount) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (!pdb_getsampwnam(samaccount, username)) {
		fprintf (stderr,
			 "user %s does not exist in the passdb\n", username);
		TALLOC_FREE(samaccount);
		return -1;
	}

	if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
		fprintf (stderr, "Unable to delete user %s\n", username);
		TALLOC_FREE(samaccount);
		return -1;
	}

	TALLOC_FREE(samaccount);
	return 0;
}
示例#4
0
/* Lookup groups a user is a member of.  I wish Unix had a call like this! */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
				  TALLOC_CTX *mem_ctx,
				  const DOM_SID *user_sid,
				  uint32 *num_groups, DOM_SID **user_gids)
{
	NTSTATUS result;
	DOM_SID *groups = NULL;
	gid_t *gids = NULL;
	size_t ngroups = 0;
	struct samu *user;

	if ( (user = samu_new(mem_ctx)) == NULL ) {
		return NT_STATUS_NO_MEMORY;
	}

	if ( !pdb_getsampwsid( user, user_sid ) ) {
		return NT_STATUS_NO_SUCH_USER;
	}

	result = pdb_enum_group_memberships( mem_ctx, user, &groups, &gids, &ngroups );

	TALLOC_FREE( user );

	*num_groups = (uint32)ngroups;
	*user_gids = groups;

	return result;
}
示例#5
0
文件: pdbedit.c 项目: Gazzonyx/samba
/*********************************************************
 Fix a list of Users for uninitialised passwords
**********************************************************/
static int fix_users_list(void)
{
	struct pdb_search *u_search;
	struct samr_displayentry userentry;
	struct samu *sam_pwent;
	TALLOC_CTX *tosctx;
	struct dom_sid user_sid;
	NTSTATUS status;
	bool bret;
	int ret;

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return 1;
	}

	u_search = pdb_search_users(tosctx, 0);
	if (!u_search) {
		fprintf(stderr, "User Search failed!\n");
		ret = 1;
		goto done;
	}

	while (u_search->next_entry(u_search, &userentry)) {

		sam_pwent = samu_new(tosctx);
		if (sam_pwent == NULL) {
			fprintf(stderr, "Out of memory!\n");
			ret = 1;
			goto done;
		}

		sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);

		bret = pdb_getsampwsid(sam_pwent, &user_sid);
		if (!bret) {
			DEBUG(2, ("getsampwsid failed\n"));
			TALLOC_FREE(sam_pwent);
			continue;
		}

		status = pdb_update_sam_account(sam_pwent);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Update of user %s failed!\n",
			       pdb_get_username(sam_pwent));
		}
		TALLOC_FREE(sam_pwent);
	}

	ret = 0;

done:
	TALLOC_FREE(tosctx);
	return ret;
}
示例#6
0
文件: pdbedit.c 项目: Gazzonyx/samba
/*********************************************************
 List Users
**********************************************************/
static int print_users_list(bool verbosity, bool smbpwdstyle)
{
	struct pdb_search *u_search;
	struct samr_displayentry userentry;
	struct samu *sam_pwent;
	TALLOC_CTX *tosctx;
	struct dom_sid user_sid;
	bool bret;
	int ret;

	tosctx = talloc_tos();
	if (!tosctx) {
		DEBUG(0, ("talloc failed\n"));
		return 1;
	}

	u_search = pdb_search_users(tosctx, 0);
	if (!u_search) {
		DEBUG(0, ("User Search failed!\n"));
		ret = 1;
		goto done;
	}

	while (u_search->next_entry(u_search, &userentry)) {

		sam_pwent = samu_new(tosctx);
		if (sam_pwent == NULL) {
			DEBUG(0, ("talloc failed\n"));
			ret = 1;
			goto done;
		}

		sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);

		bret = pdb_getsampwsid(sam_pwent, &user_sid);
		if (!bret) {
			DEBUG(2, ("getsampwsid failed\n"));
			TALLOC_FREE(sam_pwent);
			continue;
		}

		if (verbosity) {
			printf ("---------------\n");
		}
		print_sam_info(sam_pwent, verbosity, smbpwdstyle);
		TALLOC_FREE(sam_pwent);
	}

	ret = 0;

done:
	TALLOC_FREE(tosctx);
	return ret;
}
示例#7
0
文件: pdbedit.c 项目: OPSF/uClinux
/*********************************************************
 Fix a list of Users for uninitialised passwords
**********************************************************/
static int fix_users_list (struct pdb_methods *in)
{
	struct samu *sam_pwent=NULL;
	BOOL check;
	
	check = NT_STATUS_IS_OK(in->setsampwent(in, False, 0));
	if (!check) {
		return 1;
	}

	check = True;
	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		return 1;
	}

	while (check && NT_STATUS_IS_OK(in->getsampwent (in, sam_pwent))) {
		printf("Updating record for user %s\n", pdb_get_username(sam_pwent));
	
		if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
			printf("Update of user %s failed!\n", pdb_get_username(sam_pwent));
		}
		TALLOC_FREE(sam_pwent);
		if ( (sam_pwent = samu_new( NULL )) == NULL ) {
			check = False;
		}
		if (!check) {
			fprintf(stderr, "Failed to initialise new struct samu structure (out of memory?)\n");
		}
			
	}
	if (check) 
		TALLOC_FREE(sam_pwent);
	
	in->endsampwent(in);
	return 0;
}
示例#8
0
/**
 * update the encrypted smbpasswd file from the plaintext username and password
 *
 *  this ugly hack needs to die, but not quite yet, I think people still use it...
 **/
static BOOL update_smbpassword_file(const char *user, const char *password)
{
    struct samu 	*sampass;
    BOOL            ret;

    if ( !(sampass = samu_new( NULL )) ) {
        return False;
    }

    become_root();
    ret = pdb_getsampwnam(sampass, user);
    unbecome_root();

    if(ret == False) {
        DEBUG(0,("pdb_getsampwnam returned NULL\n"));
        TALLOC_FREE(sampass);
        return False;
    }

    /*
     * Remove the account disabled flag - we are updating the
     * users password from a login.
     */
    if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {
        TALLOC_FREE(sampass);
        return False;
    }

    if (!pdb_set_plaintext_passwd (sampass, password)) {
        TALLOC_FREE(sampass);
        return False;
    }

    /* Now write it into the file. */
    become_root();

    ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass));

    unbecome_root();

    if (ret) {
        DEBUG(3,("pdb_update_sam_account returned %d\n",ret));
    }

    TALLOC_FREE(sampass);
    return ret;
}
示例#9
0
文件: pdbedit.c 项目: OPSF/uClinux
static int delete_user_entry (struct pdb_methods *in, const char *username)
{
	struct samu *samaccount = NULL;

	if ( (samaccount = samu_new( NULL )) == NULL ) {
		return -1;
	}

	if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, username))) {
		fprintf (stderr, "user %s does not exist in the passdb\n", username);
		return -1;
	}

	if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
		fprintf (stderr, "Unable to delete user %s\n", username);
		return -1;
	}
	return 0;
}
示例#10
0
文件: pdbedit.c 项目: OPSF/uClinux
static int print_user_info (struct pdb_methods *in, const char *username, BOOL verbosity, BOOL smbpwdstyle)
{
	struct samu *sam_pwent=NULL;
	BOOL ret;

	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		return -1;
	}

	ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));

	if (ret==False) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle);
	TALLOC_FREE(sam_pwent);
	
	return ret;
}
示例#11
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int delete_machine_entry(const char *machinename)
{
	struct samu *samaccount = NULL;
	const char *name;

	if (strlen(machinename) == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	samaccount = samu_new(NULL);
	if (!samaccount) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machinename[strlen(machinename)-1] != '$') {
		name = talloc_asprintf(samaccount, "%s$", machinename);
	} else {
		name = machinename;
	}

	if (!pdb_getsampwnam(samaccount, name)) {
		fprintf (stderr,
			 "machine %s does not exist in the passdb\n", name);
		TALLOC_FREE(samaccount);
		return -1;
	}

	if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
		fprintf (stderr, "Unable to delete machine %s\n", name);
		TALLOC_FREE(samaccount);
		return -1;
	}

	TALLOC_FREE(samaccount);
	return 0;
}
示例#12
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int print_user_info(const char *username,
			   bool verbosity, bool smbpwdstyle)
{
	struct samu *sam_pwent = NULL;
	bool bret;
	int ret;

	sam_pwent = samu_new(NULL);
	if (!sam_pwent) {
		return -1;
	}

	bret = pdb_getsampwnam(sam_pwent, username);
	if (!bret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle);

	TALLOC_FREE(sam_pwent);
	return ret;
}
示例#13
0
文件: pdbedit.c 项目: Gazzonyx/samba
/*********************************************************
 Add New User
**********************************************************/
static int new_user(const char *username, const char *fullname,
		    const char *homedir, const char *drive,
		    const char *script, const char *profile,
		    char *user_sid, bool stdin_get)
{
	char *pwd1 = NULL, *pwd2 = NULL;
	char *err = NULL, *msg = NULL;
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	NTSTATUS status;
	struct dom_sid u_sid;
	int flags;
	int ret;

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (user_sid) {
		if (get_sid_from_cli_string(&u_sid, user_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
	}

	pwd1 = get_pass( "new password:"******"retype new password:"******"Failed to read passwords.\n");
		return -1;
	}
	ret = strcmp(pwd1, pwd2);
	if (ret != 0) {
		fprintf (stderr, "Passwords do not match!\n");
		goto done;
	}

	flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;

	status = local_password_change(username, flags, pwd1, &err, &msg);
	if (!NT_STATUS_IS_OK(status)) {
		if (err) fprintf(stderr, "%s", err);
		ret = -1;
		goto done;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		fprintf(stderr, "Out of memory!\n");
		ret = -1;
		goto done;
	}

	if (!pdb_getsampwnam(sam_pwent, username)) {
		fprintf(stderr, "User %s not found!\n", username);
		ret = -1;
		goto done;
	}

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
	if (user_sid)
		pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);

	status = pdb_update_sam_account(sam_pwent);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr,
			"Failed to modify entry for user %s.!\n",
			username);
		ret = -1;
		goto done;
	}

	print_user_info(username, True, False);
	ret = 0;

done:
	if (pwd1) memset(pwd1, 0, strlen(pwd1));
	if (pwd2) memset(pwd2, 0, strlen(pwd2));
	SAFE_FREE(pwd1);
	SAFE_FREE(pwd2);
	SAFE_FREE(err);
	SAFE_FREE(msg);
	TALLOC_FREE(sam_pwent);
	return ret;
}
示例#14
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int set_machine_info(const char *machinename,
			    const char *account_control,
			    const char *machine_sid)
{
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	uint32_t acb_flags;
	uint32_t not_settable;
	uint32_t new_flags;
	struct dom_sid m_sid;
	char *name;
	int len;
	bool ret;

	len = strlen(machinename);
	if (len == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		return 1;
	}

	if (machinename[len-1] == '$') {
		name = talloc_strdup(sam_pwent, machinename);
	} else {
		name = talloc_asprintf(sam_pwent, "%s$", machinename);
	}
	if (!name) {
		fprintf(stderr, "Out of memory!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (!strlower_m(name)) {
		fprintf(stderr, "strlower_m %s failed\n", name);
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	ret = pdb_getsampwnam(sam_pwent, name);
	if (!ret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (account_control) {
		not_settable = ~(ACB_DISABLED);

		new_flags = pdb_decode_acct_ctrl(account_control);

		if (new_flags & not_settable) {
			fprintf(stderr, "Can only set [D] flags\n");
			TALLOC_FREE(sam_pwent);
			return -1;
		}

		acb_flags = pdb_get_acct_ctrl(sam_pwent);

		pdb_set_acct_ctrl(sam_pwent,
				  (acb_flags & not_settable) | new_flags,
				  PDB_CHANGED);
	}
	if (machine_sid) {
		if (get_sid_from_cli_string(&m_sid, machine_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
		pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
	}

	if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
		print_user_info(name, True, False);
	} else {
		fprintf (stderr, "Unable to modify entry!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
示例#15
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int set_user_info(const char *username, const char *fullname,
			 const char *homedir, const char *acct_desc,
			 const char *drive, const char *script,
			 const char *profile, const char *account_control,
			 const char *user_sid, const char *user_domain,
			 const bool badpw, const bool hours,
			 const char *kickoff_time)
{
	bool updated_autolock = False, updated_badpw = False;
	struct samu *sam_pwent;
	uint8_t hours_array[MAX_HOURS_LEN];
	uint32_t hours_len;
	uint32_t acb_flags;
	uint32_t not_settable;
	uint32_t new_flags;
	struct dom_sid u_sid;
	bool ret;

	sam_pwent = samu_new(NULL);
	if (!sam_pwent) {
		return 1;
	}

	ret = pdb_getsampwnam(sam_pwent, username);
	if (!ret) {
		fprintf (stderr, "Username not found!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}

	if (hours) {
		hours_len = pdb_get_hours_len(sam_pwent);
		memset(hours_array, 0xff, hours_len);

		pdb_set_hours(sam_pwent, hours_array, hours_len, PDB_CHANGED);
	}

	if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
		DEBUG(2,("pdb_update_autolock_flag failed.\n"));
	}

	if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
		DEBUG(2,("pdb_update_bad_password_count failed.\n"));
	}

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (acct_desc)
		pdb_set_acct_desc(sam_pwent, acct_desc, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive(sam_pwent,drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
	if (user_domain)
		pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);

	if (account_control) {
		not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ |
				 ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK);

		new_flags = pdb_decode_acct_ctrl(account_control);

		if (new_flags & not_settable) {
			fprintf(stderr, "Can only set [NDHLX] flags\n");
			TALLOC_FREE(sam_pwent);
			return -1;
		}

		acb_flags = pdb_get_acct_ctrl(sam_pwent);

		pdb_set_acct_ctrl(sam_pwent,
				  (acb_flags & not_settable) | new_flags,
				  PDB_CHANGED);
	}
	if (user_sid) {
		if (get_sid_from_cli_string(&u_sid, user_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
		pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
	}

	if (badpw) {
		pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
	}

	if (kickoff_time) {
		char *endptr;
		time_t value = get_time_t_max();

		if (strcmp(kickoff_time, "never") != 0) {
			uint32_t num = strtoul(kickoff_time, &endptr, 10);

			if ((endptr == kickoff_time) || (endptr[0] != '\0')) {
				fprintf(stderr, "Failed to parse kickoff time\n");
				return -1;
			}

			value = convert_uint32_t_to_time_t(num);
		}

		pdb_set_kickoff_time(sam_pwent, value, PDB_CHANGED);
	}

	if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
		print_user_info(username, True, False);
	} else {
		fprintf (stderr, "Unable to modify entry!\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
示例#16
0
文件: pdbedit.c 项目: OPSF/uClinux
static int export_database (struct pdb_methods *in, 
                            struct pdb_methods *out, 
                            const char *username) 
{
	struct samu *user = NULL;
	NTSTATUS status;

	DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "******"));

	status = in->setsampwent(in, 0, 0);
	if ( NT_STATUS_IS_ERR(status) ) {
		fprintf(stderr, "Unable to set account database iterator for %s!\n", 
			in->name);
		return 1;
	}

	if ( ( user = samu_new( NULL ) ) == NULL ) {
		fprintf(stderr, "export_database: Memory allocation failure!\n");
		return 1;
	}

	while ( NT_STATUS_IS_OK(in->getsampwent(in, user)) ) 
	{
		DEBUG(4, ("Processing account %s\n", user->username));

		/* If we don't have a specific user or if we do and 
		   the login name matches */

		if ( !username || (strcmp(username, user->username) == 0)) {
			struct samu *account;

			if ( (account = samu_new( NULL )) == NULL ) {
				fprintf(stderr, "export_database: Memory allocation failure!\n");
				TALLOC_FREE( user );
				in->endsampwent( in );
				return 1;
			}

			printf("Importing account for %s...", user->username);
			if ( !NT_STATUS_IS_OK(out->getsampwnam( out, account, user->username )) ) {
				status = out->add_sam_account(out, user);
			} else {
				status = out->update_sam_account( out, user );
			}

			if ( NT_STATUS_IS_OK(status) ) {
				printf( "ok\n");
			} else {
				printf( "failed\n");
			}

			TALLOC_FREE( account );
		}

		/* clean up and get ready for another run */

		TALLOC_FREE( user );

		if ( ( user = samu_new( NULL ) ) == NULL ) {
			fprintf(stderr, "export_database: Memory allocation failure!\n");
			return 1;
		}
	}

	TALLOC_FREE( user );

	in->endsampwent(in);

	return 0;
}
示例#17
0
文件: pdbedit.c 项目: OPSF/uClinux
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;
}
示例#18
0
static int process_root(int local_flags)
{
	struct passwd  *pwd;
	int result = 0;
	char *old_passwd = NULL;

	if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) {
		char *ldap_admin_dn = lp_ldap_admin_dn();
		if ( ! *ldap_admin_dn ) {
			DEBUG(0,("ERROR: 'ldap admin dn' not defined! Please check your smb.conf\n"));
			goto done;
		}

		printf("Setting stored password for \"%s\" in secrets.tdb\n", ldap_admin_dn);
		if ( ! *ldap_secret ) {
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			fstrcpy(ldap_secret, new_passwd);
		}
		if (!store_ldap_admin_pw(ldap_secret)) {
			DEBUG(0,("ERROR: Failed to store the ldap admin password!\n"));
		}
		goto done;
	}

	/* Ensure passdb startup(). */
	if(!initialize_password_db(False)) {
		DEBUG(0, ("Failed to open passdb!\n"));
		exit(1);
	}
		
	/* Ensure we have a SAM sid. */
	get_global_sam_sid();

	/*
	 * Ensure both add/delete user are not set
	 * Ensure add/delete user and either remote machine or join domain are
	 * not both set.
	 */	
	if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) || 
	   ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && 
		(remote_machine != NULL))) {
		usage();
	}
	
	/* Only load interfaces if we are doing network operations. */

	if (remote_machine) {
		load_interfaces();
	}

	if (!user_name[0] && (pwd = getpwuid_alloc(NULL, geteuid()))) {
		fstrcpy(user_name, pwd->pw_name);
		TALLOC_FREE(pwd);
	} 

	if (!user_name[0]) {
		fprintf(stderr,"You must specify a username\n");
		exit(1);
	}

	if (local_flags & LOCAL_TRUST_ACCOUNT) {
		/* add the $ automatically */
		static fstring buf;

		/*
		 * Remove any trailing '$' before we
		 * generate the initial machine password.
		 */

		if (user_name[strlen(user_name)-1] == '$') {
			user_name[strlen(user_name)-1] = 0;
		}

		if (local_flags & LOCAL_ADD_USER) {
		        SAFE_FREE(new_passwd);
			new_passwd = smb_xstrdup(user_name);
			strlower_m(new_passwd);
		}

		/*
		 * Now ensure the username ends in '$' for
		 * the machine add.
		 */

		slprintf(buf, sizeof(buf)-1, "%s$", user_name);
		fstrcpy(user_name, buf);
	} else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
		static fstring buf;

		if ((local_flags & LOCAL_ADD_USER) && (new_passwd == NULL)) {
			/*
			 * Prompt for trusting domain's account password
			 */
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			if(!new_passwd) {
				fprintf(stderr, "Unable to get newpassword.\n");
				exit(1);
			}
		}
		
		/* prepare uppercased and '$' terminated username */
		slprintf(buf, sizeof(buf) - 1, "%s$", user_name);
		fstrcpy(user_name, buf);
		
	} else {
		
		if (remote_machine != NULL) {
			old_passwd = get_pass("Old SMB password:"******"talloc fail for struct samu.\n");
					exit(1);
				}
				if (!pdb_getsampwnam(sampass, user_name)) {
					fprintf(stderr, "Failed to find user %s in passdb backend.\n",
						user_name );
					exit(1);
				}

				if(pdb_get_nt_passwd(sampass) == NULL) {
					local_flags |= LOCAL_SET_PASSWORD;
				}
				TALLOC_FREE(sampass);
			}
		}
		
		if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
			new_passwd = prompt_for_new_password(stdin_passwd_get);
			
			if(!new_passwd) {
				fprintf(stderr, "Unable to get new password.\n");
				exit(1);
			}
		}
	}

	if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name,
					     old_passwd, new_passwd,
					     local_flags))) {
		fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
		result = 1;
		goto done;
	} 

	if(remote_machine) {
		printf("Password changed for user %s on %s.\n", user_name, remote_machine );
	} else if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD|LOCAL_SET_PASSWORD))) {
		struct samu *sampass = NULL;
		
		sampass = samu_new( NULL );
		if (!sampass) {
			fprintf(stderr, "talloc fail for struct samu.\n");
			exit(1);
		}

		if (!pdb_getsampwnam(sampass, user_name)) {
			fprintf(stderr, "Failed to find user %s in passdb backend.\n",
				user_name );
			exit(1);
		}

		printf("Password changed for user %s.", user_name );
		if(pdb_get_acct_ctrl(sampass)&ACB_DISABLED) {
			printf(" User has disabled flag set.");
		}
		if(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) {
			printf(" User has no password flag set.");
		}
		printf("\n");
		TALLOC_FREE(sampass);
	}

 done:
	SAFE_FREE(new_passwd);
	return result;
}
示例#19
0
文件: pdbedit.c 项目: OPSF/uClinux
/*********************************************************
 Add New User
**********************************************************/
static int new_user (struct pdb_methods *in, const char *username,
			const char *fullname, const char *homedir,
			const char *drive, const char *script,
			const char *profile, char *user_sid, BOOL stdin_get)
{
	struct samu *sam_pwent;
	char *password1, *password2;
	int rc_pwd_cmp;
	struct passwd *pwd;

	get_global_sam_sid();

	if ( !(pwd = getpwnam_alloc( NULL, username )) ) {
		DEBUG(0,("Cannot locate Unix account for %s\n", username));
		return -1;
	}

	if ( (sam_pwent = samu_new( NULL )) == NULL ) {
		DEBUG(0, ("Memory allocation failure!\n"));
		return -1;
	}

	if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) {
		TALLOC_FREE( sam_pwent );
		TALLOC_FREE( pwd );
		DEBUG(0, ("could not create account to add new user %s\n", username));
		return -1;
	}

	password1 = get_pass( "new password:"******"retype new password:"******"Passwords do not match!\n");
		TALLOC_FREE(sam_pwent);
	} else {
		pdb_set_plaintext_passwd(sam_pwent, password1);
	}

	memset(password1, 0, strlen(password1));
	SAFE_FREE(password1);
	memset(password2, 0, strlen(password2));
	SAFE_FREE(password2);

	/* pwds do _not_ match? */
	if (rc_pwd_cmp)
		return -1;

	if (fullname)
		pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
	if (homedir)
		pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED);
	if (drive)
		pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED);
	if (script)
		pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
	if (profile)
		pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
	if (user_sid) {
		DOM_SID u_sid;
		if (!string_to_sid(&u_sid, user_sid)) {
			/* not a complete sid, may be a RID, try building a SID */
			int u_rid;
			
			if (sscanf(user_sid, "%d", &u_rid) != 1) {
				fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
				TALLOC_FREE(sam_pwent);
				return -1;
			}
			sid_copy(&u_sid, get_global_sam_sid());
			sid_append_rid(&u_sid, u_rid);
		}
		pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
	}
	
	pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED);
	
	if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) { 
		print_user_info (in, username, True, False);
	} else {
		fprintf (stderr, "Unable to add user! (does it already exist?)\n");
		TALLOC_FREE(sam_pwent);
		return -1;
	}
	TALLOC_FREE(sam_pwent);
	return 0;
}
示例#20
0
NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx,
				char *ntuser,
				char *ntdomain,
				char *username,
				struct passwd *pw,
				struct PAC_LOGON_INFO *logon_info,
				bool mapped_to_guest, bool username_was_mapped,
				DATA_BLOB *session_key,
				struct auth_session_info **session_info)
{
	NTSTATUS status;
	struct auth_serversupplied_info *server_info;

	if (mapped_to_guest) {
		status = make_server_info_guest(mem_ctx, &server_info);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_guest failed: %s!\n",
				  nt_errstr(status)));
			return status;
		}

	} else if (logon_info) {
		/* pass the unmapped username here since map_username()
		   will be called again in make_server_info_info3() */

		status = make_server_info_info3(mem_ctx,
						ntuser, ntdomain,
						&server_info,
						&logon_info->info3);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_info3 failed: %s!\n",
				  nt_errstr(status)));
			return status;
		}

	} else {
		/*
		 * We didn't get a PAC, we have to make up the user
		 * ourselves. Try to ask the pdb backend to provide
		 * SID consistency with ntlmssp session setup
		 */
		struct samu *sampass;
		/* The stupid make_server_info_XX functions here
		   don't take a talloc context. */
		struct auth_serversupplied_info *tmp = NULL;

		sampass = samu_new(talloc_tos());
		if (sampass == NULL) {
			return NT_STATUS_NO_MEMORY;
		}

		if (pdb_getsampwnam(sampass, username)) {
			DEBUG(10, ("found user %s in passdb, calling "
				   "make_server_info_sam\n", username));
			status = make_server_info_sam(&tmp, sampass);
		} else {
			/*
			 * User not in passdb, make it up artificially
			 */
			DEBUG(10, ("didn't find user %s in passdb, calling "
				   "make_server_info_pw\n", username));
			status = make_server_info_pw(&tmp, username, pw);
		}
		TALLOC_FREE(sampass);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("make_server_info_[sam|pw] failed: %s!\n",
				  nt_errstr(status)));
			return status;
                }

		/* make_server_info_pw does not set the domain. Without this
		 * we end up with the local netbios name in substitutions for
		 * %D. */

		if (server_info->info3 != NULL) {
			server_info->info3->base.domain.string =
				talloc_strdup(server_info->info3, ntdomain);
		}
	}

	server_info->nss_token |= username_was_mapped;

	status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info);
	talloc_free(server_info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10,("failed to create local token: %s\n",
			  nt_errstr(status)));
		return status;
	}

	return NT_STATUS_OK;
}
示例#21
0
/***************************************************************************
 Renames a struct samu
 - check for the posix user/rename user script
 - Add and lock the new user record
 - rename the posix user
 - rewrite the rid->username record
 - delete the old user
 - unlock the new user record
***************************************************************************/
static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
					  struct samu *old_acct,
					  const char *newname)
{
	struct samu      *new_acct = NULL;
	char *rename_script = NULL;
	int              rename_ret;
	fstring          oldname_lower;
	fstring          newname_lower;

	/* can't do anything without an external script */

	if ( !(new_acct = samu_new( talloc_tos() )) ) {
		return NT_STATUS_NO_MEMORY;
	}

	rename_script = lp_rename_user_script(new_acct);
	if (!rename_script) {
		TALLOC_FREE(new_acct);
		return NT_STATUS_NO_MEMORY;
	}
	if (!*rename_script) {
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;
	}

	if ( !pdb_copy_sam_account(new_acct, old_acct)
		|| !pdb_set_username(new_acct, newname, PDB_CHANGED))
	{
		TALLOC_FREE(new_acct);
		return NT_STATUS_NO_MEMORY;
	}

	/* open the database */
	if ( !tdbsam_open( tdbsam_filename ) ) {
		DEBUG(0, ("tdbsam_getsampwnam: failed to open %s!\n",
			  tdbsam_filename));
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;
	}

	if (dbwrap_transaction_start(db_sam) != 0) {
		DEBUG(0, ("Could not start transaction\n"));
		TALLOC_FREE(new_acct);
		return NT_STATUS_ACCESS_DENIED;

	}

	/* add the new account and lock it */
	if ( !tdb_update_samacct_only(new_acct, TDB_INSERT) ) {
		goto cancel;
	}

	/* Rename the posix user.  Follow the semantics of _samr_create_user()
	   so that we lower case the posix name but preserve the case in passdb */

	fstrcpy( oldname_lower, pdb_get_username(old_acct) );
	if (!strlower_m( oldname_lower )) {
		goto cancel;
	}

	fstrcpy( newname_lower, newname );
	if (!strlower_m( newname_lower )) {
		goto cancel;
	}

	rename_script = talloc_string_sub2(new_acct,
				rename_script,
				"%unew",
				newname_lower,
				true,
				false,
				true);
	if (!rename_script) {
		goto cancel;
	}
	rename_script = talloc_string_sub2(new_acct,
				rename_script,
				"%uold",
				oldname_lower,
				true,
				false,
				true);
	if (!rename_script) {
		goto cancel;
	}
	rename_ret = smbrun(rename_script, NULL, NULL);

	DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n",
				rename_script, rename_ret));

	if (rename_ret != 0) {
		goto cancel;
	}

	smb_nscd_flush_user_cache();

	/* rewrite the rid->username record */

	if ( !tdb_update_ridrec_only( new_acct, TDB_MODIFY) ) {
		goto cancel;
	}

	tdb_delete_samacct_only( old_acct );

	if (dbwrap_transaction_commit(db_sam) != 0) {
		/*
		 * Ok, we're screwed. We've changed the posix account, but
		 * could not adapt passdb.tdb. Shall we change the posix
		 * account back?
		 */
		DEBUG(0, ("transaction_commit failed\n"));
		TALLOC_FREE(new_acct);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;	
	}

	TALLOC_FREE(new_acct );
	return NT_STATUS_OK;

 cancel:
	if (dbwrap_transaction_cancel(db_sam) != 0) {
		smb_panic("transaction_cancel failed");
	}

	TALLOC_FREE(new_acct);

	return NT_STATUS_ACCESS_DENIED;	
}
示例#22
0
static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
			   int flag)
{
	uint32_t oldrid;
	uint32_t newrid;

	if (!(newrid = pdb_get_user_rid(newpwd))) {
		DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n",
			 pdb_get_username(newpwd)));
		return False;
	}

	oldrid = newrid;

	/* open the database */

	if ( !tdbsam_open( tdbsam_filename ) ) {
		DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
		return False;
	}

	if (dbwrap_transaction_start(db_sam) != 0) {
		DEBUG(0, ("Could not start transaction\n"));
		return false;
	}

	/* If we are updating, we may be changing this users RID. Retrieve the old RID
	   so we can check. */

	if (flag == TDB_MODIFY) {
		struct samu *account = samu_new(talloc_tos());
		if (account == NULL) {
			DEBUG(0,("tdb_update_sam: samu_new() failed\n"));
			goto cancel;
		}
		if (!NT_STATUS_IS_OK(tdbsam_getsampwnam(my_methods, account, pdb_get_username(newpwd)))) {
			DEBUG(0,("tdb_update_sam: tdbsam_getsampwnam() for %s failed\n",
				pdb_get_username(newpwd)));
			TALLOC_FREE(account);
			goto cancel;
		}
		if (!(oldrid = pdb_get_user_rid(account))) {
			DEBUG(0,("tdb_update_sam: pdb_get_user_rid() failed\n"));
			TALLOC_FREE(account);
			goto cancel;
		}
		TALLOC_FREE(account);
	}

	/* Update the new samu entry. */
	if (!tdb_update_samacct_only(newpwd, flag)) {
		goto cancel;
	}

	/* Now take care of the case where the RID changed. We need
	 * to delete the old RID key and add the new. */

	if (flag == TDB_MODIFY && newrid != oldrid) { 
		fstring keystr;

		/* Delete old RID key */
		DEBUG(10, ("tdb_update_sam: Deleting key for RID %u\n", oldrid));
		fstr_sprintf(keystr, "%s%.8x", RIDPREFIX, oldrid);
		if (!NT_STATUS_IS_OK(dbwrap_delete_bystring(db_sam, keystr))) {
			DEBUG(0, ("tdb_update_sam: Can't delete %s\n", keystr));
			goto cancel;
		}
		/* Insert new RID key */
		DEBUG(10, ("tdb_update_sam: Inserting key for RID %u\n", newrid));
		if (!tdb_update_ridrec_only(newpwd, TDB_INSERT)) {
			goto cancel;
		}
	} else {
		DEBUG(10, ("tdb_update_sam: %s key for RID %u\n",
			flag == TDB_MODIFY ? "Updating" : "Inserting", newrid));
		if (!tdb_update_ridrec_only(newpwd, flag)) {
			goto cancel;
		}
	}

	if (dbwrap_transaction_commit(db_sam) != 0) {
		DEBUG(0, ("Could not commit transaction\n"));
		return false;
	}

	return true;

 cancel:
	if (dbwrap_transaction_cancel(db_sam) != 0) {
		smb_panic("transaction_cancel failed");
	}
	return false;
}
示例#23
0
文件: pdbtest.c 项目: AllardJ/Tomato
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;
}
示例#24
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;
}
示例#25
0
文件: auth_sam.c 项目: AllardJ/Tomato
static NTSTATUS check_sam_security(const struct auth_context *auth_context,
				   void *my_private_data, 
				   TALLOC_CTX *mem_ctx,
				   const auth_usersupplied_info *user_info, 
				   auth_serversupplied_info **server_info)
{
	struct samu *sampass=NULL;
	BOOL ret;
	NTSTATUS nt_status;
	NTSTATUS update_login_attempts_status;
	DATA_BLOB user_sess_key = data_blob(NULL, 0);
	DATA_BLOB lm_sess_key = data_blob(NULL, 0);
	BOOL updated_autolock = False, updated_badpw = False;

	if (!user_info || !auth_context) {
		return NT_STATUS_UNSUCCESSFUL;
	}

	/* Can't use the talloc version here, because the returned struct gets
	   kept on the server_info */

	if ( !(sampass = samu_new( NULL )) ) {
		return NT_STATUS_NO_MEMORY;
	}

	/* get the account information */

	become_root();
	ret = pdb_getsampwnam(sampass, user_info->internal_username);
	unbecome_root();

	if (ret == False) {
		DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
			 "passdb.\n", user_info->internal_username));
		TALLOC_FREE(sampass);
		return NT_STATUS_NO_SUCH_USER;
	}

	/* see if autolock flag needs to be updated */
	if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL)
		pdb_update_autolock_flag(sampass, &updated_autolock);
	/* Quit if the account was locked out. */
	if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
		DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", pdb_get_username(sampass)));
		return NT_STATUS_ACCOUNT_LOCKED_OUT;
	}

	nt_status = sam_password_ok(auth_context, mem_ctx, sampass, 
				    user_info, &user_sess_key, &lm_sess_key);

	/* Notify passdb backend of login success/failure. If not NT_STATUS_OK the backend doesn't like the login */
	update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
	if (!NT_STATUS_IS_OK(update_login_attempts_status))
		nt_status = update_login_attempts_status;

	if (!NT_STATUS_IS_OK(nt_status)) {
		if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && 
		    pdb_get_acct_ctrl(sampass) &ACB_NORMAL) {  
			pdb_increment_bad_password_count(sampass);
			updated_badpw = True;
		} else {
			pdb_update_bad_password_count(sampass, 
						      &updated_badpw);
		}
		if (updated_autolock || updated_badpw){
			become_root();
			if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
				DEBUG(1, ("Failed to modify entry.\n"));
			unbecome_root();
		}
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		TALLOC_FREE(sampass);
		return nt_status;
	}

	if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && 
	    (pdb_get_bad_password_count(sampass) > 0)){
		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
		updated_badpw = True;
	}

	if (updated_autolock || updated_badpw){
		become_root();
		if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
			DEBUG(1, ("Failed to modify entry.\n"));
		unbecome_root();
 	}

	nt_status = sam_account_ok(mem_ctx, sampass, user_info);

	if (!NT_STATUS_IS_OK(nt_status)) {
		TALLOC_FREE(sampass);
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		return nt_status;
	}

	become_root();
	nt_status = make_server_info_sam(server_info, sampass);
	unbecome_root();

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
		TALLOC_FREE(sampass);
		data_blob_free(&user_sess_key);
		data_blob_free(&lm_sess_key);
		return nt_status;
	}

	(*server_info)->user_session_key =
		data_blob_talloc(*server_info, user_sess_key.data,
				 user_sess_key.length);
	data_blob_free(&user_sess_key);

	(*server_info)->lm_session_key =
		data_blob_talloc(*server_info, lm_sess_key.data,
				 lm_sess_key.length);
	data_blob_free(&lm_sess_key);

	(*server_info)->was_mapped |= user_info->was_mapped;

	return nt_status;
}
示例#26
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int new_machine(const char *machinename, char *machine_sid)
{
	char *err = NULL, *msg = NULL;
	struct samu *sam_pwent = NULL;
	TALLOC_CTX *tosctx;
	NTSTATUS status;
	struct dom_sid m_sid;
	char *compatpwd;
	char *name;
	int flags;
	int len;
	int ret;

	len = strlen(machinename);
	if (len == 0) {
		fprintf(stderr, "No machine name given\n");
		return -1;
	}

	tosctx = talloc_tos();
	if (!tosctx) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machine_sid) {
		if (get_sid_from_cli_string(&m_sid, machine_sid)) {
			fprintf(stderr, "Failed to parse SID\n");
			return -1;
		}
	}

	compatpwd = talloc_strdup(tosctx, machinename);
	if (!compatpwd) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (machinename[len-1] == '$') {
		name = talloc_strdup(tosctx, machinename);
		compatpwd[len-1] = '\0';
	} else {
		name = talloc_asprintf(tosctx, "%s$", machinename);
	}
	if (!name) {
		fprintf(stderr, "Out of memory!\n");
		return -1;
	}

	if (!strlower_m(name)) {
		fprintf(stderr, "strlower_m %s failed\n", name);
		return -1;
	}

	flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;

	status = local_password_change(name, flags, compatpwd, &err, &msg);

	if (!NT_STATUS_IS_OK(status)) {
		if (err) fprintf(stderr, "%s", err);
		ret = -1;
	}

	sam_pwent = samu_new(tosctx);
	if (!sam_pwent) {
		fprintf(stderr, "Out of memory!\n");
		ret = -1;
		goto done;
	}

	if (!pdb_getsampwnam(sam_pwent, name)) {
		fprintf(stderr, "Machine %s not found!\n", name);
		ret = -1;
		goto done;
	}

	if (machine_sid)
		pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);

	status = pdb_update_sam_account(sam_pwent);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr,
			"Failed to modify entry for %s.!\n", name);
		ret = -1;
		goto done;
	}

	print_user_info(name, True, False);
	ret = 0;

done:
	SAFE_FREE(err);
	SAFE_FREE(msg);
	TALLOC_FREE(sam_pwent);
	return ret;
}
示例#27
0
文件: pdbedit.c 项目: Gazzonyx/samba
static int export_database (struct pdb_methods *in,
                            struct pdb_methods *out,
                            const char *username)
{
	NTSTATUS status;
	struct pdb_search *u_search;
	struct samr_displayentry userentry;

	DEBUG(3, ("export_database: username=\"%s\"\n", username ? username : "******"));

	u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
	if (u_search == NULL) {
		DEBUG(0, ("pdb_search_init failed\n"));
		return 1;
	}

	if (!in->search_users(in, u_search, 0)) {
		DEBUG(0, ("Could not start searching users\n"));
		TALLOC_FREE(u_search);
		return 1;
	}

	while (u_search->next_entry(u_search, &userentry)) {
		struct samu *user;
		struct samu *account;
		struct dom_sid user_sid;

		DEBUG(4, ("Processing account %s\n", userentry.account_name));

		if ((username != NULL)
		    && (strcmp(username, userentry.account_name) != 0)) {
			/*
			 * ignore unwanted users
			 */
			continue;
		}

		user = samu_new(talloc_tos());
		if (user == NULL) {
			DEBUG(0, ("talloc failed\n"));
			break;
		}

		sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);

		status = in->getsampwsid(in, user, &user_sid);

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(2, ("getsampwsid failed: %s\n",
				  nt_errstr(status)));
			TALLOC_FREE(user);
			continue;
		}

		account = samu_new(NULL);
		if (account == NULL) {
			fprintf(stderr, "export_database: Memory allocation "
				"failure!\n");
			TALLOC_FREE( user );
			TALLOC_FREE(u_search);
			return 1;
		}

		printf("Importing account for %s...", user->username);
		status = out->getsampwnam(out, account, user->username);

		if (NT_STATUS_IS_OK(status)) {
			status = out->update_sam_account( out, user );
		} else {
			status = out->add_sam_account(out, user);
		}

		if ( NT_STATUS_IS_OK(status) ) {
			printf( "ok\n");
		} else {
			printf( "failed\n");
		}

		TALLOC_FREE( account );
		TALLOC_FREE( user );
	}

	TALLOC_FREE(u_search);

	return 0;
}
示例#28
0
int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                        int argc, const char **argv)
{
	unsigned int ctrl;
	int retval, *ret_data = NULL;
	struct samu *sampass = NULL;
	const char *name;
	void (*oldsig_handler)(int) = NULL;
	bool found;

	/* Points to memory managed by the PAM library. Do not free. */
	char *p = NULL;

	/* Samba initialization. */
	load_case_tables();
        lp_set_in_client(True);

	ctrl = set_ctrl(pamh, flags, argc, argv);

	/* Get a few bytes so we can pass our return value to
		pam_sm_setcred(). */
	ret_data = SMB_MALLOC_P(int);

	/* we need to do this before we call AUTH_RETURN */
	/* Getting into places that might use LDAP -- protect the app
	from a SIGPIPE it's not expecting */
	oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);

	/* get the username */
	retval = pam_get_user( pamh, &name, "Username: "******"auth: could not identify user");
		}
		AUTH_RETURN;
	}
	if (on( SMB_DEBUG, ctrl )) {
		_log_err(pamh, LOG_DEBUG, "username [%s] obtained", name );
	}

	if (geteuid() != 0) {
		_log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
		retval = PAM_AUTHINFO_UNAVAIL;
		AUTH_RETURN;
	}

	if (!initialize_password_db(True, NULL)) {
		_log_err(pamh, LOG_ALERT, "Cannot access samba password database" );
		retval = PAM_AUTHINFO_UNAVAIL;
		AUTH_RETURN;
	}

	sampass = samu_new( NULL );
    	if (!sampass) {
		_log_err(pamh, LOG_ALERT, "Cannot talloc a samu struct" );
		retval = nt_status_to_pam(NT_STATUS_NO_MEMORY);
		AUTH_RETURN;
	}

	found = pdb_getsampwnam( sampass, name );

	if (on( SMB_MIGRATE, ctrl )) {
		retval = _smb_add_user(pamh, ctrl, name, sampass, found);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	if (!found) {
		_log_err(pamh, LOG_ALERT, "Failed to find entry for user %s.", name);
		retval = PAM_USER_UNKNOWN;
		TALLOC_FREE(sampass);
		sampass = NULL;
		AUTH_RETURN;
	}

	/* if this user does not have a password... */

	if (_smb_blankpasswd( ctrl, sampass )) {
		TALLOC_FREE(sampass);
		retval = PAM_SUCCESS;
		AUTH_RETURN;
	}

	/* get this user's authentication token */

	retval = _smb_read_password(pamh, ctrl, NULL, "Password: "******"auth: no password provided for [%s]", name);
		TALLOC_FREE(sampass);
		AUTH_RETURN;
	}

	/* verify the password of this user */

	retval = _smb_verify_password( pamh, sampass, p, ctrl );
	TALLOC_FREE(sampass);
	p = NULL;
	AUTH_RETURN;
}
示例#29
0
static int tdbsam_convert_one(struct db_record *rec, void *priv)
{
	struct tdbsam_convert_state *state =
		(struct tdbsam_convert_state *)priv;
	struct samu *user;
	TDB_DATA data;
	NTSTATUS status;
	bool ret;
	TDB_DATA key;
	TDB_DATA value;

	key = dbwrap_record_get_key(rec);

	if (key.dsize < USERPREFIX_LEN) {
		return 0;
	}
	if (strncmp((char *)key.dptr, USERPREFIX, USERPREFIX_LEN) != 0) {
		return 0;
	}

	user = samu_new(talloc_tos());
	if (user == NULL) {
		DEBUG(0,("tdbsam_convert: samu_new() failed!\n"));
		state->success = false;
		return -1;
	}

	DEBUG(10,("tdbsam_convert: Try unpacking a record with (key:%s) "
		  "(version:%d)\n", (char *)key.dptr, state->from));

	value = dbwrap_record_get_value(rec);

	switch (state->from) {
	case 0:
		ret = init_samu_from_buffer(user, SAMU_BUFFER_V0,
					    (uint8_t *)value.dptr,
					    value.dsize);
		break;
	case 1:
		ret = init_samu_from_buffer(user, SAMU_BUFFER_V1,
					    (uint8_t *)value.dptr,
					    value.dsize);
		break;
	case 2:
		ret = init_samu_from_buffer(user, SAMU_BUFFER_V2,
					    (uint8_t *)value.dptr,
					    value.dsize);
		break;
	case 3:
		ret = init_samu_from_buffer(user, SAMU_BUFFER_V3,
					    (uint8_t *)value.dptr,
					    value.dsize);
		break;
	case 4:
		ret = init_samu_from_buffer(user, SAMU_BUFFER_V4,
					    (uint8_t *)value.dptr,
					    value.dsize);
		break;
	default:
		/* unknown tdbsam version */
		ret = False;
	}
	if (!ret) {
		DEBUG(0,("tdbsam_convert: Bad struct samu entry returned "
			 "from TDB (key:%s) (version:%d)\n", (char *)key.dptr,
			 state->from));
		TALLOC_FREE(user);
		state->success = false;
		return -1;
	}

	data.dsize = init_buffer_from_samu(&data.dptr, user, false);
	TALLOC_FREE(user);

	if (data.dsize == -1) {
		DEBUG(0,("tdbsam_convert: cannot pack the struct samu into "
			 "the new format\n"));
		state->success = false;
		return -1;
	}

	status = dbwrap_record_store(rec, data, TDB_MODIFY);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Could not store the new record: %s\n",
			  nt_errstr(status)));
		state->success = false;
		return -1;
	}

	return 0;
}
示例#30
0
NTSTATUS check_sam_security(const DATA_BLOB *challenge,
			    TALLOC_CTX *mem_ctx,
			    const struct auth_usersupplied_info *user_info,
			    struct auth_serversupplied_info **server_info)
{
	struct samu *sampass=NULL;
	bool ret;
	NTSTATUS nt_status;
	NTSTATUS update_login_attempts_status;
	DATA_BLOB user_sess_key = data_blob_null;
	DATA_BLOB lm_sess_key = data_blob_null;
	bool updated_badpw = False;
	const char *username;
	const uint8_t *nt_pw;
	const uint8_t *lm_pw;
	uint32_t acct_ctrl;

	/* the returned struct gets kept on the server_info, by means
	   of a steal further down */

	sampass = samu_new(mem_ctx);
	if (sampass == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	/* get the account information */

	become_root();
	ret = pdb_getsampwnam(sampass, user_info->mapped.account_name);
	unbecome_root();

	if (ret == False) {
		DEBUG(3,("check_sam_security: Couldn't find user '%s' in "
			 "passdb.\n", user_info->mapped.account_name));
		TALLOC_FREE(sampass);
		return NT_STATUS_NO_SUCH_USER;
	}

	acct_ctrl = pdb_get_acct_ctrl(sampass);
	username = pdb_get_username(sampass);
	nt_pw = pdb_get_nt_passwd(sampass);
	lm_pw = pdb_get_lanman_passwd(sampass);

	/* Quit if the account was locked out. */
	if (acct_ctrl & ACB_AUTOLOCK) {
		DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username));
		TALLOC_FREE(sampass);
		return NT_STATUS_ACCOUNT_LOCKED_OUT;
	}

	nt_status = sam_password_ok(mem_ctx,
				    username, acct_ctrl,
				    challenge, lm_pw, nt_pw,
				    user_info, &user_sess_key, &lm_sess_key);

	/* Notify passdb backend of login success/failure. If not
	   NT_STATUS_OK the backend doesn't like the login */

	update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));

	if (!NT_STATUS_IS_OK(nt_status)) {
		bool increment_bad_pw_count = false;

		if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
		    (acct_ctrl & ACB_NORMAL) &&
		    NT_STATUS_IS_OK(update_login_attempts_status))
		{
			increment_bad_pw_count =
				need_to_increment_bad_pw_count(
					challenge, sampass, user_info);
		}

		if (increment_bad_pw_count) {
			pdb_increment_bad_password_count(sampass);
			updated_badpw = True;
		} else {
			pdb_update_bad_password_count(sampass,
						      &updated_badpw);
		}
		if (updated_badpw){
			NTSTATUS status;

			become_root();
			status = pdb_update_sam_account(sampass);
			unbecome_root();

			if (!NT_STATUS_IS_OK(status)) {
				DEBUG(1, ("Failed to modify entry: %s\n",
					  nt_errstr(status)));
			}
		}
		goto done;
	}

	/*
	 * We must only reset the bad password count if the login was
	 * successful, including checking account policies
	 */
	nt_status = sam_account_ok(mem_ctx, sampass, user_info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		goto done;
	}

	if ((acct_ctrl & ACB_NORMAL) &&
	    (pdb_get_bad_password_count(sampass) > 0)){
		NTSTATUS status;

		pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
		pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);

		become_root();
		status = pdb_update_sam_account(sampass);
		unbecome_root();

		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("Failed to modify entry: %s\n",
				  nt_errstr(status)));
		}
	}

	become_root();
	nt_status = make_server_info_sam(mem_ctx, sampass, server_info);
	unbecome_root();

	TALLOC_FREE(sampass);

	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
		goto done;
	}

	(*server_info)->session_key =
		data_blob_talloc(*server_info, user_sess_key.data,
				 user_sess_key.length);
	data_blob_free(&user_sess_key);

	(*server_info)->lm_session_key =
		data_blob_talloc(*server_info, lm_sess_key.data,
				 lm_sess_key.length);
	data_blob_free(&lm_sess_key);

	(*server_info)->nss_token |= user_info->was_mapped;

done:
	TALLOC_FREE(sampass);
	data_blob_free(&user_sess_key);
	data_blob_free(&lm_sess_key);
	return nt_status;
}