00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024 #include "winbindd.h"
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_WINBIND
00027
00028 #define MAX_CACHED_LOGINS 10
00029
00030 NTSTATUS winbindd_get_creds(struct winbindd_domain *domain,
00031 TALLOC_CTX *mem_ctx,
00032 const DOM_SID *sid,
00033 NET_USER_INFO_3 **info3,
00034 const uint8 *cached_nt_pass[NT_HASH_LEN],
00035 const uint8 *cred_salt[NT_HASH_LEN])
00036 {
00037 NET_USER_INFO_3 *info;
00038 NTSTATUS status;
00039
00040 status = wcache_get_creds(domain, mem_ctx, sid, cached_nt_pass, cred_salt);
00041 if (!NT_STATUS_IS_OK(status)) {
00042 return status;
00043 }
00044
00045 info = netsamlogon_cache_get(mem_ctx, sid);
00046 if (info == NULL) {
00047 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
00048 }
00049
00050 *info3 = info;
00051
00052 return NT_STATUS_OK;
00053 }
00054
00055
00056 NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
00057 TALLOC_CTX *mem_ctx,
00058 const char *user,
00059 const char *pass,
00060 NET_USER_INFO_3 *info3,
00061 const DOM_SID *user_sid)
00062 {
00063 NTSTATUS status;
00064 uchar nt_pass[NT_HASH_LEN];
00065 DOM_SID cred_sid;
00066
00067 if (info3 != NULL) {
00068
00069 DOM_SID sid;
00070 sid_copy(&sid, &(info3->dom_sid.sid));
00071 sid_append_rid(&sid, info3->user_rid);
00072 sid_copy(&cred_sid, &sid);
00073 info3->user_flgs |= LOGON_CACHED_ACCOUNT;
00074
00075 } else if (user_sid != NULL) {
00076
00077 sid_copy(&cred_sid, user_sid);
00078
00079 } else if (user != NULL) {
00080
00081
00082
00083 enum lsa_SidType type;
00084
00085 if (!lookup_cached_name(mem_ctx,
00086 domain->name,
00087 user,
00088 &cred_sid,
00089 &type)) {
00090 return NT_STATUS_NO_SUCH_USER;
00091 }
00092 } else {
00093 return NT_STATUS_INVALID_PARAMETER;
00094 }
00095
00096 if (pass) {
00097
00098 int count = 0;
00099
00100 status = wcache_count_cached_creds(domain, &count);
00101 if (!NT_STATUS_IS_OK(status)) {
00102 return status;
00103 }
00104
00105 DEBUG(11,("we have %d cached creds\n", count));
00106
00107 if (count + 1 > MAX_CACHED_LOGINS) {
00108
00109 DEBUG(10,("need to delete the oldest cached login\n"));
00110
00111 status = wcache_remove_oldest_cached_creds(domain, &cred_sid);
00112 if (!NT_STATUS_IS_OK(status)) {
00113 DEBUG(10,("failed to remove oldest cached cred: %s\n",
00114 nt_errstr(status)));
00115 return status;
00116 }
00117 }
00118
00119 E_md4hash(pass, nt_pass);
00120
00121 #if DEBUG_PASSWORD
00122 dump_data(100, (const char *)nt_pass, NT_HASH_LEN);
00123 #endif
00124
00125 status = wcache_save_creds(domain, mem_ctx, &cred_sid, nt_pass);
00126 if (!NT_STATUS_IS_OK(status)) {
00127 return status;
00128 }
00129 }
00130
00131 if (info3 != NULL && user != NULL) {
00132 if (!netsamlogon_cache_store(user, info3)) {
00133 return NT_STATUS_ACCESS_DENIED;
00134 }
00135 }
00136
00137 return NT_STATUS_OK;
00138 }
00139
00140 NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
00141 TALLOC_CTX *mem_ctx,
00142 const char *user,
00143 const char *pass,
00144 NET_USER_INFO_3 *info3)
00145 {
00146 return winbindd_store_creds(domain, mem_ctx, user, pass, info3, NULL);
00147 }
00148
00149 NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain,
00150 TALLOC_CTX *mem_ctx,
00151 const DOM_SID *sid,
00152 const char *pass)
00153 {
00154 return winbindd_store_creds(domain, mem_ctx, NULL, pass, NULL, sid);
00155 }
00156
00157 NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain,
00158 TALLOC_CTX *mem_ctx,
00159 const char *user,
00160 const char *pass)
00161 {
00162 return winbindd_store_creds(domain, mem_ctx, user, pass, NULL, NULL);
00163 }
00164
00165