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; }
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; }