s4-auth: Add smb_krb5_create_principals_array()
authorAndreas Schneider <asn@samba.org>
Fri, 17 Apr 2015 13:53:06 +0000 (15:53 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 16 Jul 2015 23:38:15 +0000 (01:38 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source4/auth/kerberos/kerberos_util.c

index c2e48fd51550e0e417e4403c2ae2f822b0f52177..9cfeee519b476041d339ab6db4a95a717034bd6a 100644 (file)
@@ -134,6 +134,92 @@ static krb5_error_code impersonate_principal_from_credentials(
                        smb_krb5_context, princ, error_string);
 }
 
+krb5_error_code smb_krb5_create_principals_array(TALLOC_CTX *mem_ctx,
+                                                krb5_context context,
+                                                const char *account_name,
+                                                const char *realm,
+                                                uint32_t num_spns,
+                                                const char *spns[],
+                                                uint32_t *pnum_principals,
+                                                krb5_principal **pprincipals,
+                                                const char **error_string)
+{
+       krb5_error_code code;
+       TALLOC_CTX *tmp_ctx;
+       uint32_t num_principals = 0;
+       krb5_principal *principals;
+       uint32_t i;
+
+       tmp_ctx = talloc_new(mem_ctx);
+       if (tmp_ctx == NULL) {
+               *error_string = "Cannot allocate tmp_ctx";
+               return ENOMEM;
+       }
+
+       if (realm == NULL) {
+               *error_string = "Cannot create principal without a realm";
+               code = EINVAL;
+               goto done;
+       }
+
+       if (account_name == NULL && (num_spns == 0 || spns == NULL)) {
+               *error_string = "Cannot create principal without an account or SPN";
+               code = EINVAL;
+               goto done;
+       }
+
+       if (account_name != NULL && account_name[0] != '\0') {
+               num_principals++;
+       }
+       num_principals += num_spns;
+
+       principals = talloc_zero_array(tmp_ctx,
+                                      krb5_principal,
+                                      num_principals);
+       if (principals == NULL) {
+               *error_string = "Cannot allocate principals";
+               code = ENOMEM;
+               goto done;
+       }
+
+       for (i = 0; i < num_spns; i++) {
+               code = krb5_parse_name(context, spns[i], &(principals[i]));
+               if (code != 0) {
+                       *error_string = smb_get_krb5_error_message(context,
+                                                                  code,
+                                                                  mem_ctx);
+                       goto done;
+               }
+       }
+
+       if (account_name != NULL && account_name[0] != '\0') {
+               code = smb_krb5_make_principal(context,
+                                              &(principals[i]),
+                                              realm,
+                                              account_name,
+                                              NULL);
+               if (code != 0) {
+                       *error_string = smb_get_krb5_error_message(context,
+                                                                  code,
+                                                                  mem_ctx);
+                       goto done;
+               }
+       }
+
+       if (pnum_principals != NULL) {
+               *pnum_principals = num_principals;
+
+               if (pprincipals != NULL) {
+                       *pprincipals = talloc_steal(mem_ctx, principals);
+               }
+       }
+
+       code = 0;
+done:
+       talloc_free(tmp_ctx);
+       return code;
+}
+
 /**
  * Return a freshly allocated ccache (destroyed by destructor on child
  * of parent_ctx), for a given set of client credentials