s4:credentials Put the 'secrets.keytab' in the same directory as secrets.ldb
[ira/wip.git] / source4 / auth / credentials / credentials_files.c
index 2b6bc4f9d6c7f1ea0a0042a0ee1de68f2bf856f8..8036e48193e65357d61376145e3caae1c654acea 100644 (file)
 */
 
 #include "includes.h"
+#include "lib/events/events.h"
 #include "lib/ldb/include/ldb.h"
 #include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
 #include "param/secrets.h"
 #include "system/filesys.h"
-#include "db_wrap.h"
+#include "../lib/util/util_ldb.h"
 #include "auth/credentials/credentials.h"
 #include "auth/credentials/credentials_krb5.h"
+#include "auth/credentials/credentials_proto.h"
+#include "param/param.h"
+#include "lib/events/events.h"
+#include "dsdb/samdb/samdb.h"
+
 
 /**
  * Read a file descriptor, and parse it for a password (eg from a file or stdin)
@@ -38,7 +44,7 @@
  * @param obtained This enum describes how 'specified' this password is
  */
 
-BOOL cli_credentials_parse_password_fd(struct cli_credentials *credentials, 
+_PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, 
                                       int fd, enum credentials_obtained obtained)
 {
        char *p;
@@ -60,18 +66,18 @@ BOOL cli_credentials_parse_password_fd(struct cli_credentials *credentials,
                                break;
                        } else {
                                fprintf(stderr, "Error reading password from file descriptor %d: %s\n", fd, "empty password\n");
-                               return False;
+                               return false;
                        }
 
                default:
                        fprintf(stderr, "Error reading password from file descriptor %d: %s\n",
                                        fd, strerror(errno));
-                       return False;
+                       return false;
                }
        }
 
        cli_credentials_set_password(credentials, pass, obtained);
-       return True;
+       return true;
 }
 
 /**
@@ -82,15 +88,15 @@ BOOL cli_credentials_parse_password_fd(struct cli_credentials *credentials,
  * @param obtained This enum describes how 'specified' this password is
  */
 
