s3: Add wbinfo --ccache-save
[ira/wip.git] / source3 / winbindd / winbindd_ccache_access.c
index f8f9ddfad5c4b1c138d00ef94f3a6c1ab91670e0..b0efc6474bf5377e7d5e024a482e59b25b892557 100644 (file)
@@ -116,7 +116,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
                data_blob_free(&reply);
                goto done;
        }
-       *auth_msg = reply;
+       *auth_msg = data_blob(reply.data, reply.length);
        status = NT_STATUS_OK;
 
 done:
@@ -251,21 +251,15 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma
                goto process_result;
        }
 
-       initial = data_blob(state->request->extra_data.data, initial_blob_len);
-       challenge = data_blob(state->request->extra_data.data + initial_blob_len,
-                               state->request->data.ccache_ntlm_auth.challenge_blob_len);
-
-       if (!initial.data || !challenge.data) {
-               result = NT_STATUS_NO_MEMORY;
-       } else {
-               result = do_ntlm_auth_with_hashes(name_user, name_domain,
-                                               entry->lm_hash, entry->nt_hash,
-                                               initial, challenge, &auth);
-       }
-
-       data_blob_free(&initial);
-       data_blob_free(&challenge);
+       initial = data_blob_const(state->request->extra_data.data,
+                                 initial_blob_len);
+       challenge = data_blob_const(
+               state->request->extra_data.data + initial_blob_len,
+               state->request->data.ccache_ntlm_auth.challenge_blob_len);
 
+       result = do_ntlm_auth_with_hashes(name_user, name_domain,
+                                         entry->lm_hash, entry->nt_hash,
+                                         initial, challenge, &auth);
        if (!NT_STATUS_IS_OK(result)) {
                goto process_result;
        }
@@ -284,3 +278,75 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma
   process_result:
        return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
 }
+
+void winbindd_ccache_save(struct winbindd_cli_state *state)
+{
+       struct winbindd_domain *domain;
+       fstring name_domain, name_user;
+
+       /* Ensure null termination */
+       state->request->data.ccache_save.user[
+               sizeof(state->request->data.ccache_save.user)-1]='\0';
+       state->request->data.ccache_save.pass[
+               sizeof(state->request->data.ccache_save.pass)-1]='\0';
+
+       DEBUG(3, ("[%5lu]: save passord of user %s\n",
+                 (unsigned long)state->pid,
+                 state->request->data.ccache_save.user));
+
+       /* Parse domain and username */
+
+       if (!canonicalize_username(state->request->data.ccache_ntlm_auth.user,
+                                  name_domain, name_user)) {
+               DEBUG(5,("winbindd_ccache_save: cannot parse domain and user "
+                        "from name [%s]\n",
+                        state->request->data.ccache_save.user));
+               request_error(state);
+               return;
+       }
+
+       domain = find_auth_domain(state->request->flags, name_domain);
+
+       if (domain == NULL) {
+               DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n",
+                         name_domain));
+               request_error(state);
+               return;
+       }
+
+       if (!check_client_uid(state, state->request->data.ccache_save.uid)) {
+               request_error(state);
+               return;
+       }
+
+       sendto_domain(state, domain);
+}
+
+enum winbindd_result winbindd_dual_ccache_save(
+       struct winbindd_domain *domain, struct winbindd_cli_state *state)
+{
+       NTSTATUS status = NT_STATUS_NOT_SUPPORTED;
+
+       /* Ensure null termination */
+       state->request->data.ccache_save.user[
+               sizeof(state->request->data.ccache_save.user)-1]='\0';
+       state->request->data.ccache_save.pass[
+               sizeof(state->request->data.ccache_save.pass)-1]='\0';
+
+       DEBUG(3, ("winbindd_dual_ccache_save: [%5lu]: save password of user "
+                 "%s\n", (unsigned long)state->pid,
+                 state->request->data.ccache_save.user));
+
+       status = winbindd_add_memory_creds(
+               state->request->data.ccache_save.user,
+               state->request->data.ccache_save.uid,
+               state->request->data.ccache_save.pass);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("winbindd_add_memory_creds failed %s\n",
+                         nt_errstr(status)));
+               return WINBINDD_ERROR;
+       }
+
+       return WINBINDD_OK;
+}