diff options
Diffstat (limited to 'source4/lib')
-rw-r--r-- | source4/lib/basic.mk | 2 | ||||
-rw-r--r-- | source4/lib/cmdline/config.mk | 2 | ||||
-rw-r--r-- | source4/lib/cmdline/popt_common.c | 21 | ||||
-rw-r--r-- | source4/lib/credentials.c | 79 | ||||
-rw-r--r-- | source4/lib/gendb.c | 80 |
5 files changed, 158 insertions, 26 deletions
diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk index 29dbbd22c7..7d6847c465 100644 --- a/source4/lib/basic.mk +++ b/source4/lib/basic.mk @@ -65,8 +65,10 @@ ADD_OBJ_FILES = \ lib/unix_privs.o \ lib/db_wrap.o \ lib/gencache.o \ + lib/gendb.o \ lib/credentials.o REQUIRED_SUBSYSTEMS = \ LIBLDB CHARSET LIBREPLACE LIBNETIF LIBCRYPTO EXT_LIB_DL LIBTALLOC # End SUBSYSTEM LIBBASIC ############################## + diff --git a/source4/lib/cmdline/config.mk b/source4/lib/cmdline/config.mk index 803c81f273..831461b7f3 100644 --- a/source4/lib/cmdline/config.mk +++ b/source4/lib/cmdline/config.mk @@ -2,6 +2,6 @@ # Start SUBSYSTEM LIBCMDLINE_CREDENTIALS [SUBSYSTEM::LIBCMDLINE_CREDENTIALS] ADD_OBJ_FILES = lib/cmdline/getsmbpass.o \ - lib/cmdline/credentials.o + lib/cmdline/credentials.o # End SUBSYSTEM LIBCMDLINE_CREDENTIALS ############################## diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c index 7049ce65df..50e07d95e9 100644 --- a/source4/lib/cmdline/popt_common.c +++ b/source4/lib/cmdline/popt_common.c @@ -213,26 +213,7 @@ static void popt_common_credentials_callback(poptContext con, case 'P': { - char *opt_password = NULL; - /* it is very useful to be able to make ads queries as the - machine account for testing purposes and for domain leave */ - - if (!secrets_init()) { - d_printf("ERROR: Unable to open secrets database\n"); - exit(1); - } - - opt_password = secrets_fetch_machine_password(lp_workgroup()); - - if (!opt_password) { - d_printf("ERROR: Unable to fetch machine password\n"); - exit(1); - } - cmdline_credentials->username = talloc_asprintf(cmdline_credentials, "%s$", lp_netbios_name()); - cmdline_credentials->username_obtained = CRED_SPECIFIED; - cli_credentials_set_password(cmdline_credentials, opt_password, CRED_SPECIFIED); - free(opt_password); - + cli_credentials_set_machine_account(cmdline_credentials); } /* machine accounts only work with kerberos */ diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c index 211cb9ce07..b997e6ae53 100644 --- a/source4/lib/credentials.c +++ b/source4/lib/credentials.c @@ -22,11 +22,23 @@ #include "includes.h" #include "system/filesys.h" +#include "lib/cmdline/popt_common.h" +#include "include/secrets.h" +#include "lib/ldb/include/ldb.h" /* Create a new credentials structure, on the specified TALLOC_CTX */ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) { - return talloc_zero(mem_ctx, struct cli_credentials); + struct cli_credentails *cred = talloc_zero(mem_ctx, struct cli_credentials); + if (!cred) { + return cred; + } + + cli_credentials_set_domain(cred, lp_workgroup(), CRED_GUESSED); + cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_GUESSED); + cli_credentials_set_realm(cred, lp_realm(), CRED_GUESSED); + + return cred; } const char *cli_credentials_get_username(struct cli_credentials *cred) @@ -279,10 +291,6 @@ void cli_credentials_guess(struct cli_credentials *cred) { char *p; - cli_credentials_set_domain(cred, lp_workgroup(), CRED_GUESSED); - cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_GUESSED); - cli_credentials_set_realm(cred, lp_realm(), CRED_GUESSED); - if (getenv("LOGNAME")) { cli_credentials_set_username(cred, getenv("LOGNAME"), CRED_GUESSED); } @@ -311,6 +319,67 @@ void cli_credentials_guess(struct cli_credentials *cred) } } +NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *creds) +{ + TALLOC_CTX *mem_ctx = talloc_named(creds, 0, "cli_credentials fetch machine password"); + + struct ldb_context *ldb; + int ldb_ret; + struct ldb_message **msgs; + const char *base_dn = SECRETS_PRIMARY_DOMAIN_DN; + const char *attrs[] = { + "secret", + "samAccountName", + NULL + }; + + const char *machine_account; + const char *password; + + /* Local secrets are stored in secrets.ldb */ + ldb = secrets_db_connect(mem_ctx); + if (!ldb) { + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + /* search for the secret record */ + ldb_ret = gendb_search(ldb, + mem_ctx, base_dn, &msgs, attrs, + SECRETS_PRIMARY_DOMAIN_FILTER, + cli_credentials_get_domain(creds)); + if (ldb_ret == 0) { + DEBUG(1, ("Could not find join record to domain: %s\n", + lp_workgroup())); + talloc_free(mem_ctx); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } else if (ldb_ret != 1) { + talloc_free(mem_ctx); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + password = ldb_msg_find_string(msgs[0], "secret", NULL); + if (!password) { + DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n", + cli_credentials_get_domain(creds))); + talloc_free(mem_ctx); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + machine_account = ldb_msg_find_string(msgs[0], "samAccountName", NULL); + if (!machine_account) { + DEBUG(1, ("Could not find 'samAccountName' in join record to domain: %s\n", + cli_credentials_get_domain(creds))); + talloc_free(mem_ctx); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + cli_credentials_set_username(creds, machine_account, CRED_SPECIFIED); + cli_credentials_set_password(creds, password, CRED_SPECIFIED); + talloc_free(mem_ctx); + + return NT_STATUS_OK; +} + /* Fill in a credentails structure as anonymous */ void cli_credentials_set_anonymous(struct cli_credentials *cred) { diff --git a/source4/lib/gendb.c b/source4/lib/gendb.c new file mode 100644 index 0000000000..befdd63c9e --- /dev/null +++ b/source4/lib/gendb.c @@ -0,0 +1,80 @@ +/* + Unix SMB/CIFS implementation. + + common share info functions + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Tim Potter 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/ldb/include/ldb.h" + +/* + search the sam for the specified attributes - va_list variant +*/ +int gendb_search_v(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *basedn, + struct ldb_message ***res, + const char * const *attrs, + const char *format, + va_list ap) _PRINTF_ATTRIBUTE(6,0) +{ + char *expr = NULL; + int count; + + vasprintf(&expr, format, ap); + if (expr == NULL) { + return -1; + } + + *res = NULL; + + count = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE, expr, attrs, res); + + if (*res) talloc_steal(mem_ctx, *res); + + DEBUG(4,("gendb_search_v: %s %s -> %d (%s)\n", + basedn?basedn:"NULL", expr, count, + count==-1?ldb_errstring(ldb):"OK")); + + free(expr); + + return count; +} + +/* + search the LDB for the specified attributes - varargs variant +*/ +int gendb_search(struct ldb_context *sam_ldb, + TALLOC_CTX *mem_ctx, + const char *basedn, + struct ldb_message ***res, + const char * const *attrs, + const char *format, ...) _PRINTF_ATTRIBUTE(6,7) +{ + va_list ap; + int count; + + va_start(ap, format); + count = gendb_search_v(sam_ldb, mem_ctx, basedn, res, attrs, format, ap); + va_end(ap); + + return count; +} + |