lib/krb5_wrap/krb5_samba.c smb_krb5_kinit_send/recv ... TODO keyblock
authorStefan Metzmacher <metze@samba.org>
Thu, 28 Nov 2019 17:00:05 +0000 (18:00 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 6 Aug 2020 12:03:26 +0000 (14:03 +0200)
lib/krb5_wrap/krb5_samba.c
lib/krb5_wrap/krb5_samba.h

index 8f6cd11de80db17081d11ee92a226e5ee93113c2..407886a3b31b34d72b2ce2644e8245b7c7db8372 100644 (file)
@@ -4346,18 +4346,19 @@ kerb_prompter(krb5_context ctx, void *data,
        return 0;
 }
 
-struct smb_krb5_kinit_passwd_state {
+struct smb_krb5_kinit_state {
        struct tevent_context *ev;
        struct smb_krb5_network *net_ctx;
        krb5_context krb5_ctx;
-       const char *given_principal;
+       const char *principal;
        const char *password;
+       const krb5_keyblock *keyblock;
        int time_offset;
        time_t renewable_time;
        const char *workstation;
        smb_krb5_addresses *addr;
 
-       krb5_principal principal;
+       krb5_principal k5principal;
        char *client_realm;
        char *krbtgt_service;
        krb5_get_init_creds_opt *creds_opt;
@@ -4365,12 +4366,12 @@ struct smb_krb5_kinit_passwd_state {
        krb5_creds creds;
 };
 
-static void smb_krb5_kinit_passwd_cleanup(struct tevent_req *req,
+static void smb_krb5_kinit_cleanup(struct tevent_req *req,
                                          enum tevent_req_state req_state)
 {
-       struct smb_krb5_kinit_passwd_state *state =
+       struct smb_krb5_kinit_state *state =
                tevent_req_data(req,
-               struct smb_krb5_kinit_passwd_state);
+               struct smb_krb5_kinit_state);
 
        if (req_state != TEVENT_REQ_RECEIVED) {
                return;
@@ -4385,10 +4386,10 @@ static void smb_krb5_kinit_passwd_cleanup(struct tevent_req *req,
                state->creds_ctx = NULL;
        }
 
-       if (state->principal != NULL) {
+       if (state->k5principal != NULL) {
                krb5_free_principal(state->krb5_ctx,
-                                   state->principal);
-               state->principal = NULL;
+                                   state->k5principal);
+               state->k5principal = NULL;
        }
 
        if (state->addr != NULL) {
@@ -4404,46 +4405,65 @@ static void smb_krb5_kinit_passwd_cleanup(struct tevent_req *req,
        }
 }
 
-static void smb_krb5_kinit_passwd_done(struct tevent_req *subreq);
+static void smb_krb5_kinit_done(struct tevent_req *subreq);
 
-struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
-                                             struct tevent_context *ev,
-                                             struct smb_krb5_network *net_ctx,
-                                             krb5_context krb5_ctx,
-                                             const char *given_principal,
-                                             const char *password,
-                                             time_t renewable_time,
-                                             const char *workstation)
+struct tevent_req *smb_krb5_kinit_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct smb_krb5_network *net_ctx,
+                                      krb5_context krb5_ctx,
+                                      const char *principal,
+                                      const char *password,
+                                      const krb5_keyblock *keyblock,
+                                      time_t renewable_time,
+                                      const char *workstation)
 {
        struct tevent_req *req = NULL;
-       struct smb_krb5_kinit_passwd_state *state = NULL;
+       struct smb_krb5_kinit_state *state = NULL;
        struct tevent_req *subreq = NULL;
        NTSTATUS status;
        krb5_error_code k5ret;
 
        req = tevent_req_create(mem_ctx, &state,
-                               struct smb_krb5_kinit_passwd_state);
+                               struct smb_krb5_kinit_state);
        if (req == NULL) {
                return NULL;
        }
        state->ev = ev;
        state->net_ctx = net_ctx;
        state->krb5_ctx = krb5_ctx;
-       state->given_principal = given_principal;
+       state->principal = principal;
        state->password = password;
+       state->keyblock = keyblock;
        state->renewable_time = state->renewable_time;
        state->workstation = workstation;
 
-       tevent_req_set_cleanup_fn(req, smb_krb5_kinit_passwd_cleanup);
+       tevent_req_set_cleanup_fn(req, smb_krb5_kinit_cleanup);
 
        k5ret = smb_krb5_parse_name(state->krb5_ctx,
-                                      state->given_principal,
-                                      &state->principal);
+                                   state->principal,
+                                   &state->k5principal);
        status = krb5_to_nt_status(k5ret);
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
        }
 
+       /*
+        * We only allow either password or keyblock!
+        */
+       if (password == NULL && keyblock == NULL) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+               return tevent_req_post(req, ev);
+       }
+       if (password != NULL && keyblock != NULL) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+               return tevent_req_post(req, ev);
+       }
+
+       if (keyblock != NULL) {
+               tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+               return tevent_req_post(req, ev);
+       }
+
        k5ret = krb5_get_init_creds_opt_alloc(state->krb5_ctx,
                                              &state->creds_opt);
        status = krb5_to_nt_status(k5ret);