-BOOL cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained)
+_PUBLIC_ bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained)
 {
        int fd = open(file, O_RDONLY, 0);
-       BOOL ret;
+       bool ret;
 
        if (fd < 0) {
                fprintf(stderr, "Error opening password file %s: %s\n",
                                file, strerror(errno));
-               return False;
+               return false;
        }
 
        ret = cli_credentials_parse_password_fd(credentials, fd, obtained);
@@ -108,20 +114,20 @@ BOOL cli_credentials_parse_password_file(struct cli_credentials *credentials, co
  * @param obtained This enum describes how 'specified' this password is
  */
 
-BOOL cli_credentials_parse_file(struct cli_credentials *cred, const char *file, enum credentials_obtained obtained) 
+_PUBLIC_ bool cli_credentials_parse_file(struct cli_credentials *cred, const char *file, enum credentials_obtained obtained) 
 {
        uint16_t len = 0;
        char *ptr, *val, *param;
        char **lines;
        int i, numlines;
 
-       lines = file_lines_load(file, &numlines, NULL);
+       lines = file_lines_load(file, &numlines, 0, NULL);
 
        if (lines == NULL)
        {
                /* fail if we can't open the credentials file */
                d_printf("ERROR: Unable to open credentials file!\n");
-               return False;
+               return false;
        }
 
        for (i = 0; i < numlines; i++) {
@@ -157,7 +163,7 @@ BOOL cli_credentials_parse_file(struct cli_credentials *cred, const char *file,
 
        talloc_free(lines);
 
-       return True;
+       return true;
 }
 
 
@@ -167,7 +173,9 @@ BOOL cli_credentials_parse_file(struct cli_credentials *cred, const char *file,
  * @param cred Credentials structure to fill in
  * @retval NTSTATUS error detailing any failure
  */
-NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
+_PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
+                                             struct tevent_context *event_ctx,
+                                    struct loadparm_context *lp_ctx,
                                     struct ldb_context *ldb,
                                     const char *base,
                                     const char *filter)
@@ -189,6 +197,7 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
                "privateKeytab",
                "krb5Keytab",
                "servicePrincipalName",
+               "ldapBindDn",
                NULL
        };
        
@@ -202,20 +211,21 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
        const char *keytab;
        
        /* ok, we are going to get it now, don't recurse back here */
-       cred->machine_account_pending = False;
+       cred->machine_account_pending = false;
 
        /* some other parts of the system will key off this */
-       cred->machine_account = True;
+       cred->machine_account = true;
 
        mem_ctx = talloc_named(cred, 0, "cli_credentials fetch machine password");
 
        if (!ldb) {
                /* Local secrets are stored in secrets.ldb */
-               ldb = secrets_db_connect(mem_ctx);
+               ldb = secrets_db_connect(mem_ctx, event_ctx, lp_ctx);
                if (!ldb) {
                        /* set anonymous as the fallback, if the machine account won't work */
                        cli_credentials_set_anonymous(cred);
                        DEBUG(1, ("Could not open secrets.ldb\n"));
+                       talloc_free(mem_ctx);
                        return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
                }
        }
@@ -226,14 +236,14 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
                               &msgs, attrs,
                               "%s", filter);
        if (ldb_ret == 0) {
-               DEBUG(1, ("Could not find entry to match filter: '%s' base: '%s'\n",
+               DEBUG(5, ("(normal if no LDAP backend required) Could not find entry to match filter: '%s' base: '%s'\n",
                          filter, base));
                /* set anonymous as the fallback, if the machine account won't work */
                cli_credentials_set_anonymous(cred);
                talloc_free(mem_ctx);
                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
        } else if (ldb_ret != 1) {
-               DEBUG(1, ("Found more than one (%d) entry to match filter: '%s' base: '%s'\n",
+               DEBUG(5, ("Found more than one (%d) entry to match filter: '%s' base: '%s'\n",
                          ldb_ret, filter, base));
                /* set anonymous as the fallback, if the machine account won't work */
                cli_credentials_set_anonymous(cred);
@@ -250,12 +260,18 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
                machine_account = ldb_msg_find_attr_as_string(msgs[0], "servicePrincipalName", NULL);
                
                if (!machine_account) {
-                       DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s: filter: '%s' base: '%s'\n",
-                                 cli_credentials_get_domain(cred), filter, base));
-                       /* set anonymous as the fallback, if the machine account won't work */
-                       cli_credentials_set_anonymous(cred);
-                       talloc_free(mem_ctx);
-                       return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+                       const char *ldap_bind_dn = ldb_msg_find_attr_as_string(msgs[0], "ldapBindDn", NULL);
+                       if (!ldap_bind_dn) {
+                               DEBUG(1, ("Could not find 'samAccountName', 'servicePrincipalName' or 'ldapBindDn' in secrets record: filter: '%s' base: '%s'\n",
+                                         filter, base));
+                               /* set anonymous as the fallback, if the machine account won't work */
+                               cli_credentials_set_anonymous(cred);
+                               talloc_free(mem_ctx);
+                               return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+                       } else {
+                               /* store bind dn in credentials */
+                               cli_credentials_set_bind_dn(cred, ldap_bind_dn);
+                       }
                }
        }
 
@@ -294,7 +310,9 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
                cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
        }
 
-       cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
+       if (machine_account) {
+               cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
+       }
 
        cli_credentials_set_kvno(cred, ldb_msg_find_attr_as_int(msgs[0], "msDS-KeyVersionNumber", 0));
 
@@ -303,13 +321,13 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
         * (chewing CPU time) from the password */
        keytab = ldb_msg_find_attr_as_string(msgs[0], "krb5Keytab", NULL);
        if (keytab) {
-               cli_credentials_set_keytab_name(cred, keytab, CRED_SPECIFIED);
+               cli_credentials_set_keytab_name(cred, event_ctx, lp_ctx, keytab, CRED_SPECIFIED);
        } else {
                keytab = ldb_msg_find_attr_as_string(msgs[0], "privateKeytab", NULL);
                if (keytab) {
-                       keytab = talloc_asprintf(mem_ctx, "FILE:%s", private_path(mem_ctx, keytab));
+                       keytab = talloc_asprintf(mem_ctx, "FILE:%s", samdb_relative_path(ldb, mem_ctx, keytab));
                        if (keytab) {
-                               cli_credentials_set_keytab_name(cred, keytab, CRED_SPECIFIED);
+                               cli_credentials_set_keytab_name(cred, event_ctx, lp_ctx, keytab, CRED_SPECIFIED);
                        }
                }
        }
@@ -324,17 +342,24 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
  * @param cred Credentials structure to fill in
  * @retval NTSTATUS error detailing any failure
  */
-NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
+_PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred,
+                                                     struct loadparm_context *lp_ctx)
 {
+       NTSTATUS status;
        char *filter;
        /* Bleh, nasty recursion issues: We are setting a machine
         * account here, so we don't want the 'pending' flag around
         * any more */
-       cred->machine_account_pending = False;
+       cred->machine_account_pending = false;
        filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, 
                                       cli_credentials_get_domain(cred));
-       return cli_credentials_set_secrets(cred, NULL, SECRETS_PRIMARY_DOMAIN_DN,
+       status = cli_credentials_set_secrets(cred, event_context_find(cred), lp_ctx, NULL, 
+                                          SECRETS_PRIMARY_DOMAIN_DN,
                                           filter);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Could not find machine account in secrets database: %s", nt_errstr(status)));
+       }
+       return status;
 }
 
 /**
@@ -343,40 +368,55 @@ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cred)
  * @param cred Credentials structure to fill in
  * @retval NTSTATUS error detailing any failure
  */
-NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred)
+NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred,
+                                   struct tevent_context *event_ctx,
+                                   struct loadparm_context *lp_ctx)
 {
+       NTSTATUS status;
        char *filter;
        /* Bleh, nasty recursion issues: We are setting a machine
         * account here, so we don't want the 'pending' flag around
         * any more */
-       cred->machine_account_pending = False;
+       cred->machine_account_pending = false;
        filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH,
                                       cli_credentials_get_realm(cred),
                                       cli_credentials_get_domain(cred));
