summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
authorKarolin Seeger <kseeger@samba.org>2008-02-29 10:44:38 +0100
committerKarolin Seeger <kseeger@samba.org>2008-02-29 10:44:38 +0100
commitc4fbe2846231a6b322c1094c6a1dbf93b7305768 (patch)
tree09eb77a294f4acda131b41fe4c9bec4ed175eb16 /source3/winbindd
parent1a6415fc77c708b87c8e2ce6e7828f486ffc87ac (diff)
parent695b6662abe64a40061bfa05ede12173fc4b1945 (diff)
downloadsamba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.gz
samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.bz2
samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.zip
Merge commit 'origin/v3-2-test' into v3-2-stable
Conflicts: WHATSNEW.txt (This used to be commit a390bcf9403df4cf4d5eef42b35ebccbe253882e)
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/idmap_nss.c8
-rw-r--r--source3/winbindd/idmap_tdb2.c1017
-rw-r--r--source3/winbindd/winbindd.c4
-rw-r--r--source3/winbindd/winbindd.h18
-rw-r--r--source3/winbindd/winbindd_ads.c69
-rw-r--r--source3/winbindd/winbindd_async.c20
-rw-r--r--source3/winbindd/winbindd_cache.c85
-rw-r--r--source3/winbindd/winbindd_cm.c271
-rw-r--r--source3/winbindd/winbindd_creds.c14
-rw-r--r--source3/winbindd/winbindd_dual.c125
-rw-r--r--source3/winbindd/winbindd_locator.c12
-rw-r--r--source3/winbindd/winbindd_misc.c30
-rw-r--r--source3/winbindd/winbindd_ndr.c153
-rw-r--r--source3/winbindd/winbindd_pam.c378
-rw-r--r--source3/winbindd/winbindd_passdb.c14
-rw-r--r--source3/winbindd/winbindd_reconnect.c4
-rw-r--r--source3/winbindd/winbindd_rpc.c329
-rw-r--r--source3/winbindd/winbindd_util.c97
18 files changed, 2044 insertions, 604 deletions
diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
index 46c24d7fcb..e4acd9ce65 100644
--- a/source3/winbindd/idmap_nss.c
+++ b/source3/winbindd/idmap_nss.c
@@ -87,10 +87,10 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
/* by default calls to winbindd are disabled
the following call will not recurse so this is safe */
- winbind_on();
+ (void)winbind_on();
/* Lookup name from PDC using lsa_lookup_names() */
ret = winbind_lookup_name(dom->name, name, ids[i]->sid, &type);
- winbind_off();
+ (void)winbind_off();
if (!ret) {
/* TODO: how do we know if the name is really not mapped,
@@ -153,9 +153,9 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
/* by default calls to winbindd are disabled
the following call will not recurse so this is safe */
- winbind_on();
+ (void)winbind_on();
ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type);
- winbind_off();
+ (void)winbind_off();
if (!ret) {
/* TODO: how do we know if the name is really not mapped,
diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c
new file mode 100644
index 0000000000..ab89e615f7
--- /dev/null
+++ b/source3/winbindd/idmap_tdb2.c
@@ -0,0 +1,1017 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ idmap TDB2 backend, used for clustered Samba setups.
+
+ This uses 2 tdb files. One is permanent, and is in shared storage
+ on the cluster (using "tdb:idmap2.tdb =" in smb.conf). The other is a
+ temporary cache tdb on local storage.
+
+ Copyright (C) Andrew Tridgell 2007
+
+ This is heavily based upon idmap_tdb.c, which is:
+
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) Jeremy Allison 2006
+ Copyright (C) Simo Sorce 2003-2006
+
+ 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 "winbindd.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+/* High water mark keys */
+#define HWM_GROUP "GROUP HWM"
+#define HWM_USER "USER HWM"
+
+static struct idmap_tdb2_state {
+ /* User and group id pool */
+ uid_t low_uid, high_uid; /* Range of uids to allocate */
+ gid_t low_gid, high_gid; /* Range of gids to allocate */
+ const char *idmap_script;
+} idmap_tdb2_state;
+
+
+
+/* tdb context for the local cache tdb */
+static TDB_CONTEXT *idmap_tdb2_tmp;
+
+/* handle to the permanent tdb */
+static struct db_context *idmap_tdb2_perm;
+
+/*
+ open the cache tdb
+ */
+static NTSTATUS idmap_tdb2_open_cache_db(void)
+{
+ const char *db_path;
+
+ if (idmap_tdb2_tmp) {
+ /* its already open */
+ return NT_STATUS_OK;
+ }
+
+ db_path = lock_path("idmap2_cache.tdb");
+
+ /* Open idmap repository */
+ if (!(idmap_tdb2_tmp = tdb_open_log(db_path, 0, TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644))) {
+ DEBUG(0, ("Unable to open cache idmap database '%s'\n", db_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+static NTSTATUS idmap_tdb2_alloc_load(void);
+
+/*
+ open the permanent tdb
+ */
+static NTSTATUS idmap_tdb2_open_perm_db(void)
+{
+ char *db_path;
+
+ if (idmap_tdb2_perm) {
+ /* its already open */
+ return NT_STATUS_OK;
+ }
+
+ db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL);
+ if (db_path == NULL) {
+ /* fall back to the private directory, which, despite
+ its name, is usually on shared storage */
+ db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir());
+ }
+ NT_STATUS_HAVE_NO_MEMORY(db_path);
+
+ /* Open idmap repository */
+ idmap_tdb2_perm = db_open(NULL, db_path, 0, TDB_DEFAULT,
+ O_RDWR|O_CREAT, 0644);
+ TALLOC_FREE(db_path);
+
+ if (idmap_tdb2_perm == NULL) {
+ DEBUG(0, ("Unable to open permanent idmap database '%s'\n",
+ db_path));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* load the ranges and high/low water marks */
+ return idmap_tdb2_alloc_load();
+}
+
+
+/*
+ load the idmap allocation ranges and high/low water marks
+*/
+static NTSTATUS idmap_tdb2_alloc_load(void)
+{
+ const char *range;
+ uid_t low_uid = 0;
+ uid_t high_uid = 0;
+ gid_t low_gid = 0;
+ gid_t high_gid = 0;
+
+ /* load ranges */
+ idmap_tdb2_state.low_uid = 0;
+ idmap_tdb2_state.high_uid = 0;
+ idmap_tdb2_state.low_gid = 0;
+ idmap_tdb2_state.high_gid = 0;
+
+ /* see if a idmap script is configured */
+ idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL);
+
+ if (idmap_tdb2_state.idmap_script) {
+ DEBUG(1, ("using idmap script '%s'\n", idmap_tdb2_state.idmap_script));
+ }
+
+ range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL);
+ if (range && range[0]) {
+ unsigned low_id, high_id;
+ if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) {
+ if (low_id < high_id) {
+ idmap_tdb2_state.low_gid = idmap_tdb2_state.low_uid = low_id;
+ idmap_tdb2_state.high_gid = idmap_tdb2_state.high_uid = high_id;
+ } else {
+ DEBUG(1, ("ERROR: invalid idmap alloc range [%s]", range));
+ }
+ } else {
+ DEBUG(1, ("ERROR: invalid syntax for idmap alloc config:range [%s]", range));
+ }
+ }
+
+ /* Create high water marks for group and user id */
+ if (lp_idmap_uid(&low_uid, &high_uid)) {
+ idmap_tdb2_state.low_uid = low_uid;
+ idmap_tdb2_state.high_uid = high_uid;
+ }
+
+ if (lp_idmap_gid(&low_gid, &high_gid)) {
+ idmap_tdb2_state.low_gid = low_gid;
+ idmap_tdb2_state.high_gid = high_gid;
+ }
+
+ if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) {
+ DEBUG(1, ("idmap uid range missing or invalid\n"));
+ DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_USER)) == -1) ||
+ (low_id < idmap_tdb2_state.low_uid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_USER,
+ idmap_tdb2_state.low_uid) == -1) {
+ DEBUG(0, ("Unable to initialise user hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+ }
+ }
+
+ if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) {
+ DEBUG(1, ("idmap gid range missing or invalid\n"));
+ DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ } else {
+ uint32 low_id;
+
+ if (((low_id = dbwrap_fetch_int32(idmap_tdb2_perm,
+ HWM_GROUP)) == -1) ||
+ (low_id < idmap_tdb2_state.low_gid)) {
+ if (dbwrap_store_int32(
+ idmap_tdb2_perm, HWM_GROUP,
+ idmap_tdb2_state.low_gid) == -1) {
+ DEBUG(0, ("Unable to initialise group hwm in idmap database\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Initialise idmap alloc database.
+*/
+static NTSTATUS idmap_tdb2_alloc_init(const char *params)
+{
+ /* nothing to do - we want to avoid opening the permanent
+ database if possible. Instead we load the params when we
+ first need it. */
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Allocate a new id.
+*/
+static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid)
+{
+ bool ret;
+ const char *hwmkey;
+ const char *hwmtype;
+ uint32_t high_hwm;
+ uint32_t hwm;
+ NTSTATUS status;
+
+ status = idmap_tdb2_open_perm_db();
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ /* Get current high water mark */
+ switch (xid->type) {
+
+ case ID_TYPE_UID:
+ hwmkey = HWM_USER;
+ hwmtype = "UID";
+ high_hwm = idmap_tdb2_state.high_uid;
+ break;
+
+ case ID_TYPE_GID:
+ hwmkey = HWM_GROUP;
+ hwmtype = "GID";
+ high_hwm = idmap_tdb2_state.high_gid;
+ break;
+
+ default:
+ DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ /* check it is in the range */
+ if (hwm > high_hwm) {
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* fetch a new id and increment it */
+ ret = dbwrap_change_uint32_atomic(idmap_tdb2_perm, hwmkey, &hwm, 1);
+ if (ret == -1) {
+ DEBUG(1, ("Fatal error while fetching a new %s value\n!", hwmtype));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* recheck it is in the range */
+ if (hwm > high_hwm) {
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ xid->id = hwm;
+ DEBUG(10,("New %s = %d\n", hwmtype, hwm));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ Get current highest id.
+*/
+static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
+{
+ const char *hwmkey;
+ const char *hwmtype;
+ uint32_t hwm;
+ uint32_t high_hwm;
+
+ /* Get current high water mark */
+ switch (xid->type) {
+
+ case ID_TYPE_UID:
+ hwmkey = HWM_USER;
+ hwmtype = "UID";
+ high_hwm = idmap_tdb2_state.high_uid;
+ break;
+
+ case ID_TYPE_GID:
+ hwmkey = HWM_GROUP;
+ hwmtype = "GID";
+ high_hwm = idmap_tdb2_state.high_gid;
+ break;
+
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hwm = dbwrap_fetch_int32(idmap_tdb2_perm, hwmkey)) == -1) {
+ return NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ xid->id = hwm;
+
+ /* Warn if it is out of range */
+ if (hwm >= high_hwm) {
+ DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
+ hwmtype, (unsigned long)high_hwm));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ Set high id.
+*/
+static NTSTATUS idmap_tdb2_set_hwm(struct unixid *xid)
+{
+ /* not supported, or we would invalidate the cache tdb on
+ other nodes */
+ DEBUG(0,("idmap_tdb2_set_hwm not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+/*
+ Close the alloc tdb
+*/
+static NTSTATUS idmap_tdb2_alloc_close(void)
+{
+ /* don't actually close it */
+ return NT_STATUS_OK;
+}
+
+/*
+ IDMAP MAPPING TDB BACKEND
+*/
+struct idmap_tdb2_context {
+ uint32_t filter_low_id;
+ uint32_t filter_high_id;
+};
+
+/*
+ try fetching from the cache tdb, and if that fails then
+ fetch from the permanent tdb
+ */
+static TDB_DATA tdb2_fetch_bystring(TALLOC_CTX *mem_ctx, const char *keystr)
+{
+ TDB_DATA ret;
+ NTSTATUS status;
+
+ ret = tdb_fetch_bystring(idmap_tdb2_tmp, keystr);
+ if (ret.dptr != NULL) {
+ /* got it from cache */
+ unsigned char *tmp;
+
+ tmp = (unsigned char *)talloc_memdup(mem_ctx, ret.dptr,
+ ret.dsize);
+ SAFE_FREE(ret.dptr);
+ ret.dptr = tmp;
+
+ if (ret.dptr == NULL) {
+ return make_tdb_data(NULL, 0);
+ }
+ return ret;
+ }
+
+ status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return ret;
+ }
+
+ /* fetch from the permanent tdb */
+ return dbwrap_fetch_bystring(idmap_tdb2_perm, mem_ctx, keystr);
+}
+
+/*
+ store into both databases
+ */
+static NTSTATUS tdb2_store_bystring(const char *keystr, TDB_DATA data, int flags)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_store_bystring(idmap_tdb2_perm, keystr, data, flags);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_store_bystring(idmap_tdb2_tmp, keystr, data, flags) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
+ delete from both databases
+ */
+static NTSTATUS tdb2_delete_bystring(const char *keystr)
+{
+ NTSTATUS ret;
+ NTSTATUS status = idmap_tdb2_open_perm_db();
+ if (!NT_STATUS_IS_OK(status)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ ret = dbwrap_delete_bystring(idmap_tdb2_perm, keystr);
+ if (!NT_STATUS_IS_OK(ret)) {
+ ret = tdb_delete_bystring(idmap_tdb2_tmp, keystr) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+
+/*
+ Initialise idmap database.
+*/
+static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
+{
+ NTSTATUS ret;
+ struct idmap_tdb2_context *ctx;
+ char *config_option = NULL;
+ const char *range;
+ NTSTATUS status;
+
+ status = idmap_tdb2_open_cache_db();
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ ctx = talloc(dom, struct idmap_tdb2_context);
+ if ( ! ctx) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ config_option = talloc_asprintf(ctx, "idmap config %s", dom->name);
+ if ( ! config_option) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto failed;
+ }
+
+ range = lp_parm_const_string(-1, config_option, "range", NULL);
+ if (( ! range) ||
+ (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||
+ (ctx->filter_low_id > ctx->filter_high_id)) {
+ ctx->filter_low_id = 0;
+ ctx->filter_high_id = 0;
+ }
+
+ dom->private_data = ctx;
+ dom->initialized = True;
+
+ talloc_free(config_option);
+ return NT_STATUS_OK;
+
+failed:
+ talloc_free(ctx);
+ return ret;
+}
+
+
+/*
+ run a script to perform a mapping
+
+ The script should the following command lines:
+
+ SIDTOID S-1-xxxx
+ IDTOSID UID xxxx
+ IDTOSID GID xxxx
+
+ and should return one of the following as a single line of text
+ UID:xxxx
+ GID:xxxx
+ SID:xxxx
+ ERR:xxxx
+ */
+static NTSTATUS idmap_tdb2_script(struct idmap_tdb2_context *ctx, struct id_map *map,
+ const char *fmt, ...)
+{
+ va_list ap;
+ char *cmd;
+ FILE *p;
+ char line[64];
+ unsigned long v;
+
+ cmd = talloc_asprintf(ctx, "%s ", idmap_tdb2_state.idmap_script);
+ NT_STATUS_HAVE_NO_MEMORY(cmd);
+
+ va_start(ap, fmt);
+ cmd = talloc_vasprintf_append(cmd, fmt, ap);
+ va_end(ap);
+ NT_STATUS_HAVE_NO_MEMORY(cmd);
+
+ p = popen(cmd, "r");
+ talloc_free(cmd);
+ if (p == NULL) {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ if (fgets(line, sizeof(line)-1, p) == NULL) {
+ pclose(p);
+ return NT_STATUS_NONE_MAPPED;
+ }
+ pclose(p);
+
+ DEBUG(10,("idmap script gave: %s\n", line));
+
+ if (sscanf(line, "UID:%lu", &v) == 1) {
+ map->xid.id = v;
+ map->xid.type = ID_TYPE_UID;
+ } else if (sscanf(line, "GID:%lu", &v) == 1) {
+ map->xid.id = v;
+ map->xid.type = ID_TYPE_GID;
+ } else if (strncmp(line, "SID:S-", 6) == 0) {
+ if (!string_to_sid(map->sid, &line[4])) {
+ DEBUG(0,("Bad SID in '%s' from idmap script %s\n",
+ line, idmap_tdb2_state.idmap_script));
+ return NT_STATUS_NONE_MAPPED;
+ }
+ } else {
+ DEBUG(0,("Bad reply '%s' from idmap script %s\n",
+ line, idmap_tdb2_state.idmap_script));
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+
+/*
+ Single id to sid lookup function.
+*/
+static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_map *map)
+{
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *keystr;
+
+ if (!ctx || !map) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* apply filters before checking */
+ if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
+ (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
+ DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
+ map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ switch (map->xid.type) {
+
+ case ID_TYPE_UID:
+ keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ break;
+
+ case ID_TYPE_GID:
+ keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ break;
+
+ default:
+ DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* final SAFE_FREE safe */
+ data.dptr = NULL;
+
+ if (keystr == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10,("Fetching record %s\n", keystr));
+
+ /* Check if the mapping exists */
+ data = tdb2_fetch_bystring(keystr, keystr);
+
+ if (!data.dptr) {
+ fstring sidstr;
+
+ DEBUG(10,("Record %s not found\n", keystr));
+ if (idmap_tdb2_state.idmap_script == NULL) {
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr);
+
+ /* store it on shared storage */
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto done;
+ }
+
+ if (sid_to_fstring(sidstr, map->sid)) {
+ /* both forward and reverse mappings */
+ tdb2_store_bystring(keystr,
+ string_term_tdb_data(sidstr),
+ TDB_REPLACE);
+ tdb2_store_bystring(sidstr,
+ string_term_tdb_data(keystr),
+ TDB_REPLACE);
+ }
+ goto done;
+ }
+
+ if (!string_to_sid(map->sid, (const char *)data.dptr)) {
+ DEBUG(10,("INVALID SID (%s) in record %s\n",
+ (const char *)data.dptr, keystr));
+ ret = NT_STATUS_INTERNAL_DB_ERROR;
+ goto done;
+ }
+
+ DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(keystr);
+ return ret;
+}
+
+
+/*
+ Single sid to id lookup function.
+*/
+static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_map *map)
+{
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *keystr;
+ unsigned long rec_id = 0;
+
+ if ((keystr = sid_string_talloc(ctx, map->sid)) == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10,("Fetching record %s\n", keystr));
+
+ /* Check if sid is present in database */
+ data = tdb2_fetch_bystring(keystr, keystr);
+ if (!data.dptr) {
+ fstring idstr;
+
+ DEBUG(10,(__location__ " Record %s not found\n", keystr));
+
+ if (idmap_tdb2_state.idmap_script == NULL) {
+ ret = NT_STATUS_NONE_MAPPED;
+ goto done;
+ }
+
+ ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr);
+ /* store it on shared storage */
+ if (!NT_STATUS_IS_OK(ret)) {
+ goto done;
+ }
+
+ snprintf(idstr, sizeof(idstr), "%cID %lu",
+ map->xid.type == ID_TYPE_UID?'U':'G',
+ (unsigned long)map->xid.id);
+ /* store both forward and reverse mappings */
+ tdb2_store_bystring(keystr, string_term_tdb_data(idstr),
+ TDB_REPLACE);
+ tdb2_store_bystring(idstr, string_term_tdb_data(keystr),
+ TDB_REPLACE);
+ goto done;
+ }
+
+ /* What type of record is this ? */
+ if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */
+ map->xid.id = rec_id;
+ map->xid.type = ID_TYPE_UID;
+ DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr ));
+ ret = NT_STATUS_OK;
+
+ } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */
+ map->xid.id = rec_id;
+ map->xid.type = ID_TYPE_GID;
+ DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr ));
+ ret = NT_STATUS_OK;
+
+ } else { /* Unknown record type ! */
+ DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
+ ret = NT_STATUS_INTERNAL_DB_ERROR;
+ }
+
+ /* apply filters before returning result */
+ if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
+ (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
+ DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",
+ map->xid.id, ctx->filter_low_id, ctx->filter_high_id));
+ ret = NT_STATUS_NONE_MAPPED;
+ }
+
+done:
+ talloc_free(keystr);
+ return ret;
+}
+
+/*
+ lookup a set of unix ids.
+*/
+static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ int i;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ for (i = 0; ids[i]; i++) {
+ ret = idmap_tdb2_id_to_sid(ctx, ids[i]);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ /* if it is just a failed mapping continue */
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+
+ /* make sure it is marked as unmapped */
+ ids[i]->status = ID_UNMAPPED;
+ continue;
+ }
+
+ /* some fatal error occurred, return immediately */
+ goto done;
+ }
+
+ /* all ok, id is mapped */
+ ids[i]->status = ID_MAPPED;
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+/*
+ lookup a set of sids.
+*/
+static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ int i;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ for (i = 0; ids[i]; i++) {
+ ret = idmap_tdb2_sid_to_id(ctx, ids[i]);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+
+ /* if it is just a failed mapping continue */
+ if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+
+ /* make sure it is marked as unmapped */
+ ids[i]->status = ID_UNMAPPED;
+ continue;
+ }
+
+ /* some fatal error occurred, return immediately */
+ goto done;
+ }
+
+ /* all ok, id is mapped */
+ ids[i]->status = ID_MAPPED;
+ }
+
+ ret = NT_STATUS_OK;
+
+done:
+ return ret;
+}
+
+
+/*
+ set a mapping.
+*/
+static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
+{
+ struct idmap_tdb2_context *ctx;
+ NTSTATUS ret;
+ TDB_DATA data;
+ char *ksidstr, *kidstr;
+ struct db_record *update_lock = NULL;
+ struct db_record *rec = NULL;
+
+ /* make sure we initialized */
+ if ( ! dom->initialized) {
+ ret = idmap_tdb2_db_init(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
+ if (!map || !map->sid) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ksidstr = kidstr = NULL;
+ data.dptr = NULL;
+
+ /* TODO: should we filter a set_mapping using low/high filters ? */
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
+
+ switch (map->xid.type) {
+
+ case ID_TYPE_UID:
+ kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ break;
+
+ case ID_TYPE_GID:
+ kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ break;
+
+ default:
+ DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (kidstr == NULL) {
+ DEBUG(0, ("ERROR: Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if (!(ksidstr = sid_string_talloc(ctx, map->sid))) {
+ DEBUG(0, ("Out of memory!\n"));
+ ret = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr));
+
+ /*
+ * Get us the update lock. This is necessary to get the lock orders
+ * right, we need to deal with two records under a lock.
+ */
+
+ if (!(update_lock = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, ctx,
+ string_term_tdb_data("UPDATELOCK")))) {
+ DEBUG(10,("Failed to lock record %s\n", ksidstr));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /*
+ * *DELETE* previous mappings if any. *
+ */
+
+ /* First delete indexed on SID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(ksidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
+ }
+ TALLOC_FREE(rec);
+
+ /* Now delete indexed on unix ID */
+
+ if (((rec = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock,
+ string_term_tdb_data(kidstr))) != NULL)
+ && (rec->value.dsize != 0)) {
+ struct db_record *rec2;
+
+ if ((rec2 = idmap_tdb2_perm->fetch_locked(
+ idmap_tdb2_perm, update_lock, rec->value))
+ != NULL) {
+ rec2->delete_rec(rec2);
+ TALLOC_FREE(rec2);
+ }
+
+ rec->delete_rec(rec);
+
+ tdb_delete(idmap_tdb2_tmp, rec->key);
+ tdb_delete(idmap_tdb2_tmp, rec->value);
+ }
+ TALLOC_FREE(rec);
+
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(ksidstr, string_term_tdb_data(kidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing SID -> ID\n"));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+ if (!NT_STATUS_IS_OK(tdb2_store_bystring(kidstr, string_term_tdb_data(ksidstr),
+ TDB_INSERT))) {
+ DEBUG(0, ("Error storing ID -> SID\n"));
+ /* try to remove the previous stored SID -> ID map */
+ tdb2_delete_bystring(ksidstr);
+ ret = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr));
+ ret = NT_STATUS_OK;
+
+done:
+ talloc_free(ksidstr);
+ talloc_free(kidstr);
+ SAFE_FREE(data.dptr);
+ TALLOC_FREE(update_lock);
+ return ret;
+}
+
+/*
+ remove a mapping.
+*/
+static NTSTATUS idmap_tdb2_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
+{
+ /* not supported as it would invalidate the cache tdb on other
+ nodes */
+ DEBUG(0,("idmap_tdb2_remove_mapping not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+/*
+ Close the idmap tdb instance
+*/
+static NTSTATUS idmap_tdb2_close(struct idmap_domain *dom)
+{
+ /* don't do anything */
+ return NT_STATUS_OK;
+}
+
+
+/*
+ Dump all mappings out
+*/
+static NTSTATUS idmap_tdb2_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps)
+{
+ DEBUG(0,("idmap_tdb2_dump_data not supported\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static struct idmap_methods db_methods = {
+ .init = idmap_tdb2_db_init,
+ .unixids_to_sids = idmap_tdb2_unixids_to_sids,
+ .sids_to_unixids = idmap_tdb2_sids_to_unixids,
+ .set_mapping = idmap_tdb2_set_mapping,
+ .remove_mapping = idmap_tdb2_remove_mapping,
+ .dump_data = idmap_tdb2_dump_data,
+ .close_fn = idmap_tdb2_close
+};
+
+static struct idmap_alloc_methods db_alloc_methods = {
+ .init = idmap_tdb2_alloc_init,
+ .allocate_id = idmap_tdb2_allocate_id,
+ .get_id_hwm = idmap_tdb2_get_hwm,
+ .set_id_hwm = idmap_tdb2_set_hwm,
+ .close_fn = idmap_tdb2_alloc_close
+};
+
+NTSTATUS idmap_tdb2_init(void)
+{
+ NTSTATUS ret;
+
+ /* register both backends */
+ ret = smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_alloc_methods);
+ if (! NT_STATUS_IS_OK(ret)) {
+ DEBUG(0, ("Unable to register idmap alloc tdb2 module: %s\n", get_friendly_nt_error_msg(ret)));
+ return ret;
+ }
+
+ return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods);
+}
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 5e9900d1d6..615f4a918e 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1227,6 +1227,10 @@ int main(int argc, char **argv, char **envp)
MSG_WINBIND_VALIDATE_CACHE,
winbind_msg_validate_cache);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_WINBIND_DUMP_DOMAIN_LIST,
+ winbind_msg_dump_domain_list);
+
netsamlogon_cache_init(); /* Non-critical */
/* clear the cached list of trusted domains */
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 6bf6e6c68f..b812d69aeb 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -164,9 +164,9 @@ struct winbindd_domain {
fstring alt_name; /* alt Domain name, if any (FQDN for ADS) */
fstring forest_name; /* Name of the AD forest we're in */
DOM_SID sid; /* SID for this domain */
- uint32 domain_flags; /* Domain flags from rpc_ds.h */
- uint32 domain_type; /* Domain type from rpc_ds.h */
- uint32 domain_trust_attribs; /* Trust attribs from rpc_ds.h */
+ uint32 domain_flags; /* Domain flags from netlogon.h */
+ uint32 domain_type; /* Domain type from netlogon.h */
+ uint32 domain_trust_attribs; /* Trust attribs from netlogon.h */
bool initialized; /* Did we already ask for the domain mode? */
bool native_mode; /* is this a win2k domain in native mode ? */
bool active_directory; /* is this a win2k active directory ? */
@@ -301,15 +301,15 @@ struct winbindd_methods {
NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32 *seq);
/* return the lockout policy */
- NTSTATUS (*lockout_policy)(struct winbindd_domain *domain,
+ NTSTATUS (*lockout_policy)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_12 *lockout_policy);
-
+ struct samr_DomInfo12 *lockout_policy);
+
/* return the lockout policy */
- NTSTATUS (*password_policy)(struct winbindd_domain *domain,
+ NTSTATUS (*password_policy)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_1 *password_policy);
-
+ struct samr_DomInfo1 *password_policy);
+
/* enumerate trusted domains */
NTSTATUS (*trusted_domains)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index f963669825..0900d56987 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -421,7 +421,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
char *sidstr;
uint32 group_rid;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- NET_USER_INFO_3 *user;
+ struct netr_SamInfo3 *user = NULL;
DEBUG(3,("ads: query_user\n"));
@@ -437,11 +437,11 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
sid_string_dbg(sid)));
- sid_compose(&info->user_sid, &domain->sid, user->user_rid);
- sid_compose(&info->group_sid, &domain->sid, user->group_rid);
+ sid_compose(&info->user_sid, &domain->sid, user->base.rid);
+ sid_compose(&info->group_sid, &domain->sid, user->base.primary_gid);
- info->acct_name = unistr2_to_ascii_talloc(mem_ctx, &user->uni_user_name);
- info->full_name = unistr2_to_ascii_talloc(mem_ctx, &user->uni_full_name);
+ info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string);
+ info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string);
nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
&info->homedir, &info->shell, &info->full_name,
@@ -1157,12 +1157,11 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
DOM_SID **dom_sids)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- struct ds_domain_trust *domains = NULL;
- int count = 0;
+ struct netr_DomainTrustList trusts;
int i;
uint32 flags;
struct rpc_pipe_client *cli;
- uint32 fr_flags = (DS_DOMAIN_IN_FOREST | DS_DOMAIN_TREE_ROOT);
+ uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT);
int ret_count;
DEBUG(3,("ads: trusted_domains\n"));
@@ -1179,11 +1178,11 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
if ( domain->primary ||
((domain->domain_flags&fr_flags) == fr_flags) )
{
- flags = DS_DOMAIN_DIRECT_OUTBOUND |
- DS_DOMAIN_DIRECT_INBOUND |
- DS_DOMAIN_IN_FOREST;
+ flags = NETR_TRUST_FLAG_OUTBOUND |
+ NETR_TRUST_FLAG_INBOUND |
+ NETR_TRUST_FLAG_IN_FOREST;
} else {
- flags = DS_DOMAIN_IN_FOREST;
+ flags = NETR_TRUST_FLAG_IN_FOREST;
}
result = cm_connect_netlogon(domain, &cli);
@@ -1194,29 +1193,27 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
domain->name, nt_errstr(result)));
return NT_STATUS_UNSUCCESSFUL;
}
-
- if ( NT_STATUS_IS_OK(result) ) {
- result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
- cli->cli->desthost,
- flags, &domains,
- (unsigned int *)&count);
- }
-
- if ( NT_STATUS_IS_OK(result) && count) {
+
+ result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
+ cli->cli->desthost,
+ flags,
+ &trusts,
+ NULL);
+ if ( NT_STATUS_IS_OK(result) && trusts.count) {
/* Allocate memory for trusted domain names and sids */
- if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, count)) ) {
+ if ( !(*names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) {
DEBUG(0, ("trusted_domains: out of memory\n"));
return NT_STATUS_NO_MEMORY;
}
- if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, count)) ) {
+ if ( !(*alt_names = TALLOC_ARRAY(mem_ctx, char *, trusts.count)) ) {
DEBUG(0, ("trusted_domains: out of memory\n"));
return NT_STATUS_NO_MEMORY;
}
- if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, count)) ) {
+ if ( !(*dom_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, trusts.count)) ) {
DEBUG(0, ("trusted_domains: out of memory\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -1225,7 +1222,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
ret_count = 0;
- for (i = 0; i < count; i++) {
+ for (i = 0; i < trusts.count; i++) {
struct winbindd_domain d;
/* drop external trusts if this is not our primary
@@ -1233,24 +1230,24 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
domains may be less that the ones actually trusted
by the DC. */
- if ( (domains[i].trust_attributes == DS_DOMAIN_TRUST_ATTRIB_QUARANTINED_DOMAIN) &&
+ if ( (trusts.array[i].trust_attributes == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) &&
!domain->primary )
{
DEBUG(10,("trusted_domains: Skipping external trusted domain "
"%s because it is outside of our primary domain\n",
- domains[i].netbios_domain));
+ trusts.array[i].netbios_name));
continue;
}
- (*names)[ret_count] = domains[i].netbios_domain;
- (*alt_names)[ret_count] = domains[i].dns_domain;
- sid_copy(&(*dom_sids)[ret_count], &domains[i].sid);
+ (*names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].netbios_name);
+ (*alt_names)[ret_count] = CONST_DISCARD(char *, trusts.array[i].dns_name);
+ sid_copy(&(*dom_sids)[ret_count], trusts.array[i].sid);
/* add to the trusted domain cache */
- fstrcpy( d.name, domains[i].netbios_domain );
- fstrcpy( d.alt_name, domains[i].dns_domain );
- sid_copy( &d.sid, &domains[i].sid );
+ fstrcpy( d.name, trusts.array[i].netbios_name);
+ fstrcpy( d.alt_name, trusts.array[i].dns_name);
+ sid_copy( &d.sid, trusts.array[i].sid);
/* This gets a little tricky. If we are
following a transitive forest trust, then
@@ -1269,9 +1266,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
we have the current trust flags and
attributes */
- d.domain_flags = domains[i].flags;
- d.domain_type = domains[i].trust_type;
- d.domain_trust_attribs = domains[i].trust_attributes;
+ d.domain_flags = trusts.array[i].trust_flags;
+ d.domain_type = trusts.array[i].trust_type;
+ d.domain_trust_attribs = trusts.array[i].trust_attributes;
} else {
/* Look up the record in the cache */
struct winbindd_tdc_domain *parent;
diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c
index ab32ee0c76..2ff5ef230d 100644
--- a/source3/winbindd/winbindd_async.c
+++ b/source3/winbindd/winbindd_async.c
@@ -283,9 +283,8 @@ static void lookupname_recv2(TALLOC_CTX *mem_ctx, bool success,
enum lsa_SidType type) =
(void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c;
DOM_SID sid;
- struct lookupname_state *s = talloc_get_type_abort( private_data,
+ struct lookupname_state *s = talloc_get_type_abort( private_data,
struct lookupname_state );
-
if (!success) {
DEBUG(5, ("Could not trigger lookup_name\n"));
@@ -311,7 +310,7 @@ static void lookupname_recv2(TALLOC_CTX *mem_ctx, bool success,
}
/********************************************************************
- This is the first callback after contacting our own domain
+ This is the first callback after contacting our own domain
********************************************************************/
static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
@@ -322,7 +321,7 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
enum lsa_SidType type) =
(void (*)(void *, bool, const DOM_SID *, enum lsa_SidType))c;
DOM_SID sid;
- struct lookupname_state *s = talloc_get_type_abort( private_data,
+ struct lookupname_state *s = talloc_get_type_abort( private_data,
struct lookupname_state );
if (!success) {
@@ -334,8 +333,8 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
if (response->result != WINBINDD_OK) {
/* Try again using the forest root */
struct winbindd_domain *root_domain = find_root_domain();
- struct winbindd_request request;
-
+ struct winbindd_request request;
+
if ( !root_domain ) {
DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
@@ -346,7 +345,7 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
request.cmd = WINBINDD_LOOKUPNAME;
fstrcpy( request.data.name.dom_name, s->dom_name );
- fstrcpy( request.data.name.name, s->name );
+ fstrcpy( request.data.name.name, s->name );
do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
(void *)cont, s);
@@ -381,7 +380,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
{
struct winbindd_request request;
struct winbindd_domain *domain;
- struct lookupname_state *s;
+ struct lookupname_state *s;
if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
DEBUG(5, ("Could not find domain for name '%s'\n", dom_name));
@@ -403,6 +402,11 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
s->dom_name = talloc_strdup( s, dom_name );
s->name = talloc_strdup( s, name );
+ if (!s->dom_name || !s->name) {
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
s->caller_private_data = private_data;
do_async_domain(mem_ctx, domain, &request, lookupname_recv,
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index c293861492..4d81ee3960 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -908,7 +908,9 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI
centry_free(centry);
}
-static void wcache_save_lockout_policy(struct winbindd_domain *domain, NTSTATUS status, SAM_UNK_INFO_12 *lockout_policy)
+static void wcache_save_lockout_policy(struct winbindd_domain *domain,
+ NTSTATUS status,
+ struct samr_DomInfo12 *lockout_policy)
{
struct cache_entry *centry;
@@ -916,18 +918,20 @@ static void wcache_save_lockout_policy(struct winbindd_domain *domain, NTSTATUS
if (!centry)
return;
- centry_put_nttime(centry, lockout_policy->duration);
- centry_put_nttime(centry, lockout_policy->reset_count);
- centry_put_uint16(centry, lockout_policy->bad_attempt_lockout);
+ centry_put_nttime(centry, lockout_policy->lockout_duration);
+ centry_put_nttime(centry, lockout_policy->lockout_window);
+ centry_put_uint16(centry, lockout_policy->lockout_threshold);
centry_end(centry, "LOC_POL/%s", domain->name);
-
+
DEBUG(10,("wcache_save_lockout_policy: %s\n", domain->name));
centry_free(centry);
}
-static void wcache_save_password_policy(struct winbindd_domain *domain, NTSTATUS status, SAM_UNK_INFO_1 *policy)
+static void wcache_save_password_policy(struct winbindd_domain *domain,
+ NTSTATUS status,
+ struct samr_DomInfo1 *policy)
{
struct cache_entry *centry;
@@ -935,14 +939,14 @@ static void wcache_save_password_policy(struct winbindd_domain *domain, NTSTATUS
if (!centry)
return;
- centry_put_uint16(centry, policy->min_length_password);
- centry_put_uint16(centry, policy->password_history);
+ centry_put_uint16(centry, policy->min_password_length);
+ centry_put_uint16(centry, policy->password_history_length);
centry_put_uint32(centry, policy->password_properties);
- centry_put_nttime(centry, policy->expire);
- centry_put_nttime(centry, policy->min_passwordage);
+ centry_put_nttime(centry, policy->max_password_age);
+ centry_put_nttime(centry, policy->min_password_age);
centry_end(centry, "PWD_POL/%s", domain->name);
-
+
DEBUG(10,("wcache_save_password_policy: %s\n", domain->name));
centry_free(centry);
@@ -2131,55 +2135,56 @@ skip_save:
/* get lockout policy */
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_12 *policy){
+ struct samr_DomInfo12 *policy)
+{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
-
+
if (!cache->tdb)
goto do_query;
-
+
centry = wcache_fetch(cache, domain, "LOC_POL/%s", domain->name);
-
+
if (!centry)
goto do_query;
-
- policy->duration = centry_nttime(centry);
- policy->reset_count = centry_nttime(centry);
- policy->bad_attempt_lockout = centry_uint16(centry);
-
+
+ policy->lockout_duration = centry_nttime(centry);
+ policy->lockout_window = centry_nttime(centry);
+ policy->lockout_threshold = centry_uint16(centry);
+
status = centry->status;
-
+
DEBUG(10,("lockout_policy: [Cached] - cached info for domain %s status: %s\n",
domain->name, nt_errstr(status) ));
-
+
centry_free(centry);
return status;
-
+
do_query:
ZERO_STRUCTP(policy);
-
+
/* Return status value returned by seq number check */
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
-
+
DEBUG(10,("lockout_policy: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
-
- status = domain->backend->lockout_policy(domain, mem_ctx, policy);
-
+
+ status = domain->backend->lockout_policy(domain, mem_ctx, policy);
+
/* and save it */
refresh_sequence_number(domain, false);
wcache_save_lockout_policy(domain, status, policy);
-
+
return status;
}
-
+
/* get password policy */
static NTSTATUS password_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_1 *policy)
+ struct samr_DomInfo1 *policy)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
@@ -2187,17 +2192,17 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
if (!cache->tdb)
goto do_query;
-
+
centry = wcache_fetch(cache, domain, "PWD_POL/%s", domain->name);
-
+
if (!centry)
goto do_query;
- policy->min_length_password = centry_uint16(centry);
- policy->password_history = centry_uint16(centry);
+ policy->min_password_length = centry_uint16(centry);
+ policy->password_history_length = centry_uint16(centry);
policy->password_properties = centry_uint32(centry);
- policy->expire = centry_nttime(centry);
- policy->min_passwordage = centry_nttime(centry);
+ policy->max_password_age = centry_nttime(centry);
+ policy->min_password_age = centry_nttime(centry);
status = centry->status;
@@ -2214,11 +2219,11 @@ do_query:
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
-
+
DEBUG(10,("password_policy: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
- status = domain->backend->password_policy(domain, mem_ctx, policy);
+ status = domain->backend->password_policy(domain, mem_ctx, policy);
/* and save it */
refresh_sequence_number(domain, false);
@@ -2243,7 +2248,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
/* Invalidate the getpwnam and getgroups entries for a winbindd domain */
void wcache_invalidate_samlogon(struct winbindd_domain *domain,
- NET_USER_INFO_3 *info3)
+ struct netr_SamInfo3 *info3)
{
struct winbind_cache *cache;
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 908228717e..0f536cdfb8 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -570,8 +570,8 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
WERROR werr;
TALLOC_CTX *mem_ctx;
unsigned int orig_timeout;
- char *tmp = NULL;
- char *p;
+ const char *tmp = NULL;
+ const char *p;
/* Hmmmm. We can only open one connection to the NETLOGON pipe at the
* moment.... */
@@ -602,48 +602,60 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
if (our_domain->active_directory) {
- struct DS_DOMAIN_CONTROLLER_INFO *domain_info = NULL;
-
- werr = rpccli_netlogon_dsr_getdcname(netlogon_pipe,
- mem_ctx,
- our_domain->dcname,
- domain->name,
- NULL,
- NULL,
- DS_RETURN_DNS_NAME,
- &domain_info);
+ struct netr_DsRGetDCNameInfo *domain_info = NULL;
+
+ result = rpccli_netr_DsRGetDCName(netlogon_pipe,
+ mem_ctx,
+ our_domain->dcname,
+ domain->name,
+ NULL,
+ NULL,
+ DS_RETURN_DNS_NAME,
+ &domain_info,
+ &werr);
if (W_ERROR_IS_OK(werr)) {
- fstrcpy(tmp, domain_info->domain_controller_name);
+ tmp = talloc_strdup(
+ mem_ctx, domain_info->dc_unc);
+ if (tmp == NULL) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ talloc_destroy(mem_ctx);
+ return false;
+ }
if (strlen(domain->alt_name) == 0) {
fstrcpy(domain->alt_name,
domain_info->domain_name);
}
if (strlen(domain->forest_name) == 0) {
fstrcpy(domain->forest_name,
- domain_info->dns_forest_name);
+ domain_info->forest_name);
}
}
} else {
-
- werr = rpccli_netlogon_getanydcname(netlogon_pipe,
- mem_ctx,
- our_domain->dcname,
- domain->name,
- &tmp);
+ result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,
+ our_domain->dcname,
+ domain->name,
+ &tmp,
+ &werr);
}
/* And restore our original timeout. */
cli_set_timeout(netlogon_pipe->cli, orig_timeout);
- talloc_destroy(mem_ctx);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
+ nt_errstr(result)));
+ talloc_destroy(mem_ctx);
+ return false;
+ }
if (!W_ERROR_IS_OK(werr)) {
- DEBUG(10, ("rpccli_netlogon_getanydcname failed: %s\n",
+ DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
dos_errstr(werr)));
- return False;
+ talloc_destroy(mem_ctx);
+ return false;
}
- /* cli_netlogon_getanydcname gives us a name with \\ */
+ /* rpccli_netr_GetAnyDCName gives us a name with \\ */
p = tmp;
if (*p == '\\') {
p+=1;
@@ -654,7 +666,9 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
fstrcpy(dcname, p);
- DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname));
+ talloc_destroy(mem_ctx);
+
+ DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
if (!resolve_name(dcname, dc_ss, 0x20)) {
return False;
@@ -672,8 +686,22 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
char **machine_krb5_principal)
{
const char *account_name;
+ const char *name = NULL;
+
+ /* If we are a DC and this is not our own domain */
- if (!get_trust_pw_clear(domain->name, machine_password,
+ if (IS_DC) {
+ name = domain->name;
+ } else {
+ struct winbindd_domain *our_domain = find_our_domain();
+
+ if (!our_domain)
+ return NT_STATUS_INVALID_SERVER_STATE;
+
+ name = our_domain->name;
+ }
+
+ if (!get_trust_pw_clear(name, machine_password,
&account_name, NULL))
{
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
@@ -687,11 +715,15 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
/* this is at least correct when domain is our domain,
* which is the only case, when this is currently used: */
- if ((machine_krb5_principal != NULL) &&
- (asprintf(machine_krb5_principal, "%s$@%s", account_name,
- domain->alt_name) == -1))
+ if (machine_krb5_principal != NULL)
{
- return NT_STATUS_NO_MEMORY;
+ if (asprintf(machine_krb5_principal, "%s$@%s",
+ account_name, domain->alt_name) == -1)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ strupper_m(*machine_krb5_principal);
}
return NT_STATUS_OK;
@@ -1691,12 +1723,11 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
{
struct winbindd_domain *our_domain;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- struct ds_domain_trust *domains = NULL;
- int count = 0;
+ struct netr_DomainTrustList trusts;
int i;
- uint32 flags = (DS_DOMAIN_IN_FOREST |
- DS_DOMAIN_DIRECT_OUTBOUND |
- DS_DOMAIN_DIRECT_INBOUND);
+ uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
+ NETR_TRUST_FLAG_OUTBOUND |
+ NETR_TRUST_FLAG_INBOUND);
struct rpc_pipe_client *cli;
TALLOC_CTX *mem_ctx = NULL;
@@ -1738,27 +1769,35 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
return False;
}
- result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
- cli->cli->desthost,
- flags, &domains,
- (unsigned int *)&count);
+ result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
+ cli->cli->desthost,
+ flags,
+ &trusts,
+ NULL);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("set_dc_type_and_flags_trustinfo: "
+ "failed to query trusted domain list: %s\n",
+ nt_errstr(result)));
+ talloc_destroy(mem_ctx);
+ return false;
+ }
/* Now find the domain name and get the flags */
- for ( i=0; i<count; i++ ) {
- if ( strequal( domain->name, domains[i].netbios_domain ) ) {
- domain->domain_flags = domains[i].flags;
- domain->domain_type = domains[i].trust_type;
- domain->domain_trust_attribs = domains[i].trust_attributes;
-
- if ( domain->domain_type == DS_DOMAIN_TRUST_TYPE_UPLEVEL )
+ for ( i=0; i<trusts.count; i++ ) {
+ if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
+ domain->domain_flags = trusts.array[i].trust_flags;
+ domain->domain_type = trusts.array[i].trust_type;
+ domain->domain_trust_attribs = trusts.array[i].trust_attributes;
+
+ if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
domain->active_directory = True;
/* This flag is only set if the domain is *our*
primary domain and the primary domain is in
native mode */
- domain->native_mode = (domain->domain_flags & DS_DOMAIN_NATIVE_MODE);
+ domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
"native mode.\n", domain->name,
@@ -1794,18 +1833,13 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
{
NTSTATUS result;
- DS_DOMINFO_CTR ctr;
+ WERROR werr;
TALLOC_CTX *mem_ctx = NULL;
struct rpc_pipe_client *cli;
POLICY_HND pol;
+ union dssetup_DsRoleInfo info;
+ union lsa_PolicyInformation *lsa_info = NULL;
- const char *domain_name = NULL;
- const char *dns_name = NULL;
- const char *forest_name = NULL;
- DOM_SID *dom_sid = NULL;
-
- ZERO_STRUCT( ctr );
-
if (!connection_ok(domain)) {
return;
}
@@ -1819,24 +1853,25 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
- cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_DSSETUP,
&result);
if (cli == NULL) {
DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
- "PI_LSARPC_DS on domain %s: (%s)\n",
+ "PI_DSSETUP on domain %s: (%s)\n",
domain->name, nt_errstr(result)));
/* if this is just a non-AD domain we need to continue
* identifying so that we can in the end return with
* domain->initialized = True - gd */
- goto no_lsarpc_ds;
+ goto no_dssetup;
}
- result = rpccli_ds_getprimarydominfo(cli, mem_ctx,
- DsRolePrimaryDomainInfoBasic,
- &ctr);
+ result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
+ DS_ROLE_BASIC_INFORMATION,
+ &info,
+ &werr);
cli_rpc_pipe_close(cli);
if (!NT_STATUS_IS_OK(result)) {
@@ -1845,26 +1880,26 @@ static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
domain->name, nt_errstr(result)));
/* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
- * every opcode on the LSARPC_DS pipe, continue with
- * no_lsarpc_ds mode here as well to get domain->initialized
+ * every opcode on the DSSETUP pipe, continue with
+ * no_dssetup mode here as well to get domain->initialized
* set - gd */
if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
- goto no_lsarpc_ds;
+ goto no_dssetup;
}
TALLOC_FREE(mem_ctx);
return;
}
-
- if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
- !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
+
+ if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
+ !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
domain->native_mode = True;
} else {
domain->native_mode = False;
}
-no_lsarpc_ds:
+no_dssetup:
cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
if (cli == NULL) {
@@ -1882,54 +1917,65 @@ no_lsarpc_ds:
if (NT_STATUS_IS_OK(result)) {
/* This particular query is exactly what Win2k clients use
to determine that the DC is active directory */
- result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
- 12, &domain_name,
- &dns_name, &forest_name,
- NULL, &dom_sid);
+ result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
+ &pol,
+ LSA_POLICY_INFO_DNS,
+ &lsa_info);
}
if (NT_STATUS_IS_OK(result)) {
domain->active_directory = True;
- if (domain_name)
- fstrcpy(domain->name, domain_name);
+ if (lsa_info->dns.name.string) {
+ fstrcpy(domain->name, lsa_info->dns.name.string);
+ }
- if (dns_name)
- fstrcpy(domain->alt_name, dns_name);
+ if (lsa_info->dns.dns_domain.string) {
+ fstrcpy(domain->alt_name,
+ lsa_info->dns.dns_domain.string);
+ }
/* See if we can set some domain trust flags about
ourself */
- if ( forest_name ) {
- fstrcpy(domain->forest_name, forest_name);
+ if (lsa_info->dns.dns_forest.string) {
+ fstrcpy(domain->forest_name,
+ lsa_info->dns.dns_forest.string);
if (strequal(domain->forest_name, domain->alt_name)) {
- domain->domain_flags = DS_DOMAIN_TREE_ROOT;
+ domain->domain_flags = NETR_TRUST_FLAG_TREEROOT;
}
}
- if (dom_sid)
- sid_copy(&domain->sid, dom_sid);
+ if (lsa_info->dns.sid) {
+ sid_copy(&domain->sid, lsa_info->dns.sid);
+ }
} else {
domain->active_directory = False;
result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&pol);
-
- if (!NT_STATUS_IS_OK(result))
+
+ if (!NT_STATUS_IS_OK(result)) {
goto done;
-
- result = rpccli_lsa_query_info_policy(cli, mem_ctx,
- &pol, 5, &domain_name,
- &dom_sid);
-
+ }
+
+ result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
+ &pol,
+ LSA_POLICY_INFO_ACCOUNT_DOMAIN,
+ &lsa_info);
+
if (NT_STATUS_IS_OK(result)) {
- if (domain_name)
- fstrcpy(domain->name, domain_name);
- if (dom_sid)
- sid_copy(&domain->sid, dom_sid);
+ if (lsa_info->account_domain.name.string) {
+ fstrcpy(domain->name,
+ lsa_info->account_domain.name.string);
+ }
+
+ if (lsa_info->account_domain.sid) {
+ sid_copy(&domain->sid, lsa_info->account_domain.sid);
+ }
}
}
done:
@@ -2076,13 +2122,14 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
"pipe: user %s\\%s\n", domain->name,
domain_name, machine_account));
- result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &conn->sam_connect_handle);
+ result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
+ conn->samr_pipe->cli->desthost,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &conn->sam_connect_handle);
if (NT_STATUS_IS_OK(result)) {
goto open_domain;
}
- DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
+ DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
"failed for domain %s, error was %s. Trying schannel\n",
domain->name, nt_errstr(result) ));
cli_rpc_pipe_close(conn->samr_pipe);
@@ -2110,13 +2157,14 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
"schannel.\n", domain->name ));
- result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &conn->sam_connect_handle);
+ result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
+ conn->samr_pipe->cli->desthost,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &conn->sam_connect_handle);
if (NT_STATUS_IS_OK(result)) {
goto open_domain;
}
- DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
+ DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
"for domain %s, error was %s. Trying anonymous\n",
domain->name, nt_errstr(result) ));
cli_rpc_pipe_close(conn->samr_pipe);
@@ -2132,23 +2180,24 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
goto done;
}
- result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &conn->sam_connect_handle);
+ result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
+ conn->samr_pipe->cli->desthost,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &conn->sam_connect_handle);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
+ DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
"for domain %s Error was %s\n",
domain->name, nt_errstr(result) ));
goto done;
}
open_domain:
- result = rpccli_samr_open_domain(conn->samr_pipe,
- mem_ctx,
- &conn->sam_connect_handle,
- SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain->sid,
- &conn->sam_domain_handle);
+ result = rpccli_samr_OpenDomain(conn->samr_pipe,
+ mem_ctx,
+ &conn->sam_connect_handle,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sid,
+ &conn->sam_domain_handle);
done:
@@ -2291,7 +2340,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
struct winbindd_cm_conn *conn;
NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint8 mach_pwd[16];
uint32 sec_chan_type;
const char *account_name;
diff --git a/source3/winbindd/winbindd_creds.c b/source3/winbindd/winbindd_creds.c
index 62facb6769..9c7acd64e6 100644
--- a/source3/winbindd/winbindd_creds.c
+++ b/source3/winbindd/winbindd_creds.c
@@ -29,11 +29,11 @@
NTSTATUS winbindd_get_creds(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const DOM_SID *sid,
- NET_USER_INFO_3 **info3,
+ struct netr_SamInfo3 **info3,
const uint8 *cached_nt_pass[NT_HASH_LEN],
const uint8 *cred_salt[NT_HASH_LEN])
{
- NET_USER_INFO_3 *info;
+ struct netr_SamInfo3 *info;
NTSTATUS status;
status = wcache_get_creds(domain, mem_ctx, sid, cached_nt_pass, cred_salt);
@@ -56,7 +56,7 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const char *user,
const char *pass,
- NET_USER_INFO_3 *info3,
+ struct netr_SamInfo3 *info3,
const DOM_SID *user_sid)
{
NTSTATUS status;
@@ -66,10 +66,10 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
if (info3 != NULL) {
DOM_SID sid;
- sid_copy(&sid, &(info3->dom_sid.sid));
- sid_append_rid(&sid, info3->user_rid);
+ sid_copy(&sid, info3->base.domain_sid);
+ sid_append_rid(&sid, info3->base.rid);
sid_copy(&cred_sid, &sid);
- info3->user_flgs |= LOGON_CACHED_ACCOUNT;
+ info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT;
} else if (user_sid != NULL) {
@@ -138,7 +138,7 @@ NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const char *user,
const char *pass,
- NET_USER_INFO_3 *info3)
+ struct netr_SamInfo3 *info3)
{
return winbindd_store_creds(domain, mem_ctx, user, pass, info3, NULL);
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 778886d8e2..2b756b24d1 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -34,20 +34,22 @@
#define DBGC_CLASS DBGC_WINBIND
extern bool override_logfile;
+extern struct winbindd_methods cache_methods;
/* Read some data from a client connection */
static void child_read_request(struct winbindd_cli_state *state)
{
- ssize_t len;
+ NTSTATUS status;
/* Read data */
- len = read_data(state->sock, (char *)&state->request,
- sizeof(state->request), NULL);
+ status = read_data(state->sock, (char *)&state->request,
+ sizeof(state->request));
- if (len != sizeof(state->request)) {
- DEBUG(len > 0 ? 0 : 3, ("Got invalid request length: %d\n", (int)len));
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("child_read_request: read_data failed: %s\n",
+ nt_errstr(status)));
state->finished = True;
return;
}
@@ -71,11 +73,12 @@ static void child_read_request(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.extra_data.data[state->request.extra_len] = '\0';
- len = read_data(state->sock, state->request.extra_data.data,
- state->request.extra_len, NULL);
+ status= read_data(state->sock, state->request.extra_data.data,
+ state->request.extra_len);
- if (len != state->request.extra_len) {
- DEBUG(0, ("Could not read extra data\n"));
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Could not read extra data: %s\n",
+ nt_errstr(status)));
state->finished = True;
return;
}
@@ -480,7 +483,6 @@ void winbind_child_died(pid_t pid)
child->event.fd = 0;
child->event.flags = 0;
child->pid = 0;
- SAFE_FREE(child->logfilename);
schedule_async_request(child);
}
@@ -677,6 +679,88 @@ void winbind_msg_dump_event_list(struct messaging_context *msg_ctx,
}
+void winbind_msg_dump_domain_list(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ TALLOC_CTX *mem_ctx;
+ const char *message = NULL;
+ struct server_id *sender = NULL;
+ const char *domain = NULL;
+ char *s = NULL;
+ NTSTATUS status;
+ struct winbindd_domain *dom = NULL;
+
+ DEBUG(5,("winbind_msg_dump_domain_list received.\n"));
+
+ if (!data || !data->data) {
+ return;
+ }
+
+ if (data->length < sizeof(struct server_id)) {
+ return;
+ }
+
+ mem_ctx = talloc_init("winbind_msg_dump_domain_list");
+ if (!mem_ctx) {
+ return;
+ }
+
+ sender = (struct server_id *)data->data;
+ if (data->length > sizeof(struct server_id)) {
+ domain = (const char *)data->data+sizeof(struct server_id);
+ }
+
+ if (domain) {
+
+ DEBUG(5,("winbind_msg_dump_domain_list for domain: %s\n",
+ domain));
+
+ message = NDR_PRINT_STRUCT_STRING(mem_ctx, winbindd_domain,
+ find_domain_from_name_noinit(domain));
+ if (!message) {
+ talloc_destroy(mem_ctx);
+ return;
+ }
+
+ messaging_send_buf(msg_ctx, *sender,
+ MSG_WINBIND_DUMP_DOMAIN_LIST,
+ (uint8_t *)message, strlen(message) + 1);
+
+ talloc_destroy(mem_ctx);
+
+ return;
+ }
+
+ DEBUG(5,("winbind_msg_dump_domain_list all domains\n"));
+
+ for (dom = domain_list(); dom; dom=dom->next) {
+ message = NDR_PRINT_STRUCT_STRING(mem_ctx, winbindd_domain, dom);
+ if (!message) {
+ talloc_destroy(mem_ctx);
+ return;
+ }
+
+ s = talloc_asprintf_append(s, "%s\n", message);
+ if (!s) {
+ talloc_destroy(mem_ctx);
+ return;
+ }
+ }
+
+ status = messaging_send_buf(msg_ctx, *sender,
+ MSG_WINBIND_DUMP_DOMAIN_LIST,
+ (uint8_t *)s, strlen(s) + 1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("failed to send message: %s\n",
+ nt_errstr(status)));
+ }
+
+ talloc_destroy(mem_ctx);
+}
+
static void account_lockout_policy_handler(struct event_context *ctx,
struct timed_event *te,
const struct timeval *now,
@@ -686,7 +770,7 @@ static void account_lockout_policy_handler(struct event_context *ctx,
(struct winbindd_child *)private_data;
TALLOC_CTX *mem_ctx = NULL;
struct winbindd_methods *methods;
- SAM_UNK_INFO_12 lockout_policy;
+ struct samr_DomInfo12 lockout_policy;
NTSTATUS result;
DEBUG(10,("account_lockout_policy_handler called\n"));
@@ -878,6 +962,13 @@ static bool fork_domain_child(struct winbindd_child *child)
struct winbindd_cli_state state;
struct winbindd_domain *domain;
+ if (child->domain) {
+ DEBUG(10, ("fork_domain_child called for domain '%s'\n",
+ child->domain->name));
+ } else {
+ DEBUG(10, ("fork_domain_child called without domain.\n"));
+ }
+
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) {
DEBUG(0, ("Could not open child pipe: %s\n",
strerror(errno)));
@@ -947,6 +1038,8 @@ static bool fork_domain_child(struct winbindd_child *child)
MSG_WINBIND_ONLINESTATUS, NULL);
messaging_deregister(winbind_messaging_context(),
MSG_DUMP_EVENT_LIST, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_WINBIND_DUMP_DOMAIN_LIST, NULL);
/* Handle online/offline messages. */
messaging_register(winbind_messaging_context(), NULL,
@@ -991,6 +1084,16 @@ static bool fork_domain_child(struct winbindd_child *child)
child);
}
+ /* Special case for Winbindd on a Samba DC,
+ * We want to make sure the child can connect to smbd
+ * but not the main daemon */
+
+ if (child->domain && child->domain->internal && IS_DC) {
+ child->domain->internal = False;
+ child->domain->methods = &cache_methods;
+ child->domain->online = False;
+ }
+
while (1) {
int ret;
diff --git a/source3/winbindd/winbindd_locator.c b/source3/winbindd/winbindd_locator.c
index 05bd74af25..10a6c5afeb 100644
--- a/source3/winbindd/winbindd_locator.c
+++ b/source3/winbindd/winbindd_locator.c
@@ -58,7 +58,7 @@ static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result;
- struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
+ struct netr_DsRGetDCNameInfo *info = NULL;
const char *dc = NULL;
state->request.domain_name
@@ -67,22 +67,22 @@ static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain,
DEBUG(3, ("[%5lu]: dsgetdcname for %s\n", (unsigned long)state->pid,
state->request.domain_name));
- result = dsgetdcname(state->mem_ctx, NULL, state->request.domain_name,
+ result = dsgetdcname(state->mem_ctx, state->request.domain_name,
NULL, NULL, state->request.flags, &info);
if (!NT_STATUS_IS_OK(result)) {
return WINBINDD_ERROR;
}
- if (info->domain_controller_address) {
- dc = info->domain_controller_address;
+ if (info->dc_address) {
+ dc = info->dc_address;
if ((dc[0] == '\\') && (dc[1] == '\\')) {
dc += 2;
}
}
- if ((!dc || !is_ipaddress_v4(dc)) && info->domain_controller_name) {
- dc = info->domain_controller_name;
+ if ((!dc || !is_ipaddress_v4(dc)) && info->dc_unc) {
+ dc = info->dc_unc;
}
if (!dc || !*dc) {
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 76f2554122..c22da3e8ef 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -231,8 +231,8 @@ void winbindd_getdcname(struct winbindd_cli_state *state)
enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
- char *dcname_slash = NULL;
- char *p;
+ const char *dcname_slash = NULL;
+ const char *p;
struct rpc_pipe_client *netlogon_pipe;
NTSTATUS result;
WERROR werr;
@@ -259,19 +259,29 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
req_domain = find_domain_from_name_noinit(state->request.domain_name);
if (req_domain == domain) {
- werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx,
- domain->dcname,
- state->request.domain_name,
- &dcname_slash);
+ result = rpccli_netr_GetDcName(netlogon_pipe,
+ state->mem_ctx,
+ domain->dcname,
+ state->request.domain_name,
+ &dcname_slash,
+ &werr);
} else {
- werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx,
- domain->dcname,
- state->request.domain_name,
- &dcname_slash);
+ result = rpccli_netr_GetAnyDCName(netlogon_pipe,
+ state->mem_ctx,
+ domain->dcname,
+ state->request.domain_name,
+ &dcname_slash,
+ &werr);
}
/* And restore our original timeout. */
cli_set_timeout(netlogon_pipe->cli, orig_timeout);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(5,("Error requesting DCname for domain %s: %s\n",
+ state->request.domain_name, nt_errstr(result)));
+ return WINBINDD_ERROR;
+ }
+
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("Error requesting DCname for domain %s: %s\n",
state->request.domain_name, dos_errstr(werr)));
diff --git a/source3/winbindd/winbindd_ndr.c b/source3/winbindd/winbindd_ndr.c
new file mode 100644
index 0000000000..842c915c5f
--- /dev/null
+++ b/source3/winbindd/winbindd_ndr.c
@@ -0,0 +1,153 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * winbindd debug helper
+ * Copyright (C) Guenther Deschner 2008
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "winbindd.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_WINBIND
+
+/****************************************************************
+****************************************************************/
+
+void ndr_print_winbindd_child(struct ndr_print *ndr,
+ const char *name,
+ const struct winbindd_child *r)
+{
+ ndr_print_struct(ndr, name, "winbindd_child");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "next", r->next);
+ ndr_print_ptr(ndr, "prev", r->prev);
+ ndr_print_uint32(ndr, "pid", (uint32_t)r->pid);
+#if 0
+ ndr_print_winbindd_domain(ndr, "domain", r->domain);
+#else
+ ndr_print_ptr(ndr, "domain", r->domain);
+#endif
+ ndr_print_string(ndr, "logfilename", r->logfilename);
+ /* struct fd_event event; */
+ ndr_print_ptr(ndr, "lockout_policy_event", r->lockout_policy_event);
+ ndr_print_ptr(ndr, "requests", r->requests);
+ ndr_print_ptr(ndr, "table", r->table);
+ ndr->depth--;
+}
+
+/****************************************************************
+****************************************************************/
+
+void ndr_print_winbindd_cm_conn(struct ndr_print *ndr,
+ const char *name,
+ const struct winbindd_cm_conn *r)
+{
+ ndr_print_struct(ndr, name, "winbindd_cm_conn");
+ ndr->depth++;
+ ndr_print_ptr(ndr, "cli", r->cli);
+ ndr_print_ptr(ndr, "samr_pipe", r->samr_pipe);
+ ndr_print_policy_handle(ndr, "sam_connect_handle", &r->sam_connect_handle);
+ ndr_print_policy_handle(ndr, "sam_domain_handle", &r->sam_domain_handle);
+ ndr_print_ptr(ndr, "lsa_pipe", r->lsa_pipe);
+ ndr_print_policy_handle(ndr, "lsa_policy", &r->lsa_policy);
+ ndr_print_ptr(ndr, "netlogon_pipe", r->netlogon_pipe);
+ ndr->depth--;
+}
+
+/****************************************************************
+****************************************************************/
+
+void ndr_print_winbindd_methods(struct ndr_print *ndr,
+ const char *name,
+ const struct winbindd_methods *r)
+{
+#ifdef HAVE_ADS
+ extern struct winbindd_methods ads_methods;
+#endif
+ extern struct winbindd_methods msrpc_methods;
+ extern struct winbindd_methods passdb_methods;
+ extern struct winbindd_methods reconnect_methods;
+ extern struct winbindd_methods cache_methods;
+
+ ndr_print_struct(ndr, name, "winbindd_methods");
+ ndr->depth++;
+
+ if (r == NULL) {
+ ndr_print_string(ndr, name, "(NULL)");
+ ndr->depth--;
+ return;
+ }
+
+ if (r == &msrpc_methods) {
+ ndr_print_string(ndr, name, "msrpc_methods");
+#ifdef HAVE_ADS
+ } else if (r == &ads_methods) {
+ ndr_print_string(ndr, name, "ads_methods");
+#endif
+ } else if (r == &passdb_methods) {
+ ndr_print_string(ndr, name, "passdb_methods");
+ } else if (r == &reconnect_methods) {
+ ndr_print_string(ndr, name, "reconnect_methods");
+ } else if (r == &cache_methods) {
+ ndr_print_string(ndr, name, "cache_methods");
+ } else {
+ ndr_print_string(ndr, name, "UNKNOWN");
+ }
+ ndr->depth--;
+}
+
+/****************************************************************
+****************************************************************/
+
+void ndr_print_winbindd_domain(struct ndr_print *ndr,
+ const char *name,
+ const struct winbindd_domain *r)
+{
+ if (!r) {
+ return;
+ }
+
+ ndr_print_struct(ndr, name, "winbindd_domain");
+ ndr->depth++;
+ ndr_print_string(ndr, "name", r->name);
+ ndr_print_string(ndr, "alt_name", r->alt_name);
+ ndr_print_string(ndr, "forest_name", r->forest_name);
+ ndr_print_dom_sid(ndr, "sid", &r->sid);
+ ndr_print_netr_TrustFlags(ndr, "domain_flags", r->domain_flags);
+ ndr_print_netr_TrustType(ndr, "domain_type", r->domain_type);
+ ndr_print_netr_TrustAttributes(ndr, "domain_trust_attribs", r->domain_trust_attribs);
+ ndr_print_bool(ndr, "initialized", r->initialized);
+ ndr_print_bool(ndr, "native_mode", r->native_mode);
+ ndr_print_bool(ndr, "active_directory", r->active_directory);
+ ndr_print_bool(ndr, "primary", r->primary);
+ ndr_print_bool(ndr, "internal", r->internal);
+ ndr_print_bool(ndr, "online", r->online);
+ ndr_print_time_t(ndr, "startup_time", r->startup_time);
+ ndr_print_bool(ndr, "startup", r->startup);
+ ndr_print_winbindd_methods(ndr, "methods", r->methods);
+ ndr_print_winbindd_methods(ndr, "backend", r->backend);
+ ndr_print_ptr(ndr, "private_data", r->private_data);
+ ndr_print_string(ndr, "dcname", r->dcname);
+ ndr_print_sockaddr_storage(ndr, "dcaddr", &r->dcaddr);
+ ndr_print_time_t(ndr, "last_seq_check", r->last_seq_check);
+ ndr_print_uint32(ndr, "sequence_number", r->sequence_number);
+ ndr_print_NTSTATUS(ndr, "last_status", r->last_status);
+ ndr_print_winbindd_cm_conn(ndr, "conn", &r->conn);
+ ndr_print_winbindd_child(ndr, "child", &r->child);
+ ndr_print_uint32(ndr, "check_online_timeout", r->check_online_timeout);
+ ndr_print_ptr(ndr, "check_online_event", r->check_online_event);
+ ndr->depth--;
+}
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 525096b0a2..ef5a312eea 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -29,139 +29,162 @@
static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 *info3)
+ struct netr_SamInfo3 *info3)
{
- fstring str_sid;
+ char *ex;
+ size_t size;
+ uint32_t i;
state->response.data.auth.info3.logon_time =
- nt_time_to_unix(info3->logon_time);
+ nt_time_to_unix(info3->base.last_logon);
state->response.data.auth.info3.logoff_time =
- nt_time_to_unix(info3->logoff_time);
+ nt_time_to_unix(info3->base.last_logoff);
state->response.data.auth.info3.kickoff_time =
- nt_time_to_unix(info3->kickoff_time);
+ nt_time_to_unix(info3->base.acct_expiry);
state->response.data.auth.info3.pass_last_set_time =
- nt_time_to_unix(info3->pass_last_set_time);
+ nt_time_to_unix(info3->base.last_password_change);
state->response.data.auth.info3.pass_can_change_time =
- nt_time_to_unix(info3->pass_can_change_time);
+ nt_time_to_unix(info3->base.allow_password_change);
state->response.data.auth.info3.pass_must_change_time =
- nt_time_to_unix(info3->pass_must_change_time);
-
- state->response.data.auth.info3.logon_count = info3->logon_count;
- state->response.data.auth.info3.bad_pw_count = info3->bad_pw_count;
-
- state->response.data.auth.info3.user_rid = info3->user_rid;
- state->response.data.auth.info3.group_rid = info3->group_rid;
- sid_to_fstring(str_sid, &(info3->dom_sid.sid));
- fstrcpy(state->response.data.auth.info3.dom_sid, str_sid);
-
- state->response.data.auth.info3.num_groups = info3->num_groups;
- state->response.data.auth.info3.user_flgs = info3->user_flgs;
-
- state->response.data.auth.info3.acct_flags = info3->acct_flags;
- state->response.data.auth.info3.num_other_sids = info3->num_other_sids;
-
- unistr2_to_ascii(state->response.data.auth.info3.user_name,
- &info3->uni_user_name,
- sizeof(state->response.data.auth.info3.user_name));
- unistr2_to_ascii(state->response.data.auth.info3.full_name,
- &info3->uni_full_name,
- sizeof(state->response.data.auth.info3.full_name));
- unistr2_to_ascii(state->response.data.auth.info3.logon_script,
- &info3->uni_logon_script,
- sizeof(state->response.data.auth.info3.logon_script));
- unistr2_to_ascii(state->response.data.auth.info3.profile_path,
- &info3->uni_profile_path,
- sizeof(state->response.data.auth.info3.profile_path));
- unistr2_to_ascii(state->response.data.auth.info3.home_dir,
- &info3->uni_home_dir,
- sizeof(state->response.data.auth.info3.home_dir));
- unistr2_to_ascii(state->response.data.auth.info3.dir_drive,
- &info3->uni_dir_drive,
- sizeof(state->response.data.auth.info3.dir_drive));
-
- unistr2_to_ascii(state->response.data.auth.info3.logon_srv,
- &info3->uni_logon_srv,
- sizeof(state->response.data.auth.info3.logon_srv));
- unistr2_to_ascii(state->response.data.auth.info3.logon_dom,
- &info3->uni_logon_dom,
- sizeof(state->response.data.auth.info3.logon_dom));
+ nt_time_to_unix(info3->base.force_password_change);
+
+ state->response.data.auth.info3.logon_count = info3->base.logon_count;
+ state->response.data.auth.info3.bad_pw_count = info3->base.bad_password_count;
+
+ state->response.data.auth.info3.user_rid = info3->base.rid;
+ state->response.data.auth.info3.group_rid = info3->base.primary_gid;
+ sid_to_fstring(state->response.data.auth.info3.dom_sid, info3->base.domain_sid);
+
+ state->response.data.auth.info3.num_groups = info3->base.groups.count;
+ state->response.data.auth.info3.user_flgs = info3->base.user_flags;
+
+ state->response.data.auth.info3.acct_flags = info3->base.acct_flags;
+ state->response.data.auth.info3.num_other_sids = info3->sidcount;
+
+ fstrcpy(state->response.data.auth.info3.user_name,
+ info3->base.account_name.string);
+ fstrcpy(state->response.data.auth.info3.full_name,
+ info3->base.full_name.string);
+ fstrcpy(state->response.data.auth.info3.logon_script,
+ info3->base.logon_script.string);
+ fstrcpy(state->response.data.auth.info3.profile_path,
+ info3->base.profile_path.string);
+ fstrcpy(state->response.data.auth.info3.home_dir,
+ info3->base.home_directory.string);
+ fstrcpy(state->response.data.auth.info3.dir_drive,
+ info3->base.home_drive.string);
+
+ fstrcpy(state->response.data.auth.info3.logon_srv,
+ info3->base.logon_server.string);
+ fstrcpy(state->response.data.auth.info3.logon_dom,
+ info3->base.domain.string);
+
+ ex = talloc_strdup(mem_ctx, "");
+ NT_STATUS_HAVE_NO_MEMORY(ex);
+
+ for (i=0; i < info3->base.groups.count; i++) {
+ ex = talloc_asprintf_append_buffer(ex, "0x%08X:0x%08X\n",
+ info3->base.groups.rids[i].rid,
+ info3->base.groups.rids[i].attributes);
+ NT_STATUS_HAVE_NO_MEMORY(ex);
+ }
+
+ for (i=0; i < info3->sidcount; i++) {
+ char *sid;
+
+ sid = dom_sid_string(mem_ctx, info3->sids[i].sid);
+ NT_STATUS_HAVE_NO_MEMORY(sid);
+
+ ex = talloc_asprintf_append_buffer(ex, "%s:0x%08X\n",
+ sid,
+ info3->sids[i].attributes);
+ NT_STATUS_HAVE_NO_MEMORY(ex);
+
+ talloc_free(sid);
+ }
+
+ size = talloc_get_size(ex);
+
+ SAFE_FREE(state->response.extra_data.data);
+ state->response.extra_data.data = SMB_MALLOC(size);
+ if (!state->response.extra_data.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memcpy(state->response.extra_data.data, ex, size);
+ talloc_free(ex);
+
+ state->response.length += size;
return NT_STATUS_OK;
}
static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 *info3)
+ struct netr_SamInfo3 *info3)
{
- prs_struct ps;
- uint32 size;
- if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
- return NT_STATUS_NO_MEMORY;
- }
- if (!net_io_user_info3("", info3, &ps, 1, 3, False)) {
- prs_mem_free(&ps);
- return NT_STATUS_UNSUCCESSFUL;
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3,
+ (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0,("append_info3_as_ndr: failed to append\n"));
+ return ndr_map_error2ntstatus(ndr_err);
}
- size = prs_data_size(&ps);
SAFE_FREE(state->response.extra_data.data);
- state->response.extra_data.data = SMB_MALLOC(size);
+ state->response.extra_data.data = SMB_MALLOC(blob.length);
if (!state->response.extra_data.data) {
- prs_mem_free(&ps);
+ data_blob_free(&blob);
return NT_STATUS_NO_MEMORY;
}
- memset( state->response.extra_data.data, '\0', size );
- prs_copy_all_data_out((char *)state->response.extra_data.data, &ps);
- state->response.length += size;
- prs_mem_free(&ps);
+
+ memset(state->response.extra_data.data, '\0', blob.length);
+ memcpy(state->response.extra_data.data, blob.data, blob.length);
+ state->response.length += blob.length;
+
+ data_blob_free(&blob);
+
return NT_STATUS_OK;
}
static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
- const NET_USER_INFO_3 *info3,
+ const struct netr_SamInfo3 *info3,
const char *name_domain,
const char *name_user)
{
/* We've been asked to return the unix username, per
'winbind use default domain' settings and the like */
- fstring username_out;
const char *nt_username, *nt_domain;
- if (!(nt_domain = unistr2_to_ascii_talloc(mem_ctx,
- &info3->uni_logon_dom))) {
+ nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
+ if (!nt_domain) {
/* If the server didn't give us one, just use the one
* we sent them */
nt_domain = name_domain;
}
- if (!(nt_username = unistr2_to_ascii_talloc(mem_ctx,
- &info3->uni_user_name))) {
+ nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
+ if (!nt_username) {
/* If the server didn't give us one, just use the one
* we sent them */
nt_username = name_user;
}
- fill_domain_username(username_out, nt_domain, nt_username,
- True);
+ fill_domain_username(state->response.data.auth.unix_username,
+ nt_domain, nt_username, True);
- DEBUG(5,("Setting unix username to [%s]\n", username_out));
-
- SAFE_FREE(state->response.extra_data.data);
- state->response.extra_data.data = SMB_STRDUP(username_out);
- if (!state->response.extra_data.data) {
- return NT_STATUS_NO_MEMORY;
- }
- state->response.length +=
- strlen((const char *)state->response.extra_data.data)+1;
+ DEBUG(5,("Setting unix username to [%s]\n",
+ state->response.data.auth.unix_username));
return NT_STATUS_OK;
}
static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
- const NET_USER_INFO_3 *info3,
+ const struct netr_SamInfo3 *info3,
const char *name_domain,
const char *name_user)
{
@@ -185,8 +208,8 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
DOM_SID user_sid;
fstring sidstr;
- sid_copy(&user_sid, &info3->dom_sid.sid);
- sid_append_rid(&user_sid, info3->user_rid);
+ sid_copy(&user_sid, info3->base.domain_sid);
+ sid_append_rid(&user_sid, info3->base.rid);
sid_to_fstring(sidstr, &user_sid);
afsname = talloc_string_sub(mem_ctx, afsname,
"%s", sidstr);
@@ -223,7 +246,7 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
}
static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
- NET_USER_INFO_3 *info3,
+ struct netr_SamInfo3 *info3,
const char *group_sid)
/**
* Check whether a user belongs to a group or list of groups.
@@ -327,7 +350,7 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state,
if (IS_DC) {
domain = find_domain_from_name_noinit(domain_name);
if (domain == NULL) {
- DEBUG(3, ("Authentication for domain [%s] refused"
+ DEBUG(3, ("Authentication for domain [%s] refused "
"as it is not a trusted domain\n",
domain_name));
}
@@ -373,7 +396,7 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
{
struct winbindd_methods *methods;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- SAM_UNK_INFO_1 password_policy;
+ struct samr_DomInfo1 password_policy;
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(5,("fillup_password_policy: No inbound trust to "
@@ -389,28 +412,28 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain,
}
state->response.data.auth.policy.min_length_password =
- password_policy.min_length_password;
+ password_policy.min_password_length;
state->response.data.auth.policy.password_history =
- password_policy.password_history;
+ password_policy.password_history_length;
state->response.data.auth.policy.password_properties =
password_policy.password_properties;
state->response.data.auth.policy.expire =
- nt_time_to_unix_abs(&(password_policy.expire));
- state->response.data.auth.policy.min_passwordage =
- nt_time_to_unix_abs(&(password_policy.min_passwordage));
+ nt_time_to_unix_abs((NTTIME *)&(password_policy.max_password_age));
+ state->response.data.auth.policy.min_passwordage =
+ nt_time_to_unix_abs((NTTIME *)&(password_policy.min_password_age));
return NT_STATUS_OK;
}
static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint16 *max_allowed_bad_attempts)
+ uint16 *lockout_threshold)
{
struct winbindd_methods *methods;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- SAM_UNK_INFO_12 lockout_policy;
+ struct samr_DomInfo12 lockout_policy;
- *max_allowed_bad_attempts = 0;
+ *lockout_threshold = 0;
methods = domain->methods;
@@ -419,7 +442,7 @@ static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain
return status;
}
- *max_allowed_bad_attempts = lockout_policy.bad_attempt_lockout;
+ *lockout_threshold = lockout_policy.lockout_threshold;
return NT_STATUS_OK;
}
@@ -430,7 +453,7 @@ static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,
{
struct winbindd_methods *methods;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- SAM_UNK_INFO_1 password_policy;
+ struct samr_DomInfo1 password_policy;
*password_properties = 0;
@@ -537,7 +560,7 @@ static uid_t get_uid_from_state(struct winbindd_cli_state *state)
static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 **info3)
+ struct netr_SamInfo3 **info3)
{
#ifdef HAVE_KRB5
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -705,17 +728,17 @@ failed:
static bool check_request_flags(uint32_t flags)
{
uint32_t flags_edata = WBFLAG_PAM_AFS_TOKEN |
- WBFLAG_PAM_UNIX_NAME |
+ WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_INFO3_NDR;
if ( ( (flags & flags_edata) == WBFLAG_PAM_AFS_TOKEN) ||
( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) ||
- ( (flags & flags_edata) == WBFLAG_PAM_UNIX_NAME) ||
+ ( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)||
!(flags & flags_edata) ) {
return True;
}
- DEBUG(1,("check_request_flags: invalid request flags\n"));
+ DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags));
return False;
}
@@ -724,7 +747,7 @@ static bool check_request_flags(uint32_t flags)
****************************************************************/
static NTSTATUS append_data(struct winbindd_cli_state *state,
- NET_USER_INFO_3 *info3,
+ struct netr_SamInfo3 *info3,
const char *name_domain,
const char *name_user)
{
@@ -733,14 +756,14 @@ static NTSTATUS append_data(struct winbindd_cli_state *state,
if (flags & WBFLAG_PAM_USER_SESSION_KEY) {
memcpy(state->response.data.auth.user_session_key,
- info3->user_sess_key,
+ info3->base.key.key,
sizeof(state->response.data.auth.user_session_key)
/* 16 */);
}
if (flags & WBFLAG_PAM_LMKEY) {
memcpy(state->response.data.auth.first_8_lm_hash,
- info3->lm_sess_key,
+ info3->base.LMSessKey.key,
sizeof(state->response.data.auth.first_8_lm_hash)
/* 8 */);
}
@@ -841,7 +864,7 @@ void winbindd_pam_auth(struct winbindd_cli_state *state)
NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 **info3)
+ struct netr_SamInfo3 **info3)
{
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
uint16 max_allowed_bad_attempts;
@@ -851,7 +874,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
uchar new_nt_pass[NT_HASH_LEN];
const uint8 *cached_nt_pass;
const uint8 *cached_salt;
- NET_USER_INFO_3 *my_info3;
+ struct netr_SamInfo3 *my_info3;
time_t kickoff_time, must_change_time;
bool password_good = False;
#ifdef HAVE_KRB5
@@ -923,43 +946,43 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
/* User *DOES* know the password, update logon_time and reset
* bad_pw_count */
- my_info3->user_flgs |= LOGON_CACHED_ACCOUNT;
+ my_info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT;
- if (my_info3->acct_flags & ACB_AUTOLOCK) {
+ if (my_info3->base.acct_flags & ACB_AUTOLOCK) {
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
- if (my_info3->acct_flags & ACB_DISABLED) {
+ if (my_info3->base.acct_flags & ACB_DISABLED) {
return NT_STATUS_ACCOUNT_DISABLED;
}
- if (my_info3->acct_flags & ACB_WSTRUST) {
+ if (my_info3->base.acct_flags & ACB_WSTRUST) {
return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
}
- if (my_info3->acct_flags & ACB_SVRTRUST) {
+ if (my_info3->base.acct_flags & ACB_SVRTRUST) {
return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
}
- if (my_info3->acct_flags & ACB_DOMTRUST) {
+ if (my_info3->base.acct_flags & ACB_DOMTRUST) {
return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
}
- if (!(my_info3->acct_flags & ACB_NORMAL)) {
+ if (!(my_info3->base.acct_flags & ACB_NORMAL)) {
DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n",
- my_info3->acct_flags));
+ my_info3->base.acct_flags));
return NT_STATUS_LOGON_FAILURE;
}
- kickoff_time = nt_time_to_unix(my_info3->kickoff_time);
+ kickoff_time = nt_time_to_unix(my_info3->base.acct_expiry);
if (kickoff_time != 0 && time(NULL) > kickoff_time) {
return NT_STATUS_ACCOUNT_EXPIRED;
}
- must_change_time = nt_time_to_unix(my_info3->pass_must_change_time);
+ must_change_time = nt_time_to_unix(my_info3->base.force_password_change);
if (must_change_time != 0 && must_change_time < time(NULL)) {
/* we allow grace logons when the password has expired */
- my_info3->user_flgs |= LOGON_GRACE_LOGON;
+ my_info3->base.user_flags |= NETLOGON_GRACE_LOGON;
/* return NT_STATUS_PASSWORD_EXPIRED; */
goto success;
}
@@ -967,7 +990,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
#ifdef HAVE_KRB5
if ((state->request.flags & WBFLAG_PAM_KRB5) &&
((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) &&
- (tdc_domain->trust_type & DS_DOMAIN_TRUST_TYPE_UPLEVEL)) {
+ (tdc_domain->trust_type & NETR_TRUST_TYPE_UPLEVEL)) {
uid_t uid = -1;
const char *cc = NULL;
@@ -1030,8 +1053,8 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
/* FIXME: we possibly should handle logon hours as well (does xp when
* offline?) see auth/auth_sam.c:sam_account_ok for details */
- unix_to_nt_time(&my_info3->logon_time, time(NULL));
- my_info3->bad_pw_count = 0;
+ unix_to_nt_time(&my_info3->base.last_logon, time(NULL));
+ my_info3->base.bad_password_count = 0;
result = winbindd_update_creds_by_info3(domain,
state->mem_ctx,
@@ -1058,14 +1081,14 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
}
/* increase counter */
- my_info3->bad_pw_count++;
+ my_info3->base.bad_password_count++;
if (max_allowed_bad_attempts == 0) {
goto failed;
}
/* lockout user */
- if (my_info3->bad_pw_count >= max_allowed_bad_attempts) {
+ if (my_info3->base.bad_password_count >= max_allowed_bad_attempts) {
uint32 password_properties;
@@ -1074,9 +1097,9 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain,
DEBUG(10,("winbindd_dual_pam_auth_cached: failed to get password properties.\n"));
}
- if ((my_info3->user_rid != DOMAIN_USER_RID_ADMIN) ||
- (password_properties & DOMAIN_LOCKOUT_ADMINS)) {
- my_info3->acct_flags |= ACB_AUTOLOCK;
+ if ((my_info3->base.rid != DOMAIN_USER_RID_ADMIN) ||
+ (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) {
+ my_info3->base.acct_flags |= ACB_AUTOLOCK;
}
}
@@ -1097,7 +1120,7 @@ failed:
NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 **info3)
+ struct netr_SamInfo3 **info3)
{
struct winbindd_domain *contact_domain;
fstring name_domain, name_user;
@@ -1156,7 +1179,7 @@ done:
NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
struct winbindd_cli_state *state,
- NET_USER_INFO_3 **info3)
+ struct netr_SamInfo3 **info3)
{
struct rpc_pipe_client *netlogon_pipe;
@@ -1170,18 +1193,10 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
fstring name_domain, name_user;
bool retry;
NTSTATUS result;
- NET_USER_INFO_3 *my_info3;
-
- ZERO_STRUCTP(info3);
+ struct netr_SamInfo3 *my_info3 = NULL;
*info3 = NULL;
- my_info3 = TALLOC_ZERO_P(state->mem_ctx, NET_USER_INFO_3);
- if (my_info3 == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
-
DEBUG(10,("winbindd_dual_pam_auth_samlogon\n"));
/* Parse domain and username */
@@ -1289,7 +1304,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
chal,
lm_resp,
nt_resp,
- my_info3);
+ &my_info3);
attempts += 1;
/* We have to try a second time as cm_connect_netlogon
@@ -1323,16 +1338,14 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
* caller, we look up the account flags ourselve - gd */
if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) &&
- (my_info3->acct_flags == 0) && NT_STATUS_IS_OK(result)) {
+ (my_info3->base.acct_flags == 0) && NT_STATUS_IS_OK(result)) {
struct rpc_pipe_client *samr_pipe;
POLICY_HND samr_domain_handle, user_pol;
- SAM_USERINFO_CTR *user_ctr;
+ union samr_UserInfo *info = NULL;
NTSTATUS status_tmp;
uint32 acct_flags;
- ZERO_STRUCT(user_ctr);
-
status_tmp = cm_connect_sam(contact_domain, state->mem_ctx,
&samr_pipe, &samr_domain_handle);
@@ -1342,10 +1355,11 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
goto done;
}
- status_tmp = rpccli_samr_open_user(samr_pipe, state->mem_ctx,
- &samr_domain_handle,
- MAXIMUM_ALLOWED_ACCESS,
- my_info3->user_rid, &user_pol);
+ status_tmp = rpccli_samr_OpenUser(samr_pipe, state->mem_ctx,
+ &samr_domain_handle,
+ MAXIMUM_ALLOWED_ACCESS,
+ my_info3->base.rid,
+ &user_pol);
if (!NT_STATUS_IS_OK(status_tmp)) {
DEBUG(3, ("could not open user handle on SAMR pipe: %s\n",
@@ -1353,28 +1367,30 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
goto done;
}
- status_tmp = rpccli_samr_query_userinfo(samr_pipe, state->mem_ctx,
- &user_pol, 16, &user_ctr);
+ status_tmp = rpccli_samr_QueryUserInfo(samr_pipe, state->mem_ctx,
+ &user_pol,
+ 16,
+ &info);
if (!NT_STATUS_IS_OK(status_tmp)) {
DEBUG(3, ("could not query user info on SAMR pipe: %s\n",
nt_errstr(status_tmp)));
- rpccli_samr_close(samr_pipe, state->mem_ctx, &user_pol);
+ rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
goto done;
}
- acct_flags = user_ctr->info.id16->acb_info;
+ acct_flags = info->info16.acct_flags;
if (acct_flags == 0) {
- rpccli_samr_close(samr_pipe, state->mem_ctx, &user_pol);
+ rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
goto done;
}
- my_info3->acct_flags = acct_flags;
+ my_info3->base.acct_flags = acct_flags;
DEBUG(10,("successfully retrieved acct_flags 0x%x\n", acct_flags));
- rpccli_samr_close(samr_pipe, state->mem_ctx, &user_pol);
+ rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);
}
*info3 = my_info3;
@@ -1388,8 +1404,8 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain,
NTSTATUS result = NT_STATUS_LOGON_FAILURE;
NTSTATUS krb5_result = NT_STATUS_OK;
fstring name_domain, name_user;
- NET_USER_INFO_3 *info3 = NULL;
-
+ struct netr_SamInfo3 *info3 = NULL;
+
/* Ensure null termination */
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
@@ -1484,7 +1500,7 @@ sam_logon:
DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n"));
/* add the Krb5 err if we have one */
if ( NT_STATUS_EQUAL(krb5_result, NT_STATUS_TIME_DIFFERENCE_AT_DC ) ) {
- info3->user_flgs |= LOGON_KRB5_FAIL_CLOCK_SKEW;
+ info3->base.user_flags |= LOGON_KRB5_FAIL_CLOCK_SKEW;
}
goto process_result;
}
@@ -1544,8 +1560,8 @@ process_result:
the cache entry by storing the seq_num for the wrong
domain). */
if ( domain->primary ) {
- sid_compose(&user_sid, &info3->dom_sid.sid,
- info3->user_rid);
+ sid_compose(&user_sid, info3->base.domain_sid,
+ info3->base.rid);
cache_name2sid(domain, name_domain, name_user,
SID_NAME_USER, &user_sid);
}
@@ -1710,7 +1726,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
NTSTATUS result;
- NET_USER_INFO_3 info3;
+ struct netr_SamInfo3 *info3 = NULL;
struct rpc_pipe_client *netlogon_pipe;
const char *name_user = NULL;
const char *name_domain = NULL;
@@ -1788,7 +1804,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
}
do {
- ZERO_STRUCT(info3);
retry = False;
netlogon_pipe = NULL;
@@ -1842,12 +1857,12 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
if (NT_STATUS_IS_OK(result)) {
- netsamlogon_cache_store(name_user, &info3);
- wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
+ netsamlogon_cache_store(name_user, info3);
+ wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3);
/* Check if the user is in the right group */
- if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3,
+ if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3,
state->request.data.auth_crap.require_membership_of_sid))) {
DEBUG(3, ("User %s is not in the required group (%s), so "
"crap authentication is rejected\n",
@@ -1856,7 +1871,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
goto done;
}
- result = append_data(state, &info3, name_domain, name_user);
+ result = append_data(state, info3, name_domain, name_user);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
@@ -1938,8 +1953,8 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
POLICY_HND dom_pol;
struct rpc_pipe_client *cli;
bool got_info = False;
- SAM_UNK_INFO_1 info;
- SAMR_CHANGE_REJECT reject;
+ struct samr_DomInfo1 *info = NULL;
+ struct samr_ChangeReject *reject = NULL;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring domain, user;
@@ -1967,24 +1982,29 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
goto done;
}
- result = rpccli_samr_chgpasswd3(cli, state->mem_ctx, user, newpass, oldpass, &info, &reject);
+ result = rpccli_samr_chgpasswd3(cli, state->mem_ctx,
+ user,
+ newpass,
+ oldpass,
+ &info,
+ &reject);
/* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */
if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) {
- state->response.data.auth.policy.min_length_password =
- info.min_length_password;
- state->response.data.auth.policy.password_history =
- info.password_history;
- state->response.data.auth.policy.password_properties =
- info.password_properties;
- state->response.data.auth.policy.expire =
- nt_time_to_unix_abs(&info.expire);
- state->response.data.auth.policy.min_passwordage =
- nt_time_to_unix_abs(&info.min_passwordage);
-
- state->response.data.auth.reject_reason =
- reject.reject_reason;
+ state->response.data.auth.policy.min_length_password =
+ info->min_password_length;
+ state->response.data.auth.policy.password_history =
+ info->password_history_length;
+ state->response.data.auth.policy.password_properties =
+ info->password_properties;
+ state->response.data.auth.policy.expire =
+ nt_time_to_unix_abs((NTTIME *)&info->max_password_age);
+ state->response.data.auth.policy.min_passwordage =
+ nt_time_to_unix_abs((NTTIME *)&info->min_password_age);
+
+ state->response.data.auth.reject_reason =
+ reject->reason;
got_info = True;
}
diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c
index 29db8be857..7c1d7bd71b 100644
--- a/source3/winbindd/winbindd_passdb.c
+++ b/source3/winbindd/winbindd_passdb.c
@@ -338,7 +338,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_12 *policy)
+ struct samr_DomInfo12 *policy)
{
/* actually we have that */
return NT_STATUS_NOT_IMPLEMENTED;
@@ -346,14 +346,14 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain,
static NTSTATUS password_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_1 *policy)
+ struct samr_DomInfo1 *policy)
{
uint32 min_pass_len,pass_hist,password_properties;
time_t u_expire, u_min_age;
NTTIME nt_expire, nt_min_age;
uint32 account_policy_temp;
- if ((policy = TALLOC_ZERO_P(mem_ctx, SAM_UNK_INFO_1)) == NULL) {
+ if ((policy = TALLOC_ZERO_P(mem_ctx, struct samr_DomInfo1)) == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -385,8 +385,12 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
unix_to_nt_time_abs(&nt_expire, u_expire);
unix_to_nt_time_abs(&nt_min_age, u_min_age);
- init_unk_info1(policy, (uint16)min_pass_len, (uint16)pass_hist,
- password_properties, nt_expire, nt_min_age);
+ init_samr_DomInfo1(policy,
+ (uint16)min_pass_len,
+ (uint16)pass_hist,
+ password_properties,
+ nt_expire,
+ nt_min_age);
return NT_STATUS_OK;
}
diff --git a/source3/winbindd/winbindd_reconnect.c b/source3/winbindd/winbindd_reconnect.c
index a1f96a0359..25debccc5a 100644
--- a/source3/winbindd/winbindd_reconnect.c
+++ b/source3/winbindd/winbindd_reconnect.c
@@ -247,7 +247,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
/* find the lockout policy of a domain */
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_12 *policy)
+ struct samr_DomInfo12 *policy)
{
NTSTATUS result;
@@ -262,7 +262,7 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain,
/* find the password policy of a domain */
static NTSTATUS password_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_1 *policy)
+ struct samr_DomInfo1 *policy)
{
NTSTATUS result;
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index 34ba0498e0..2a7704c8a5 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -6,6 +6,7 @@
Copyright (C) Tim Potter 2000-2001,2003
Copyright (C) Andrew Tridgell 2001
Copyright (C) Volker Lendecke 2005
+ Copyright (C) Guenther Deschner 2008 (pidl conversion)
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
@@ -63,24 +64,26 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
do {
uint32 num_dom_users, j;
uint32 max_entries, max_size;
- SAM_DISPINFO_CTR ctr;
- SAM_DISPINFO_1 info1;
+ uint32_t total_size, returned_size;
- ZERO_STRUCT( ctr );
- ZERO_STRUCT( info1 );
- ctr.sam.info1 = &info1;
+ union samr_DispInfo disp_info;
/* this next bit is copied from net_user_list_internal() */
get_query_dispinfo_params(loop_count, &max_entries,
&max_size);
- result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
- &start_idx, 1,
- &num_dom_users,
- max_entries, max_size,
- &ctr);
-
+ result = rpccli_samr_QueryDisplayInfo(cli, mem_ctx,
+ &dom_pol,
+ 1,
+ start_idx,
+ max_entries,
+ max_size,
+ &total_size,
+ &returned_size,
+ &disp_info);
+ num_dom_users = disp_info.info1.count;
+ start_idx += disp_info.info1.count;
loop_count++;
*num_entries += num_dom_users;
@@ -93,14 +96,13 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
}
for (j = 0; j < num_dom_users; i++, j++) {
- fstring username, fullname;
- uint32 rid = ctr.sam.info1->sam[j].rid_user;
-
- unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username));
- unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname));
-
- (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
- (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
+
+ uint32_t rid = disp_info.info1.entries[j].rid;
+
+ (*info)[i].acct_name = talloc_strdup(mem_ctx,
+ disp_info.info1.entries[j].account_name.string);
+ (*info)[i].full_name = talloc_strdup(mem_ctx,
+ disp_info.info1.entries[j].full_name.string);
(*info)[i].homedir = NULL;
(*info)[i].shell = NULL;
sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
@@ -149,19 +151,22 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
return status;
do {
- struct acct_info *info2 = NULL;
+ struct samr_SamArray *sam_array = NULL;
uint32 count = 0;
TALLOC_CTX *mem_ctx2;
+ int g;
mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
/* start is updated by this call. */
- status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
- &start,
- 0xFFFF, /* buffer size? */
- &info2, &count);
+ status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2,
+ &dom_pol,
+ &start,
+ &sam_array,
+ 0xFFFF, /* buffer size? */
+ &count);
- if (!NT_STATUS_IS_OK(status) &&
+ if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
talloc_destroy(mem_ctx2);
break;
@@ -175,7 +180,13 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
return NT_STATUS_NO_MEMORY;
}
- memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
+ for (g=0; g < count; g++) {
+
+ fstrcpy((*info)[*num_entries + g].acct_name,
+ sam_array->entries[g].name.string);
+ (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
+ }
+
(*num_entries) += count;
talloc_destroy(mem_ctx2);
} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
@@ -210,18 +221,21 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
return result;
do {
- struct acct_info *info2 = NULL;
+ struct samr_SamArray *sam_array = NULL;
uint32 count = 0, start = *num_entries;
TALLOC_CTX *mem_ctx2;
+ int g;
mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
- result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
- &start, 0xFFFF, &info2,
- &count);
-
+ result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2,
+ &dom_pol,
+ &start,
+ &sam_array,
+ 0xFFFF, /* buffer size? */
+ &count);
if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
+ !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
{
talloc_destroy(mem_ctx2);
return result;
@@ -235,7 +249,13 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
return NT_STATUS_NO_MEMORY;
}
- memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
+ for (g=0; g < count; g++) {
+
+ fstrcpy((*info)[*num_entries + g].acct_name,
+ sam_array->entries[g].name.string);
+ (*info)[*num_entries + g].rid = sam_array->entries[g].idx;
+ }
+
(*num_entries) += count;
talloc_destroy(mem_ctx2);
@@ -408,9 +428,9 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol, user_pol;
- SAM_USERINFO_CTR *ctr;
+ union samr_UserInfo *info = NULL;
uint32 user_rid;
- NET_USER_INFO_3 *user;
+ struct netr_SamInfo3 *user;
struct rpc_pipe_client *cli;
DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid)));
@@ -430,14 +450,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
sid_string_dbg(user_sid)));
- sid_compose(&user_info->user_sid, &domain->sid, user->user_rid);
+ sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
sid_compose(&user_info->group_sid, &domain->sid,
- user->group_rid);
+ user->base.primary_gid);
- user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
- &user->uni_user_name);
- user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
- &user->uni_full_name);
+ user_info->acct_name = talloc_strdup(mem_ctx,
+ user->base.account_name.string);
+ user_info->full_name = talloc_strdup(mem_ctx,
+ user->base.full_name.string);
TALLOC_FREE(user);
@@ -469,29 +489,33 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
return result;
/* Get user handle */
- result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
- &user_pol);
+ result = rpccli_samr_OpenUser(cli, mem_ctx,
+ &dom_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ user_rid,
+ &user_pol);
if (!NT_STATUS_IS_OK(result))
return result;
/* Get user info */
- result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
- 0x15, &ctr);
+ result = rpccli_samr_QueryUserInfo(cli, mem_ctx,
+ &user_pol,
+ 0x15,
+ &info);
- rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_Close(cli, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result))
return result;
sid_compose(&user_info->user_sid, &domain->sid, user_rid);
sid_compose(&user_info->group_sid, &domain->sid,
- ctr->info.id21->group_rid);
- user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx,
- &ctr->info.id21->uni_user_name);
- user_info->full_name = unistr2_to_ascii_talloc(mem_ctx,
- &ctr->info.id21->uni_full_name);
+ info->info21.primary_gid);
+ user_info->acct_name = talloc_strdup(mem_ctx,
+ info->info21.account_name.string);
+ user_info->full_name = talloc_strdup(mem_ctx,
+ info->info21.full_name.string);
user_info->homedir = NULL;
user_info->shell = NULL;
user_info->primary_gid = (gid_t)-1;
@@ -508,7 +532,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol, user_pol;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
- DOM_GID *user_groups;
+ struct samr_RidWithAttributeArray *rid_array = NULL;
unsigned int i;
uint32 user_rid;
struct rpc_pipe_client *cli;
@@ -545,17 +569,22 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return result;
/* Get user handle */
- result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
- des_access, user_rid, &user_pol);
+ result = rpccli_samr_OpenUser(cli, mem_ctx,
+ &dom_pol,
+ des_access,
+ user_rid,
+ &user_pol);
if (!NT_STATUS_IS_OK(result))
return result;
/* Query user rids */
- result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
- num_groups, &user_groups);
+ result = rpccli_samr_GetGroupsForUser(cli, mem_ctx,
+ &user_pol,
+ &rid_array);
+ *num_groups = rid_array->count;
- rpccli_samr_close(cli, mem_ctx, &user_pol);
+ rpccli_samr_Close(cli, mem_ctx, &user_pol);
if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
return result;
@@ -567,9 +596,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
for (i=0;i<(*num_groups);i++) {
sid_copy(&((*user_grpsids)[i]), &domain->sid);
sid_append_rid(&((*user_grpsids)[i]),
- user_groups[i].g_rid);
+ rid_array->rids[i].rid);
}
-
+
return NT_STATUS_OK;
}
@@ -580,11 +609,10 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol;
- DOM_SID2 *query_sids;
uint32 num_query_sids = 0;
int i;
struct rpc_pipe_client *cli;
- uint32 *alias_rids_query, num_aliases_query;
+ struct samr_Ids alias_rids_query;
int rangesize = MAX_SAM_ENTRIES_W2K;
uint32 total_sids = 0;
int num_queries = 1;
@@ -606,6 +634,9 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
do {
/* prepare query */
+ struct lsa_SidArray sid_array;
+
+ ZERO_STRUCT(sid_array);
num_query_sids = MIN(num_sids - total_sids, rangesize);
@@ -613,45 +644,48 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
num_queries, num_query_sids));
if (num_query_sids) {
- query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
- if (query_sids == NULL) {
+ sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
+ if (sid_array.sids == NULL) {
return NT_STATUS_NO_MEMORY;
}
} else {
- query_sids = NULL;
+ sid_array.sids = NULL;
}
for (i=0; i<num_query_sids; i++) {
- sid_copy(&query_sids[i].sid, &sids[total_sids++]);
- query_sids[i].num_auths = query_sids[i].sid.num_auths;
+ sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]);
+ if (!sid_array.sids[i].sid) {
+ TALLOC_FREE(sid_array.sids);
+ return NT_STATUS_NO_MEMORY;
+ }
}
+ sid_array.num_sids = num_query_sids;
/* do request */
-
- result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
- num_query_sids, query_sids,
- &num_aliases_query,
- &alias_rids_query);
+ result = rpccli_samr_GetAliasMembership(cli, mem_ctx,
+ &dom_pol,
+ &sid_array,
+ &alias_rids_query);
if (!NT_STATUS_IS_OK(result)) {
*num_aliases = 0;
*alias_rids = NULL;
- TALLOC_FREE(query_sids);
+ TALLOC_FREE(sid_array.sids);
goto done;
}
/* process output */
- for (i=0; i<num_aliases_query; i++) {
+ for (i=0; i<alias_rids_query.count; i++) {
size_t na = *num_aliases;
- if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
+ if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],
alias_rids, &na)) {
return NT_STATUS_NO_MEMORY;
}
*num_aliases = na;
}
- TALLOC_FREE(query_sids);
+ TALLOC_FREE(sid_array.sids);
num_queries++;
@@ -678,9 +712,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
uint32 *rid_mem = NULL;
uint32 group_rid;
- unsigned int j;
+ unsigned int j, r;
struct rpc_pipe_client *cli;
unsigned int orig_timeout;
+ struct samr_RidTypeArray *rids = NULL;
DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
sid_string_dbg(group_sid)));
@@ -700,8 +735,11 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
if (!NT_STATUS_IS_OK(result))
return result;
- result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
- des_access, group_rid, &group_pol);
+ result = rpccli_samr_OpenGroup(cli, mem_ctx,
+ &dom_pol,
+ des_access,
+ group_rid,
+ &group_pol);
if (!NT_STATUS_IS_OK(result))
return result;
@@ -714,18 +752,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
orig_timeout = cli_set_timeout(cli->cli, 35000);
- result = rpccli_samr_query_groupmem(cli, mem_ctx,
- &group_pol, num_names, &rid_mem,
- name_types);
+ result = rpccli_samr_QueryGroupMember(cli, mem_ctx,
+ &group_pol,
+ &rids);
/* And restore our original timeout. */
cli_set_timeout(cli->cli, orig_timeout);
- rpccli_samr_close(cli, mem_ctx, &group_pol);
+ rpccli_samr_Close(cli, mem_ctx, &group_pol);
if (!NT_STATUS_IS_OK(result))
return result;
+ *num_names = rids->count;
+ rid_mem = rids->rids;
+
if (!*num_names) {
names = NULL;
name_types = NULL;
@@ -750,38 +791,40 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
if (*num_names>0 && (!*names || !*name_types))
return NT_STATUS_NO_MEMORY;
- for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
- int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
- uint32 tmp_num_names = 0;
- char **tmp_names = NULL;
- uint32 *tmp_types = NULL;
+ for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
+ int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
+ struct lsa_Strings tmp_names;
+ struct samr_Ids tmp_types;
- /* Lookup a chunk of rids */
+ /* Lookup a chunk of rids */
- result = rpccli_samr_lookup_rids(cli, mem_ctx,
- &dom_pol,
- num_lookup_rids,
- &rid_mem[i],
- &tmp_num_names,
- &tmp_names, &tmp_types);
+ result = rpccli_samr_LookupRids(cli, mem_ctx,
+ &dom_pol,
+ num_lookup_rids,
+ &rid_mem[i],
+ &tmp_names,
+ &tmp_types);
/* see if we have a real error (and yes the
STATUS_SOME_UNMAPPED is the one returned from 2k) */
-
+
if (!NT_STATUS_IS_OK(result) &&
!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
return result;
-
- /* Copy result into array. The talloc system will take
- care of freeing the temporary arrays later on. */
- memcpy(&(*names)[i], tmp_names, sizeof(char *) *
- tmp_num_names);
+ /* Copy result into array. The talloc system will take
+ care of freeing the temporary arrays later on. */
- memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
- tmp_num_names);
-
- total_names += tmp_num_names;
+ if (tmp_names.count != tmp_types.count) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ for (r=0; r<tmp_names.count; r++) {
+ (*names)[i+r] = CONST_DISCARD(char *, tmp_names.names[r].string);
+ (*name_types)[i+r] = tmp_types.ids[r];
+ }
+
+ total_names += tmp_names.count;
}
*num_names = total_names;
@@ -867,7 +910,7 @@ static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
{
TALLOC_CTX *mem_ctx;
- SAM_UNK_CTR ctr;
+ union samr_DomainInfo *info = NULL;
NTSTATUS result;
POLICY_HND dom_pol;
bool got_seq_num = False;
@@ -918,21 +961,27 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
/* Query domain info */
- result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
+ result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+ &dom_pol,
+ 8,
+ &info);
if (NT_STATUS_IS_OK(result)) {
- *seq = ctr.info.inf8.seq_num;
+ *seq = info->info8.sequence_num;
got_seq_num = True;
goto seq_num;
}
/* retry with info-level 2 in case the dc does not support info-level 8
- * (like all older samba2 and samba3 dc's - Guenther */
+ * (like all older samba2 and samba3 dc's) - Guenther */
+
+ result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+ &dom_pol,
+ 2,
+ &info);
- result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
-
if (NT_STATUS_IS_OK(result)) {
- *seq = ctr.info.inf2.seq_num;
+ *seq = info->info2.sequence_num;
got_seq_num = True;
}
@@ -980,22 +1029,22 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
result = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
- uint32 start_idx, num;
- char **tmp_names;
- DOM_SID *tmp_sids;
+ uint32 start_idx;
int i;
+ struct lsa_DomainList dom_list;
- result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
- &lsa_policy, &enum_ctx,
- &num, &tmp_names,
- &tmp_sids);
+ result = rpccli_lsa_EnumTrustDom(cli, mem_ctx,
+ &lsa_policy,
+ &enum_ctx,
+ &dom_list,
+ (uint32_t)-1);
if (!NT_STATUS_IS_OK(result) &&
!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
break;
start_idx = *num_domains;
- *num_domains += num;
+ *num_domains += dom_list.count;
*names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
char *, *num_domains);
*dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
@@ -1006,9 +1055,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
(*alt_names == NULL))
return NT_STATUS_NO_MEMORY;
- for (i=0; i<num; i++) {
- (*names)[start_idx+i] = tmp_names[i];
- (*dom_sids)[start_idx+i] = tmp_sids[i];
+ for (i=0; i<dom_list.count; i++) {
+ (*names)[start_idx+i] = CONST_DISCARD(char *, dom_list.domains[i].name.string);
+ (*dom_sids)[start_idx+i] = *dom_list.domains[i].sid;
(*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
}
}
@@ -1016,14 +1065,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
}
/* find the lockout policy for a domain */
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
+NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_12 *lockout_policy)
+ struct samr_DomInfo12 *lockout_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
POLICY_HND dom_pol;
- SAM_UNK_CTR ctr;
+ union samr_DomainInfo *info = NULL;
DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
@@ -1038,15 +1087,18 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
goto done;
}
- result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
+ result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+ &dom_pol,
+ 12,
+ &info);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- *lockout_policy = ctr.info.inf12;
+ *lockout_policy = info->info12;
- DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
- ctr.info.inf12.bad_attempt_lockout));
+ DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n",
+ info->info12.lockout_threshold));
done:
@@ -1054,14 +1106,14 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
}
/* find the password policy for a domain */
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
+NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- SAM_UNK_INFO_1 *password_policy)
+ struct samr_DomInfo1 *password_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
POLICY_HND dom_pol;
- SAM_UNK_CTR ctr;
+ union samr_DomainInfo *info = NULL;
DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
@@ -1076,15 +1128,18 @@ NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
goto done;
}
- result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
+ result = rpccli_samr_QueryDomainInfo(cli, mem_ctx,
+ &dom_pol,
+ 1,
+ &info);
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
- *password_policy = ctr.info.inf1;
+ *password_policy = info->info1;
- DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
- ctr.info.inf1.min_length_password));
+ DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
+ info->info1.min_password_length));
done:
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index dc48fdef8b..038bafbe4e 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -41,7 +41,7 @@ extern struct winbindd_methods passdb_methods;
individual winbindd_domain structures cannot be made. Keep a copy of
the domain name instead. */
-static struct winbindd_domain *_domain_list;
+static struct winbindd_domain *_domain_list = NULL;
/**
When was the last scan of trusted domains done?
@@ -82,9 +82,6 @@ static bool is_internal_domain(const DOM_SID *sid)
if (sid == NULL)
return False;
- if ( IS_DC )
- return sid_check_is_builtin(sid);
-
return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
}
@@ -93,9 +90,6 @@ static bool is_in_internal_domain(const DOM_SID *sid)
if (sid == NULL)
return False;
- if ( IS_DC )
- return sid_check_is_in_builtin(sid);
-
return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid));
}
@@ -218,7 +212,7 @@ static void add_trusted_domains( struct winbindd_domain *domain )
TALLOC_CTX *mem_ctx;
struct winbindd_request *request;
struct winbindd_response *response;
- uint32 fr_flags = (DS_DOMAIN_TREE_ROOT|DS_DOMAIN_IN_FOREST);
+ uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST);
struct trustdom_state *state;
@@ -391,8 +385,8 @@ static void rescan_forest_root_trusts( void )
the domain_list() as our primary domain may not
have been initialized. */
- if ( !(dom_list[i].trust_flags & DS_DOMAIN_TREE_ROOT) ) {
- continue;
+ if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) {
+ continue;
}
/* Here's the forest root */
@@ -456,10 +450,10 @@ static void rescan_forest_trusts( void )
if ( d && (d->internal || d->primary ) )
continue;
-
- if ( (flags & DS_DOMAIN_DIRECT_INBOUND) &&
- (type == DS_DOMAIN_TRUST_TYPE_UPLEVEL) &&
- (attribs == DS_DOMAIN_TRUST_ATTRIB_FOREST_TRANSITIVE) )
+
+ if ( (flags & NETR_TRUST_FLAG_INBOUND) &&
+ (type == NETR_TRUST_TYPE_UPLEVEL) &&
+ (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )
{
/* add the trusted domain if we don't know
about it */
@@ -571,7 +565,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain,
/* The primary domain has to find the DC name itself */
request->cmd = WINBINDD_INIT_CONNECTION;
fstrcpy(request->domain_name, domain->name);
- request->data.init_conn.is_primary = domain->internal ? False : True;
+ request->data.init_conn.is_primary = domain->primary ? true : false;
fstrcpy(request->data.init_conn.dcname, "");
async_request(mem_ctx, &domain->child, request, response,
init_child_recv, state);
@@ -770,8 +764,8 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid )
forest trust */
domain->active_directory = True;
- domain->domain_flags = DS_DOMAIN_DIRECT_OUTBOUND;
- domain->domain_type = DS_DOMAIN_TRUST_TYPE_UPLEVEL;
+ domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;
+ domain->domain_type = NETR_TRUST_TYPE_UPLEVEL;
domain->internal = False;
domain->online = True;
@@ -1278,7 +1272,7 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
const DOM_SID *user_sid,
uint32 *p_num_groups, DOM_SID **user_sids)
{
- NET_USER_INFO_3 *info3 = NULL;
+ struct netr_SamInfo3 *info3 = NULL;
NTSTATUS status = NT_STATUS_NO_MEMORY;
int i;
size_t num_groups = 0;
@@ -1296,13 +1290,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- if (info3->num_groups == 0) {
+ if (info3->base.groups.count == 0) {
TALLOC_FREE(info3);
return NT_STATUS_UNSUCCESSFUL;
}
/* always add the primary group to the sid array */
- sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid);
+ sid_compose(&primary_group, info3->base.domain_sid, info3->base.rid);
status = add_sid_to_array(mem_ctx, &primary_group, user_sids,
&num_groups);
@@ -1311,9 +1305,9 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
return status;
}
- for (i=0; i<info3->num_groups; i++) {
- sid_copy(&group_sid, &info3->dom_sid.sid);
- sid_append_rid(&group_sid, info3->gids[i].g_rid);
+ for (i=0; i < info3->base.groups.count; i++) {
+ sid_copy(&group_sid, info3->base.domain_sid);
+ sid_append_rid(&group_sid, info3->base.groups.rids[i].rid);
status = add_sid_to_array(mem_ctx, &group_sid, user_sids,
&num_groups);
@@ -1325,13 +1319,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
/* Add any Universal groups in the other_sids list */
- for (i=0; i<info3->num_other_sids; i++) {
+ for (i=0; i < info3->sidcount; i++) {
/* Skip Domain local groups outside our domain.
We'll get these from the getsidaliases() RPC call. */
- if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE)
+ if (info3->sids[i].attributes & SE_GROUP_RESOURCE)
continue;
- status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid,
+ status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
user_sids, &num_groups);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(info3);
@@ -1386,31 +1380,56 @@ void ws_name_return( char *name, char replace )
/*********************************************************************
********************************************************************/
-bool winbindd_can_contact_domain( struct winbindd_domain *domain )
+bool winbindd_can_contact_domain(struct winbindd_domain *domain)
{
+ struct winbindd_tdc_domain *tdc = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ bool ret = false;
+
/* We can contact the domain if it is our primary domain */
- if ( domain->primary )
- return True;
+ if (domain->primary) {
+ return true;
+ }
- /* Can always contact a domain that is in out forest */
+ /* Trust the TDC cache and not the winbindd_domain flags */
- if ( domain->domain_flags & DS_DOMAIN_IN_FOREST )
- return True;
+ if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) {
+ DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n",
+ domain->name));
+ return false;
+ }
- /* We cannot contact the domain if it is running AD and
- we have no inbound trust */
+ /* Can always contact a domain that is in out forest */
- if ( domain->active_directory &&
- ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) )
- {
- return False;
+ if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
+ ret = true;
+ goto done;
}
+ /*
+ * On a _member_ server, we cannot contact the domain if it
+ * is running AD and we have no inbound trust.
+ */
+
+ if (!IS_DC &&
+ domain->active_directory &&
+ ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND))
+ {
+ DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain "
+ "and we have no inbound trust.\n", domain->name));
+ goto done;
+ }
+
/* Assume everything else is ok (probably not true but what
can you do?) */
+
+ ret = true;
+
+done:
+ talloc_destroy(frame);
- return True;
+ return ret;
}
/*********************************************************************