Exemple #1
0
NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
{
	POLICY_HND pol;
	fstring name;
	struct reg_info *info = NULL;

	DEBUG(5,("reg_open_entry: %d\n", __LINE__));

	if (!find_policy_by_hnd(p, &q_u->pol, NULL))
		return NT_STATUS_INVALID_HANDLE;

	fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));

	DEBUG(5,("reg_open_entry: %s\n", name));

	/* lkcl XXXX do a check on the name, here */
	if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") &&
	    !strequal(name, "System\\CurrentControlSet\\services\\Netlogon\\parameters\\"))
			return NT_STATUS_ACCESS_DENIED;

	if ((info = (struct reg_info *)malloc(sizeof(struct reg_info))) == NULL)
		return NT_STATUS_NO_MEMORY;

	ZERO_STRUCTP(info);
	fstrcpy(info->name, name);

	if (!create_policy_hnd(p, &pol, free_reg_info, (void *)info))
		return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */

	init_reg_r_open_entry(r_u, &pol, NT_STATUS_OK);

	DEBUG(5,("reg_open_entry: %d\n", __LINE__));

	return r_u->status;
}
/***********************************************************
 Code to check the OEM hashed password.

 this function ignores the 516 byte nt OEM hashed password
 but does use the lm OEM password to check the nt hashed-hash.

************************************************************/
BOOL check_oem_password(char *user,
			uchar *lmdata, uchar *lmhash,
			uchar *ntdata, uchar *nthash,
                        struct smb_passwd **psmbpw, char *new_passwd,
                        int new_passwd_size)
{
	static uchar null_pw[16];
	static uchar null_ntpw[16];
	struct smb_passwd *smbpw = NULL;
	int new_pw_len;
	uchar new_ntp16[16];
	uchar unenc_old_ntpw[16];
	uchar new_p16[16];
	uchar unenc_old_pw[16];
	char no_pw[2];

	BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);

	become_root(False);
	*psmbpw = smbpw = getsmbpwnam(user);
	unbecome_root(False);

	if (smbpw == NULL)
	{
		DEBUG(0,("check_oem_password: getsmbpwnam returned NULL\n"));
		return False;
	}

	if (smbpw->acct_ctrl & ACB_DISABLED)
	{
		DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
		return False;
	}

	/* construct a null password (in case one is needed */
	no_pw[0] = 0;
	no_pw[1] = 0;
	nt_lm_owf_gen(no_pw, null_ntpw, null_pw);

	/* check for null passwords */
	if (smbpw->smb_passwd == NULL)
	{
		if (smbpw->acct_ctrl & ACB_PWNOTREQ)
		{
			smbpw->smb_passwd = null_pw;
		}
		else 
		{
			DEBUG(0,("check_oem_password: no lanman password !\n"));
			return False;
		}
	}

	if (smbpw->smb_nt_passwd == NULL && nt_pass_set)
	{
		if (smbpw->acct_ctrl & ACB_PWNOTREQ)
		{
			smbpw->smb_nt_passwd = null_pw;
		}
		else 
		{
			DEBUG(0,("check_oem_password: no ntlm password !\n"));
			return False;
		}
	}

	/* 
	 * Call the hash function to get the new password.
	 */
	SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True);

	/* 
	 * The length of the new password is in the last 4 bytes of
	 * the data buffer.
	 */

	new_pw_len = IVAL(lmdata, 512);
	if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
	{
		DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
		return False;
	}

	if (nt_pass_set)
	{
		/*
		 * nt passwords are in unicode
		 */
		int uni_pw_len = new_pw_len;
		char *pw;
		new_pw_len /= 2;
		pw = dos_unistrn2((uint16*)(&lmdata[512-uni_pw_len]), new_pw_len);
		memcpy(new_passwd, pw, new_pw_len+1);
	}
	else
	{
		memcpy(new_passwd, &lmdata[512-new_pw_len], new_pw_len);
		new_passwd[new_pw_len] = '\0';
	}

	/*
	 * To ensure we got the correct new password, hash it and
	 * use it as a key to test the passed old password.
	 */

	nt_lm_owf_gen(new_passwd, new_ntp16, new_p16);

	if (!nt_pass_set)
	{
		/*
		 * Now use new_p16 as the key to see if the old
		 * password matches.
		 */
		D_P16(new_p16  , lmhash, unenc_old_pw);

		if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
		{
			DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
			return False;
		}

#ifdef DEBUG_PASSWORD
		DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
#endif
		return True;
	}

	/*
	 * Now use new_p16 as the key to see if the old
	 * password matches.
	 */
	D_P16(new_ntp16, lmhash, unenc_old_pw);
	D_P16(new_ntp16, nthash, unenc_old_ntpw);

	if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
	{
		DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
		return False;
	}

	if (memcmp(smbpw->smb_nt_passwd, unenc_old_ntpw, 16))
	{
		DEBUG(0,("check_oem_password: old nt password doesn't match.\n"));
		return False;
	}
#ifdef DEBUG_PASSWORD
	DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
#endif
	return True;
}
Exemple #3
0
NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
	NTSTATUS status = NT_STATUS_OK;
	const char *key = NULL;
	uint32 type=0x1; /* key type: REG_SZ */

	UNISTR2 *uni_key = NULL;
	BUFFER2 *buf = NULL;
	fstring name;

	DEBUG(5,("_reg_info: %d\n", __LINE__));

	if (!find_policy_by_hnd(p, &q_u->pol, NULL))
		return NT_STATUS_INVALID_HANDLE;

	fstrcpy(name, dos_unistrn2(q_u->uni_type.buffer, q_u->uni_type.uni_str_len));

	DEBUG(5,("reg_info: checking key: %s\n", name));

	uni_key = (UNISTR2 *)talloc_zero(p->mem_ctx, sizeof(UNISTR2));
	buf = (BUFFER2 *)talloc_zero(p->mem_ctx, sizeof(BUFFER2));

	if (!uni_key || !buf)
		return NT_STATUS_NO_MEMORY;

	if ( strequal(name, "RefusePasswordChange") ) {
		type=0xF770;
		status = NT_STATUS_NO_SUCH_FILE;
		init_unistr2(uni_key, "", 0);
		init_buffer2(buf, (uint8*) uni_key->buffer, uni_key->uni_str_len*2);
		
		buf->buf_max_len=4;

		goto out;
	}

	switch (lp_server_role()) {
	case ROLE_DOMAIN_PDC:
	case ROLE_DOMAIN_BDC:
		key = "LanmanNT";
		break;
	case ROLE_STANDALONE:
		key = "ServerNT";
		break;
	case ROLE_DOMAIN_MEMBER:
		key = "WinNT";
		break;
	}

	/* This makes the server look like a member server to clients */
	/* which tells clients that we have our own local user and    */
	/* group databases and helps with ACL support.                */

	init_unistr2(uni_key, key, strlen(key)+1);
	init_buffer2(buf, (uint8*)uni_key->buffer, uni_key->uni_str_len*2);
  
 out:
	init_reg_r_info(q_u->ptr_buf, r_u, buf, type, status);

	DEBUG(5,("reg_open_entry: %d\n", __LINE__));

	return status;
}