-       return cli_credentials_set_secrets(cred, NULL, SECRETS_PRINCIPALS_DN,
+       status = cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL, 
+                                          SECRETS_PRINCIPALS_DN,
                                           filter);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Could not find krbtgt (master Kerberos) account in secrets database: %s", nt_errstr(status)));
+       }
+       return status;
 }
 
 /**
- * Fill in credentials for the machine trust account, from the secrets database.
+ * Fill in credentials for a particular prinicpal, from the secrets database.
  * 
  * @param cred Credentials structure to fill in
  * @retval NTSTATUS error detailing any failure
  */
-NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
+_PUBLIC_ NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
+                                                      struct tevent_context *event_ctx,
+                                             struct loadparm_context *lp_ctx,
                                              const char *serviceprincipal)
 {
+       NTSTATUS status;
        char *filter;
        /* Bleh, nasty recursion issues: We are setting a machine
         * account here, so we don't want the 'pending' flag around
         * any more */
-       cred->machine_account_pending = False;
+       cred->machine_account_pending = false;
        filter = talloc_asprintf(cred, SECRETS_PRINCIPAL_SEARCH,
                                 cli_credentials_get_realm(cred),
                                 cli_credentials_get_domain(cred),
                                 serviceprincipal);
-       return cli_credentials_set_secrets(cred, NULL, SECRETS_PRINCIPALS_DN,
-                                          filter);
+       status = cli_credentials_set_secrets(cred, event_ctx, lp_ctx, NULL, 
+                                          SECRETS_PRINCIPALS_DN, filter);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Could not find %s principal in secrets database: %s", serviceprincipal, nt_errstr(status)));
+       }
+       return status;
 }
 
 /**
@@ -388,9 +428,11 @@ NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
  *       than during, popt processing.
  *
  */
-void cli_credentials_set_machine_account_pending(struct cli_credentials *cred)
+_PUBLIC_ void cli_credentials_set_machine_account_pending(struct cli_credentials *cred,
+                                                struct loadparm_context *lp_ctx)
 {
-       cred->machine_account_pending = True;
+       cred->machine_account_pending = true;
+       cred->machine_account_pending_lp_ctx = lp_ctx;
 }