@@ -4509,7 +4529,7 @@ struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
 
        state->client_realm = smb_krb5_principal_get_realm(state,
                                                           state->krb5_ctx,
-                                                          state->principal);
+                                                          state->k5principal);
        if (tevent_req_nomem(state->client_realm, req)) {
                return tevent_req_post(req, ev);
        }
@@ -4523,7 +4543,7 @@ struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
        }
 
        k5ret = krb5_init_creds_init(state->krb5_ctx,
-                                    state->principal,
+                                    state->k5principal,
                                     kerb_prompter, // TODO???
                                     discard_const_p(char, state->password),
                                     0, /* start_time */
@@ -4534,17 +4554,17 @@ struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       k5ret = krb5_init_creds_set_service(state->krb5_ctx,
-                                           state->creds_ctx,
-                                           state->krbtgt_service);
+       k5ret = krb5_init_creds_set_password(state->krb5_ctx,
+                                            state->creds_ctx,
+                                            state->password);
        status = krb5_to_nt_status(k5ret);
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
        }
 
-       k5ret = krb5_init_creds_set_password(state->krb5_ctx,
-                                            state->creds_ctx,
-                                            state->password);
+       k5ret = krb5_init_creds_set_service(state->krb5_ctx,
+                                           state->creds_ctx,
+                                           state->krbtgt_service);
        status = krb5_to_nt_status(k5ret);
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
@@ -4558,19 +4578,19 @@ struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, smb_krb5_kinit_passwd_done, req);
+       tevent_req_set_callback(subreq, smb_krb5_kinit_done, req);
 
        return req;
 }
 
-static void smb_krb5_kinit_passwd_done(struct tevent_req *subreq)
+static void smb_krb5_kinit_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
                tevent_req_callback_data(subreq,
                struct tevent_req);
-       struct smb_krb5_kinit_passwd_state *state =
+       struct smb_krb5_kinit_state *state =
                tevent_req_data(req,
-               struct smb_krb5_kinit_passwd_state);
+               struct smb_krb5_kinit_state);
        NTSTATUS status;
        krb5_error_code k5ret;
 
@@ -4591,12 +4611,12 @@ static void smb_krb5_kinit_passwd_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
-NTSTATUS smb_krb5_kinit_passwd_recv(struct tevent_req *req,
+NTSTATUS smb_krb5_kinit_recv(struct tevent_req *req,
                                    krb5_creds *creds)
 {
-       struct smb_krb5_kinit_passwd_state *state =
+       struct smb_krb5_kinit_state *state =
                tevent_req_data(req,
-               struct smb_krb5_kinit_passwd_state);
+               struct smb_krb5_kinit_state);
        NTSTATUS status;
 
        if (tevent_req_is_nterror(req, &status)) {
index 979a22194c11e9f1ecbf1fc8824af45c962ac5fc..4557142314d1cbb1a7b691fcc6b4739b9641bfda 100644 (file)
@@ -485,15 +485,16 @@ struct tevent_req *smb_krb5_tkt_creds_get_send(
        krb5_tkt_creds_context tkt_creds_ctx);
 NTSTATUS smb_krb5_tkt_creds_get_recv(struct tevent_req *req);
 
-struct tevent_req *smb_krb5_kinit_passwd_send(TALLOC_CTX *mem_ctx,
-                                             struct tevent_context *ev,
-                                             struct smb_krb5_network *net_ctx,
-                                             krb5_context krb5_ctx,
-                                             const char *given_principal,
-                                             const char *password,
-                                             time_t renewable_time,
-                                             const char *workstation);
-NTSTATUS smb_krb5_kinit_passwd_recv(struct tevent_req *req,
-                                   krb5_creds *creds);
+struct tevent_req *smb_krb5_kinit_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct smb_krb5_network *net_ctx,
+                                      krb5_context krb5_ctx,
+                                      const char *principal,
+                                      const char *password,
+                                      const krb5_keyblock *keyblock,
+                                      time_t renewable_time,
+                                      const char *workstation);
+NTSTATUS smb_krb5_kinit_recv(struct tevent_req *req,
+                            krb5_creds *creds);
 
 #endif /* _KRB5_SAMBA_H */