summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-12-03 17:47:39 +1100
committerAndrew Tridgell <tridge@samba.org>2008-12-03 17:47:39 +1100
commita226d86dcec393b2cd657d5441c3041dfdf5cd8f (patch)
tree03ef7f3207607a4e5351bf50892b0a39dcf6f219 /source3/winbindd
parent30eff4f31b497ac94d8ee02ee2ec24bc8865ce0d (diff)
parent85b8cccab072bab263061654b677bc84826646c9 (diff)
downloadsamba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.gz
samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.bz2
samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/idmap.c27
-rw-r--r--source3/winbindd/idmap_ad.c414
-rw-r--r--source3/winbindd/idmap_adex/idmap_adex.c16
-rw-r--r--source3/winbindd/idmap_hash/idmap_hash.c6
-rw-r--r--source3/winbindd/idmap_tdb.c63
-rw-r--r--source3/winbindd/idmap_util.c12
-rw-r--r--source3/winbindd/nss_info.c151
-rw-r--r--source3/winbindd/nss_info_template.c4
-rw-r--r--source3/winbindd/winbindd.c3
-rw-r--r--source3/winbindd/winbindd_ads.c229
-rw-r--r--source3/winbindd/winbindd_cache.c7
-rw-r--r--source3/winbindd/winbindd_dual.c1
-rw-r--r--source3/winbindd/winbindd_group.c4
-rw-r--r--source3/winbindd/winbindd_idmap.c63
-rw-r--r--source3/winbindd/winbindd_pam.c31
-rw-r--r--source3/winbindd/winbindd_passdb.c5
-rw-r--r--source3/winbindd/winbindd_proto.h40
-rw-r--r--source3/winbindd/winbindd_rpc.c65
-rw-r--r--source3/winbindd/winbindd_sid.c45
19 files changed, 808 insertions, 378 deletions
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
index cfc5597f42..aaba7e53ee 100644
--- a/source3/winbindd/idmap.c
+++ b/source3/winbindd/idmap.c
@@ -461,6 +461,9 @@ static struct idmap_domain *idmap_find_domain(const char *domname)
struct idmap_domain *result;
int i;
+ DEBUG(10, ("idmap_find_domain called for domain '%s'\n",
+ domname?domname:"NULL"));
+
/*
* Always init the default domain, we can't go without one
*/
@@ -725,6 +728,10 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
struct idmap_domain *dom;
struct id_map *maps[2];
+ DEBUG(10, ("idmap_backend_unixid_to_sid: domain = '%s', xid = %d "
+ "(type %d)\n",
+ domname?domname:"NULL", id->xid.id, id->xid.type));
+
maps[0] = id;
maps[1] = NULL;
@@ -751,6 +758,9 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
struct idmap_domain *dom;
struct id_map *maps[2];
+ DEBUG(10, ("idmap_backend_sid_to_unixid: domain = '%s', sid = [%s]\n",
+ domain?domain:"NULL", sid_string_dbg(id->sid)));
+
maps[0] = id;
maps[1] = NULL;
@@ -788,3 +798,20 @@ NTSTATUS idmap_set_mapping(const struct id_map *map)
return dom->methods->set_mapping(dom, map);
}
+
+NTSTATUS idmap_remove_mapping(const struct id_map *map)
+{
+ struct idmap_domain *dom;
+
+ dom = idmap_find_domain(NULL);
+ if (dom == NULL) {
+ DEBUG(3, ("no default domain, no place to write\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (dom->methods->remove_mapping == NULL) {
+ DEBUG(3, ("default domain not writable\n"));
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+
+ return dom->methods->remove_mapping(dom, map);
+}
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c
index 60a2d8642a..b22e5af94a 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -9,6 +9,7 @@
* Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
* Copyright (C) Gerald (Jerry) Carter 2004-2007
* Copyright (C) Luke Howard 2001-2004
+ * Copyright (C) Michael Adam 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
@@ -25,6 +26,7 @@
*/
#include "includes.h"
+#include "winbindd.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
@@ -43,31 +45,39 @@
struct idmap_ad_context {
uint32_t filter_low_id;
uint32_t filter_high_id;
+ ADS_STRUCT *ads;
+ struct posix_schema *ad_schema;
+ enum wb_posix_mapping ad_map_type; /* WB_POSIX_MAP_UNKNOWN */
};
NTSTATUS init_module(void);
-static ADS_STRUCT *ad_idmap_ads = NULL;
-static struct posix_schema *ad_schema = NULL;
-static enum wb_posix_mapping ad_map_type = WB_POSIX_MAP_UNKNOWN;
-
/************************************************************************
***********************************************************************/
-static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
+static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom)
{
ADS_STRUCT *ads;
ADS_STATUS status;
bool local = False;
fstring dc_name;
struct sockaddr_storage dc_ip;
+ struct idmap_ad_context *ctx;
+ char *ldap_server = NULL;
+ char *realm = NULL;
+ struct winbindd_domain *wb_dom;
+
+ DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n",
+ dom->name));
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- if (ad_idmap_ads != NULL) {
+ if (ctx->ads != NULL) {
time_t expire;
time_t now = time(NULL);
- ads = ad_idmap_ads;
+ ads = ctx->ads;
expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
@@ -76,15 +86,15 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
(uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
if ( ads->config.realm && (expire > time(NULL))) {
- return ads;
+ return ADS_SUCCESS;
} else {
/* we own this ADS_STRUCT so make sure it goes away */
DEBUG(7,("Deleting expired krb5 credential cache\n"));
ads->is_mine = True;
ads_destroy( &ads );
ads_kdestroy(WINBIND_CCACHE_NAME);
- ad_idmap_ads = NULL;
- TALLOC_FREE( ad_schema );
+ ctx->ads = NULL;
+ TALLOC_FREE( ctx->ad_schema );
}
}
@@ -93,9 +103,28 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
}
- if ( (ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL ) {
+ /*
+ * At this point we only have the NetBIOS domain name.
+ * Check if we can get server nam and realm from SAF cache
+ * and the domain list.
+ */
+ ldap_server = saf_fetch(dom->name);
+ DEBUG(10, ("ldap_server from saf cache: '%s'\n", ldap_server?ldap_server:""));
+
+ wb_dom = find_domain_from_name_noinit(dom->name);
+ if (wb_dom == NULL) {
+ DEBUG(10, ("find_domain_from_name_noinit did not find domain '%s'\n",
+ dom->name));
+ realm = NULL;
+ } else {
+ DEBUG(10, ("find_domain_from_name_noinit found realm '%s' for "
+ " domain '%s'\n", wb_dom->alt_name, dom->name));
+ realm = wb_dom->alt_name;
+ }
+
+ if ( (ads = ads_init(realm, dom->name, ldap_server)) == NULL ) {
DEBUG(1,("ads_init failed\n"));
- return NULL;
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
/* the machine acct password might have change - fetch it every time */
@@ -107,54 +136,57 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
/* setup server affinity */
- get_dc_name( NULL, ads->auth.realm, dc_name, &dc_ip );
+ get_dc_name(dom->name, realm, dc_name, &dc_ip );
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
ads_destroy(&ads);
- return NULL;
+ return status;
}
ads->is_mine = False;
- ad_idmap_ads = ads;
+ ctx->ads = ads;
- return ads;
+ return ADS_SUCCESS;
}
/************************************************************************
***********************************************************************/
-static ADS_STRUCT *ad_idmap_cached_connection(void)
+static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom)
{
- ADS_STRUCT *ads = ad_idmap_cached_connection_internal();
-
- if ( !ads )
- return NULL;
+ ADS_STATUS status;
+ struct idmap_ad_context * ctx;
+
+ status = ad_idmap_cached_connection_internal(dom);
+ if (!ADS_ERR_OK(status)) {
+ return status;
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
/* if we have a valid ADS_STRUCT and the schema model is
defined, then we can return here. */
- if ( ad_schema )
- return ads;
+ if ( ctx->ad_schema ) {
+ return ADS_SUCCESS;
+ }
/* Otherwise, set the schema model */
- if ( (ad_map_type == WB_POSIX_MAP_SFU) ||
- (ad_map_type == WB_POSIX_MAP_SFU20) ||
- (ad_map_type == WB_POSIX_MAP_RFC2307) )
+ if ( (ctx->ad_map_type == WB_POSIX_MAP_SFU) ||
+ (ctx->ad_map_type == WB_POSIX_MAP_SFU20) ||
+ (ctx->ad_map_type == WB_POSIX_MAP_RFC2307) )
{
- ADS_STATUS schema_status;
-
- schema_status = ads_check_posix_schema_mapping( NULL, ads, ad_map_type, &ad_schema);
- if ( !ADS_ERR_OK(schema_status) ) {
+ status = ads_check_posix_schema_mapping(NULL, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
+ if ( !ADS_ERR_OK(status) ) {
DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
- return NULL;
}
}
- return ads;
+ return status;
}
/************************************************************************
@@ -190,17 +222,18 @@ static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
}
}
+ /* default map type */
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
+
/* schema mode */
- if ( ad_map_type == WB_POSIX_MAP_UNKNOWN )
- ad_map_type = WB_POSIX_MAP_RFC2307;
schema_mode = lp_parm_const_string(-1, config_option, "schema_mode", NULL);
if ( schema_mode && schema_mode[0] ) {
if ( strequal(schema_mode, "sfu") )
- ad_map_type = WB_POSIX_MAP_SFU;
+ ctx->ad_map_type = WB_POSIX_MAP_SFU;
else if ( strequal(schema_mode, "sfu20" ) )
- ad_map_type = WB_POSIX_MAP_SFU20;
+ ctx->ad_map_type = WB_POSIX_MAP_SFU20;
else if ( strequal(schema_mode, "rfc2307" ) )
- ad_map_type = WB_POSIX_MAP_RFC2307;
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
else
DEBUG(0,("idmap_ad_initialize: Unknown schema_mode (%s)\n",
schema_mode));
@@ -256,7 +289,6 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- ADS_STRUCT *ads;
const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* uidnumber */
@@ -284,14 +316,16 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
return NT_STATUS_NO_MEMORY;
}
- if ( (ads = ad_idmap_cached_connection()) == NULL ) {
- DEBUG(1, ("ADS uninitialized\n"));
+ rc = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(1, ("ADS uninitialized: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
+ /* ret = ads_ntstatus(rc); */
goto done;
}
- attrs[2] = ad_schema->posix_uidnumber_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ attrs[2] = ctx->ad_schema->posix_uidnumber_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
again:
bidx = idx;
@@ -308,7 +342,7 @@ again:
ATYPE_INTERDOMAIN_TRUST);
}
u_filter = talloc_asprintf_append_buffer(u_filter, "(%s=%lu)",
- ad_schema->posix_uidnumber_attr,
+ ctx->ad_schema->posix_uidnumber_attr,
(unsigned long)ids[idx]->xid.id);
CHECK_ALLOC_DONE(u_filter);
break;
@@ -322,7 +356,7 @@ again:
ATYPE_SECURITY_LOCAL_GROUP);
}
g_filter = talloc_asprintf_append_buffer(g_filter, "(%s=%lu)",
- ad_schema->posix_gidnumber_attr,
+ ctx->ad_schema->posix_gidnumber_attr,
(unsigned long)ids[idx]->xid.id);
CHECK_ALLOC_DONE(g_filter);
break;
@@ -348,14 +382,14 @@ again:
filter = talloc_asprintf_append_buffer(filter, ")");
CHECK_ALLOC_DONE(filter);
- rc = ads_search_retry(ads, &res, filter, attrs);
+ rc = ads_search_retry(ctx->ads, &res, filter, attrs);
if (!ADS_ERR_OK(rc)) {
DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if ( (count = ads_count_replies(ads, res)) == 0 ) {
+ if ( (count = ads_count_replies(ctx->ads, res)) == 0 ) {
DEBUG(10, ("No IDs found\n"));
}
@@ -368,9 +402,9 @@ again:
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, entry);
+ entry = ads_first_entry(ctx->ads, entry);
} else { /* following ones */
- entry = ads_next_entry(ads, entry);
+ entry = ads_next_entry(ctx->ads, entry);
}
if ( !entry ) {
@@ -379,13 +413,13 @@ again:
}
/* first check if the SID is present */
- if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
+ if (!ads_pull_sid(ctx->ads, entry, "objectSid", &sid)) {
DEBUG(2, ("Could not retrieve SID from entry\n"));
continue;
}
/* get type */
- if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
+ if (!ads_pull_uint32(ctx->ads, entry, "sAMAccountType", &atype)) {
DEBUG(1, ("could not get SAM account type\n"));
continue;
}
@@ -405,9 +439,9 @@ again:
continue;
}
- if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ?
- ad_schema->posix_uidnumber_attr :
- ad_schema->posix_gidnumber_attr,
+ if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
+ ctx->ad_schema->posix_uidnumber_attr :
+ ctx->ad_schema->posix_gidnumber_attr,
&id))
{
DEBUG(1, ("Could not get unix ID\n"));
@@ -439,7 +473,7 @@ again:
}
if (res) {
- ads_msgfree(ads, res);
+ ads_msgfree(ctx->ads, res);
}
if (ids[idx]) { /* still some values to map */
@@ -468,7 +502,6 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- ADS_STRUCT *ads;
const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* attr_uidnumber */
@@ -495,14 +528,22 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
return NT_STATUS_NO_MEMORY;
}
- if ( (ads = ad_idmap_cached_connection()) == NULL ) {
- DEBUG(1, ("ADS uninitialized\n"));
+ rc = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(1, ("ADS uninitialized: %s\n", ads_errstr(rc)));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ /* ret = ads_ntstatus(rc); */
+ goto done;
+ }
+
+ if (ctx->ad_schema == NULL) {
+ DEBUG(0, ("haven't got ctx->ad_schema ! \n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- attrs[2] = ad_schema->posix_uidnumber_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ attrs[2] = ctx->ad_schema->posix_uidnumber_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
again:
filter = talloc_asprintf(memctx, "(&(|"
@@ -529,14 +570,14 @@ again:
CHECK_ALLOC_DONE(filter);
DEBUG(10, ("Filter: [%s]\n", filter));
- rc = ads_search_retry(ads, &res, filter, attrs);
+ rc = ads_search_retry(ctx->ads, &res, filter, attrs);
if (!ADS_ERR_OK(rc)) {
DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if ( (count = ads_count_replies(ads, res)) == 0 ) {
+ if ( (count = ads_count_replies(ctx->ads, res)) == 0 ) {
DEBUG(10, ("No IDs found\n"));
}
@@ -549,9 +590,9 @@ again:
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, entry);
+ entry = ads_first_entry(ctx->ads, entry);
} else { /* following ones */
- entry = ads_next_entry(ads, entry);
+ entry = ads_next_entry(ctx->ads, entry);
}
if ( !entry ) {
@@ -560,7 +601,7 @@ again:
}
/* first check if the SID is present */
- if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
+ if (!ads_pull_sid(ctx->ads, entry, "objectSid", &sid)) {
DEBUG(2, ("Could not retrieve SID from entry\n"));
continue;
}
@@ -572,7 +613,7 @@ again:
}
/* get type */
- if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
+ if (!ads_pull_uint32(ctx->ads, entry, "sAMAccountType", &atype)) {
DEBUG(1, ("could not get SAM account type\n"));
continue;
}
@@ -592,9 +633,9 @@ again:
continue;
}
- if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ?
- ad_schema->posix_uidnumber_attr :
- ad_schema->posix_gidnumber_attr,
+ if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
+ ctx->ad_schema->posix_uidnumber_attr :
+ ctx->ad_schema->posix_gidnumber_attr,
&id))
{
DEBUG(1, ("Could not get unix ID\n"));
@@ -619,7 +660,7 @@ again:
}
if (res) {
- ads_msgfree(ads, res);
+ ads_msgfree(ctx->ads, res);
}
if (ids[idx]) { /* still some values to map */
@@ -644,16 +685,18 @@ done:
static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
{
- ADS_STRUCT *ads = ad_idmap_ads;
+ struct idmap_ad_context * ctx;
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- if (ads != NULL) {
+ if (ctx->ads != NULL) {
/* we own this ADS_STRUCT so make sure it goes away */
- ads->is_mine = True;
- ads_destroy( &ads );
- ad_idmap_ads = NULL;
+ ctx->ads->is_mine = True;
+ ads_destroy( &ctx->ads );
+ ctx->ads = NULL;
}
- TALLOC_FREE( ad_schema );
+ TALLOC_FREE( ctx->ad_schema );
return NT_STATUS_OK;
}
@@ -666,66 +709,107 @@ static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
Initialize the {sfu,sfu20,rfc2307} state
***********************************************************************/
-static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
-{
- /* Sanity check if we have previously been called with a
- different schema model */
+static const char *wb_posix_map_unknown_string = "WB_POSIX_MAP_UNKNOWN";
+static const char *wb_posix_map_template_string = "WB_POSIX_MAP_TEMPLATE";
+static const char *wb_posix_map_sfu_string = "WB_POSIX_MAP_SFU";
+static const char *wb_posix_map_sfu20_string = "WB_POSIX_MAP_SFU20";
+static const char *wb_posix_map_rfc2307_string = "WB_POSIX_MAP_RFC2307";
+static const char *wb_posix_map_unixinfo_string = "WB_POSIX_MAP_UNIXINFO";
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_SFU) )
- {
- DEBUG(0,("nss_sfu_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
+static const char *ad_map_type_string(enum wb_posix_mapping map_type)
+{
+ switch (map_type) {
+ case WB_POSIX_MAP_TEMPLATE:
+ return wb_posix_map_template_string;
+ case WB_POSIX_MAP_SFU:
+ return wb_posix_map_sfu_string;
+ case WB_POSIX_MAP_SFU20:
+ return wb_posix_map_sfu20_string;
+ case WB_POSIX_MAP_RFC2307:
+ return wb_posix_map_rfc2307_string;
+ case WB_POSIX_MAP_UNIXINFO:
+ return wb_posix_map_unixinfo_string;
+ default:
+ return wb_posix_map_unknown_string;
}
-
- ad_map_type = WB_POSIX_MAP_SFU;
-
- return NT_STATUS_OK;
}
-static NTSTATUS nss_sfu20_init( struct nss_domain_entry *e )
+static NTSTATUS nss_ad_generic_init(struct nss_domain_entry *e,
+ enum wb_posix_mapping new_ad_map_type)
{
- /* Sanity check if we have previously been called with a
- different schema model */
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx;
+
+ if (e->state != NULL) {
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ } else {
+ dom = TALLOC_ZERO_P(e, struct idmap_domain);
+ if (dom == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ e->state = dom;
+ }
+
+ if (e->domain != NULL) {
+ dom->name = talloc_strdup(dom, e->domain);
+ if (dom->name == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_SFU20) )
+ if (dom->private_data != NULL) {
+ ctx = talloc_get_type(dom->private_data,
+ struct idmap_ad_context);
+ } else {
+ ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
+ if (ctx == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
+ dom->private_data = ctx;
+ }
+
+ if ((ctx->ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
+ (ctx->ad_map_type != new_ad_map_type))
{
- DEBUG(0,("nss_sfu20_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
+ DEBUG(2, ("nss_ad_generic_init: "
+ "Warning: overriding previously set posix map type "
+ "%s for domain %s with map type %s.\n",
+ ad_map_type_string(ctx->ad_map_type),
+ dom->name,
+ ad_map_type_string(new_ad_map_type)));
}
-
- ad_map_type = WB_POSIX_MAP_SFU20;
+
+ ctx->ad_map_type = new_ad_map_type;
return NT_STATUS_OK;
}
-static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
+static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
{
- /* Sanity check if we have previously been called with a
- different schema model */
-
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_RFC2307) )
- {
- DEBUG(0,("nss_rfc2307_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
- }
-
- ad_map_type = WB_POSIX_MAP_RFC2307;
+ return nss_ad_generic_init(e, WB_POSIX_MAP_SFU);
+}
- return NT_STATUS_OK;
+static NTSTATUS nss_sfu20_init( struct nss_domain_entry *e )
+{
+ return nss_ad_generic_init(e, WB_POSIX_MAP_SFU20);
+}
+
+static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
+{
+ return nss_ad_generic_init(e, WB_POSIX_MAP_RFC2307);
}
/************************************************************************
***********************************************************************/
+
static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
const DOM_SID *sid,
- TALLOC_CTX *ctx,
+ TALLOC_CTX *mem_ctx,
ADS_STRUCT *ads,
LDAPMessage *msg,
char **homedir,
@@ -733,7 +817,6 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
char **gecos,
uint32 *gid )
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {NULL, /* attr_homedir */
NULL, /* attr_shell */
NULL, /* attr_gecos */
@@ -744,18 +827,27 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
char *sidstr = NULL;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx;
+
+ DEBUG(10, ("nss_ad_get_info called for sid [%s] in domain '%s'\n",
+ sid_string_dbg(sid), e->domain?e->domain:"NULL"));
/* Only do query if we are online */
if (idmap_is_offline()) {
return NT_STATUS_FILE_IS_OFFLINE;
}
- /* We are assuming that the internal ADS_STRUCT is for the
- same forest as the incoming *ads pointer */
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- ads_internal = ad_idmap_cached_connection();
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if ( !ads_internal || !ad_schema ) {
+ if (!ctx->ad_schema) {
+ DEBUG(10, ("nss_ad_get_info: no ad_schema configured!\n"));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -766,12 +858,15 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
/* See if we can use the ADS connection struct swe were given */
if (ads) {
- *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr );
- *shell = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr );
- *gecos = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr );
+ DEBUG(10, ("nss_ad_get_info: using given ads connection and "
+ "LDAP message (%p)\n", msg));
+
+ *homedir = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_homedir_attr );
+ *shell = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_shell_attr );
+ *gecos = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_gecos_attr );
if (gid) {
- if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) )
+ if ( !ads_pull_uint32(ads, msg, ctx->ad_schema->posix_gidnumber_attr, gid ) )
*gid = (uint32)-1;
}
@@ -781,13 +876,16 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
/* Have to do our own query */
- attrs[0] = ad_schema->posix_homedir_attr;
- attrs[1] = ad_schema->posix_shell_attr;
- attrs[2] = ad_schema->posix_gecos_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ DEBUG(10, ("nss_ad_get_info: no ads connection given, doing our "
+ "own query\n"));
+
+ attrs[0] = ctx->ad_schema->posix_homedir_attr;
+ attrs[1] = ctx->ad_schema->posix_shell_attr;
+ attrs[2] = ctx->ad_schema->posix_gecos_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
sidstr = sid_binstring(sid);
- filter = talloc_asprintf(ctx, "(objectSid=%s)", sidstr);
+ filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr);
SAFE_FREE(sidstr);
if (!filter) {
@@ -795,18 +893,18 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg_internal, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg_internal, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- *homedir = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_homedir_attr);
- *shell = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_shell_attr);
- *gecos = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_gecos_attr);
+ *homedir = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_homedir_attr);
+ *shell = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_shell_attr);
+ *gecos = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_gecos_attr);
if (gid) {
- if (!ads_pull_uint32(ads_internal, msg_internal, ad_schema->posix_gidnumber_attr, gid))
+ if (!ads_pull_uint32(ctx->ads, msg_internal, ctx->ad_schema->posix_gidnumber_attr, gid))
*gid = (uint32)-1;
}
@@ -814,7 +912,7 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
done:
if (msg_internal) {
- ads_msgfree(ads_internal, msg_internal);
+ ads_msgfree(ctx->ads, msg_internal);
}
return nt_status;
@@ -824,21 +922,22 @@ done:
*********************************************************************/
static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias)
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {NULL, /* attr_uid */
NULL };
char *filter = NULL;
LDAPMessage *msg = NULL;
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx = NULL;
/* Check incoming parameters */
- if ( !domain || !name || !*alias) {
+ if ( !e || !e->domain || !name || !*alias) {
nt_status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
@@ -850,14 +949,20 @@ static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
goto done;
}
- ads_internal = ad_idmap_cached_connection();
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
+
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if (!ads_internal || !ad_schema) {
+ if (!ctx->ad_schema) {
nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto done;
}
- attrs[0] = ad_schema->posix_uid_attr;
+ attrs[0] = ctx->ad_schema->posix_uid_attr;
filter = talloc_asprintf(mem_ctx,
"(sAMAccountName=%s)",
@@ -867,13 +972,13 @@ static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- *alias = ads_pull_string(ads_internal, mem_ctx, msg, ad_schema->posix_uid_attr );
+ *alias = ads_pull_string(ctx->ads, mem_ctx, msg, ctx->ad_schema->posix_uid_attr);
if (!*alias) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -886,7 +991,7 @@ done:
talloc_destroy(filter);
}
if (msg) {
- ads_msgfree(ads_internal, msg);
+ ads_msgfree(ctx->ads, msg);
}
return nt_status;
@@ -896,11 +1001,10 @@ done:
*********************************************************************/
static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name )
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {"sAMAccountName",
NULL };
char *filter = NULL;
@@ -908,6 +1012,8 @@ static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
char *username;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx = NULL;
/* Check incoming parameters */
@@ -923,29 +1029,35 @@ static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
goto done;
}
- ads_internal = ad_idmap_cached_connection();
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
+
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if (!ads_internal || !ad_schema) {
+ if (!ctx->ad_schema) {
nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto done;
}
filter = talloc_asprintf(mem_ctx,
"(%s=%s)",
- ad_schema->posix_uid_attr,
+ ctx->ad_schema->posix_uid_attr,
alias);
if (!filter) {
nt_status = NT_STATUS_NO_MEMORY;
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- username = ads_pull_string(ads_internal, mem_ctx, msg,
+ username = ads_pull_string(ctx->ads, mem_ctx, msg,
"sAMAccountName");
if (!username) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -966,7 +1078,7 @@ done:
talloc_destroy(filter);
}
if (msg) {
- ads_msgfree(ads_internal, msg);
+ ads_msgfree(ctx->ads, msg);
}
return nt_status;
diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c
index 7596b1cbd8..7e186ca8a1 100644
--- a/source3/winbindd/idmap_adex/idmap_adex.c
+++ b/source3/winbindd/idmap_adex/idmap_adex.c
@@ -329,9 +329,9 @@ static NTSTATUS _nss_adex_get_info(struct
/**********************************************************************
*********************************************************************/
-static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *name, char **alias)
+static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
+ struct nss_domain_entry *e,
+ const char *name, char **alias)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct likewise_cell *cell = NULL;
@@ -344,7 +344,7 @@ static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
BAIL_ON_NTSTATUS_ERROR(nt_status);
}
- nt_status = cell->provider->map_to_alias(mem_ctx, domain,
+ nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
name, alias);
/* go ahead and allow the cache mgr to mark this in
@@ -360,9 +360,9 @@ done:
/**********************************************************************
*********************************************************************/
-static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *alias, char **name)
+static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
+ struct nss_domain_entry *e,
+ const char *alias, char **name)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct likewise_cell *cell = NULL;
@@ -376,7 +376,7 @@ static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
}
- nt_status = cell->provider->map_from_alias(mem_ctx, domain,
+ nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
alias, name);
/* go ahead and allow the cache mgr to mark this in
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index a050f99bc8..7dd94aede0 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -304,14 +304,14 @@ done:
*********************************************************************/
static NTSTATUS nss_hash_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
const char *value;
- value = talloc_asprintf(mem_ctx, "%s\\%s", domain, name);
+ value = talloc_asprintf(mem_ctx, "%s\\%s", e->domain, name);
BAIL_ON_PTR_NT_ERROR(value, nt_status);
nt_status = mapfile_lookup_key(mem_ctx, value, alias);
@@ -325,7 +325,7 @@ done:
*********************************************************************/
static NTSTATUS nss_hash_map_from_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name)
{
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index f9d3a9fbff..4c8cceb691 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -820,10 +820,11 @@ done:
}
/**********************************
- set a mapping.
+ set a mapping.
**********************************/
-static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -839,17 +840,19 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data.dptr = NULL;
/* TODO: should we filter a set_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ 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);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -875,8 +878,13 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
ksid = string_term_tdb_data(ksidstr);
/* *DELETE* previous mappings if any.
- * This is done both SID and [U|G]ID passed in */
-
+ * This is done for both the SID and [U|G]ID passed in */
+
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -886,7 +894,8 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, ksid);
if (data.dptr) {
- DEBUG(10, ("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, ksidstr ));
+ DEBUG(10, ("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, ksidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, ksid);
SAFE_FREE(data.dptr);
@@ -894,20 +903,23 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, kid);
if (data.dptr) {
- DEBUG(10,("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, kidstr ));
+ DEBUG(10,("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, kidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, kid);
SAFE_FREE(data.dptr);
}
if (tdb_store(ctx->tdb, ksid, kid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error storing SID -> ID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing SID -> ID: %s\n",
+ tdb_errorstr(ctx->tdb)));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (tdb_store(ctx->tdb, kid, ksid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error stroing ID -> SID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing ID -> SID: %s\n",
+ tdb_errorstr(ctx->tdb)));
/* try to remove the previous stored SID -> ID map */
tdb_delete(ctx->tdb, ksid);
tdb_chainunlock(ctx->tdb, ksid);
@@ -927,10 +939,11 @@ done:
}
/**********************************
- remove a mapping.
+ remove a mapping.
**********************************/
-static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -946,17 +959,19 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
data.dptr = NULL;
/* TODO: should we filter a remove_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ 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);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -981,6 +996,11 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
ksid = string_term_tdb_data(ksidstr);
kid = string_term_tdb_data(kidstr);
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -1001,16 +1021,17 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
if ((data.dsize != kid.dsize) ||
(memcmp(data.dptr, kid.dptr, data.dsize) != 0)) {
DEBUG(10,("Specified SID does not map to specified ID\n"));
- DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, (const char *)data.dptr));
+ DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr,
+ (const char *)data.dptr));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_NONE_MAPPED;
goto done;
}
-
+
DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr));
/* Delete previous mappings. */
-
+
DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr ));
tdb_delete(ctx->tdb, ksid);
diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c
index 9f876618be..9abf425f3e 100644
--- a/source3/winbindd/idmap_util.c
+++ b/source3/winbindd/idmap_util.c
@@ -33,7 +33,8 @@ NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
struct id_map map;
bool expired;
- DEBUG(10,("uid = [%lu]\n", (unsigned long)uid));
+ DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n",
+ (unsigned long)uid, domname?domname:"NULL"));
if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
@@ -85,7 +86,8 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
struct id_map map;
bool expired;
- DEBUG(10,("gid = [%lu]\n", (unsigned long)gid));
+ DEBUG(10,("idmap_gid_to_si: gid = [%lu], domain = '%s'\n",
+ (unsigned long)gid, domname?domname:"NULL"));
if (idmap_cache_find_gid2sid(gid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
@@ -137,7 +139,8 @@ NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
struct id_map map;
bool expired;
- DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid)));
+ DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n",
+ sid_string_dbg(sid), dom_name));
if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
@@ -209,7 +212,8 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
struct id_map map;
bool expired;
- DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid)));
+ DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n",
+ sid_string_dbg(sid), domname));
if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
diff --git a/source3/winbindd/nss_info.c b/source3/winbindd/nss_info.c
index 0e8cb60257..734c009602 100644
--- a/source3/winbindd/nss_info.c
+++ b/source3/winbindd/nss_info.c
@@ -1,19 +1,20 @@
-/*
+/*
Unix SMB/CIFS implementation.
Idmap NSS headers
Copyright (C) Gerald Carter 2006
+ Copyright (C) Michael Adam 2008
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
-
+
This library 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
Library General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,6 +23,7 @@
#include "nss_info.h"
static struct nss_function_entry *backends = NULL;
+static struct nss_function_entry *default_backend = NULL;
static struct nss_domain_entry *nss_domain_list = NULL;
/**********************************************************************
@@ -48,14 +50,14 @@ static struct nss_function_entry *nss_get_backend(const char *name )
{
struct nss_function_entry *entry;
- if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
+ if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
DEBUG(0, ("smb_register_idmap_nss: Failed to register idmap_nss module.\n"
- "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
- "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
- "Please recompile against the current version of samba!\n",
+ "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
+ "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
+ "Please recompile against the current version of samba!\n",
version, SMB_NSS_INFO_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ }
if (!name || !name[0] || !methods) {
DEBUG(0,("smb_register_idmap_nss: called with NULL pointer or empty name!\n"));
@@ -89,12 +91,12 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
int len;
*backend = *domain = NULL;
-
+
if ( !config )
return False;
-
+
p = strchr( config, ':' );
-
+
/* if no : then the string must be the backend name only */
if ( !p ) {
@@ -107,13 +109,13 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
if ( strlen(p+1) > 0 ) {
*domain = SMB_STRDUP( p+1 );
}
-
+
len = PTR_DIFF(p,config)+1;
if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) {
SAFE_FREE( *backend );
return False;
}
-
+
StrnCpy( q, config, len-1);
q[len-1] = '\0';
*backend = q;
@@ -121,8 +123,44 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
return True;
}
+static NTSTATUS nss_domain_list_add_domain(const char *domain,
+ struct nss_function_entry *nss_backend)
+{
+ struct nss_domain_entry *nss_domain;
+
+ nss_domain = TALLOC_ZERO_P(nss_domain_list, struct nss_domain_entry);
+ if (!nss_domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nss_domain->backend = nss_backend;
+ if (domain) {
+ nss_domain->domain = talloc_strdup(nss_domain, domain);
+ if (!nss_domain->domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() "
+ "failure!\n"));
+ TALLOC_FREE(nss_domain);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ nss_domain->init_status = nss_domain->backend->methods->init(nss_domain);
+ if (!NT_STATUS_IS_OK(nss_domain->init_status)) {
+ DEBUG(0, ("nss_init: Failed to init backend '%s' for domain "
+ "'%s'!\n", nss_backend->name, nss_domain->domain));
+ }
+
+ DLIST_ADD(nss_domain_list, nss_domain);
+
+ DEBUG(10, ("Added domain '%s' with backend '%s' to nss_domain_list.\n",
+ domain, nss_backend->name));
+
+ return NT_STATUS_OK;
+}
+
/********************************************************************
- Each nss backend must not store global state, but rather be able
+ Each nss backend must not store global state, but rather be able
to initialize the state on a per domain basis.
*******************************************************************/
@@ -133,18 +171,17 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
int i;
char *backend, *domain;
struct nss_function_entry *nss_backend;
- struct nss_domain_entry *nss_domain;
/* check for previous successful initializations */
if ( NT_STATUS_IS_OK(nss_initialized) )
return NT_STATUS_OK;
-
+
/* The "template" backend should alqays be registered as it
is a static module */
if ( (nss_backend = nss_get_backend( "template" )) == NULL ) {
- static_init_nss_info;
+ static_init_nss_info;
}
/* Create the list of nss_domains (loading any shared plugins
@@ -152,12 +189,15 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
for ( i=0; nss_list && nss_list[i]; i++ ) {
- if ( !parse_nss_parm(nss_list[i], &backend, &domain) ) {
+ if ( !parse_nss_parm(nss_list[i], &backend, &domain) ) {
DEBUG(0,("nss_init: failed to parse \"%s\"!\n",
nss_list[i]));
- continue;
+ continue;
}
+ DEBUG(10, ("parsed backend = '%s', domain = '%s'\n",
+ backend, domain));
+
/* validate the backend */
if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
@@ -166,41 +206,34 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
if ( !NT_STATUS_IS_OK(status) ) {
continue;
}
-
+
/* try again */
if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
DEBUG(0,("nss_init: unregistered backend %s!. Skipping\n",
backend));
continue;
}
-
}
- /* fill in the nss_domain_entry and add it to the
- list of domains */
-
- nss_domain = TALLOC_ZERO_P( nss_domain_list, struct nss_domain_entry );
- if ( !nss_domain ) {
- DEBUG(0,("nss_init: talloc() failure!\n"));
- return NT_STATUS_NO_MEMORY;
+ /*
+ * The first config item of the list without an explicit domain
+ * is treated as the default nss info backend.
+ */
+ if ((domain == NULL) && (default_backend == NULL)) {
+ DEBUG(10, ("nss_init: using '%s' as default backend.\n",
+ backend));
+ default_backend = nss_backend;
}
-
- nss_domain->backend = nss_backend;
- nss_domain->domain = talloc_strdup( nss_domain, domain );
- /* Try to init and ave the result */
-
- nss_domain->init_status = nss_domain->backend->methods->init( nss_domain );
- DLIST_ADD( nss_domain_list, nss_domain );
- if ( !NT_STATUS_IS_OK(nss_domain->init_status) ) {
- DEBUG(0,("nss_init: Failed to init backend for %s domain!\n",
- nss_domain->domain));
+ status = nss_domain_list_add_domain(domain, nss_backend);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
/* cleanup */
SAFE_FREE( backend );
- SAFE_FREE( domain );
+ SAFE_FREE( domain );
}
if ( !nss_domain_list ) {
@@ -210,10 +243,9 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
/* we shouild default to use template here */
}
-
-
+
nss_initialized = NT_STATUS_OK;
-
+
return NT_STATUS_OK;
}
@@ -222,7 +254,7 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
static struct nss_domain_entry *find_nss_domain( const char *domain )
{
- NTSTATUS status;
+ NTSTATUS status;
struct nss_domain_entry *p;
status = nss_init( lp_winbind_nss_info() );
@@ -231,20 +263,30 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
nt_errstr(status)));
return NULL;
}
-
+
for ( p=nss_domain_list; p; p=p->next ) {
if ( strequal( p->domain, domain ) )
break;
}
-
- /* If we didn't find a match, then use the default nss info */
+
+ /* If we didn't find a match, then use the default nss backend */
if ( !p ) {
- if ( !nss_domain_list ) {
+ if (!default_backend) {
+ return NULL;
+ }
+
+ status = nss_domain_list_add_domain(domain, default_backend);
+ if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
-
- p = nss_domain_list;
+
+ /*
+ * HACK ALERT:
+ * Here, we use the fact that the new domain was added at
+ * the beginning of the list...
+ */
+ p = nss_domain_list;
}
if ( !NT_STATUS_IS_OK( p->init_status ) ) {
@@ -266,15 +308,18 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
struct nss_domain_entry *p;
struct nss_info_methods *m;
+ DEBUG(10, ("nss_get_info called for sid [%s] in domain '%s'\n",
+ sid_string_dbg(user_sid), domain?domain:"NULL"));
+
if ( (p = find_nss_domain( domain )) == NULL ) {
DEBUG(4,("nss_get_info: Failed to find nss domain pointer for %s\n",
domain ));
return NT_STATUS_NOT_FOUND;
}
-
+
m = p->backend->methods;
- return m->get_nss_info( p, user_sid, ctx, ads, msg,
+ return m->get_nss_info( p, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
}
@@ -295,7 +340,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
m = p->backend->methods;
- return m->map_to_alias( mem_ctx, domain, name, alias );
+ return m->map_to_alias(mem_ctx, p, name, alias);
}
@@ -316,7 +361,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
m = p->backend->methods;
- return m->map_from_alias( mem_ctx, domain, alias, name );
+ return m->map_from_alias( mem_ctx, p, alias, name );
}
/********************************************************************
diff --git a/source3/winbindd/nss_info_template.c b/source3/winbindd/nss_info_template.c
index d8f903ddd0..f44c73f3a6 100644
--- a/source3/winbindd/nss_info_template.c
+++ b/source3/winbindd/nss_info_template.c
@@ -62,7 +62,7 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
*********************************************************************/
static NTSTATUS nss_template_map_to_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias )
{
@@ -73,7 +73,7 @@ static NTSTATUS nss_template_map_to_alias( TALLOC_CTX *mem_ctx,
*********************************************************************/
static NTSTATUS nss_template_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name )
{
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index ce1a1fe52f..82af55800f 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -343,6 +343,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" },
{ WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" },
+ { WINBINDD_REMOVE_MAPPING, winbindd_remove_mapping, "REMOVE_MAPPING" },
{ WINBINDD_SET_HWM, winbindd_set_hwm, "SET_HWMS" },
/* Miscellaneous */
@@ -367,7 +368,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
{ WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
-
+
/* End of list */
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 1febddf110..5c7d491849 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -401,6 +401,47 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
+/* convert a single name to a sid in a domain - use rpc methods */
+static NTSTATUS name_to_sid(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ enum winbindd_cmd orig_cmd,
+ const char *domain_name,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *type)
+{
+ return reconnect_methods.name_to_sid(domain, mem_ctx, orig_cmd,
+ domain_name, name,
+ sid, type);
+}
+
+/* convert a domain SID to a user or group name - use rpc methods */
+static NTSTATUS sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ char **domain_name,
+ char **name,
+ enum lsa_SidType *type)
+{
+ return reconnect_methods.sid_to_name(domain, mem_ctx, sid,
+ domain_name, name, type);
+}
+
+/* convert a list of rids to names - use rpc methods */
+static NTSTATUS rids_to_names(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ uint32 *rids,
+ size_t num_rids,
+ char **domain_name,
+ char ***names,
+ enum lsa_SidType **types)
+{
+ return reconnect_methods.rids_to_names(domain, mem_ctx, sid,
+ rids, num_rids,
+ domain_name, names, types);
+}
+
/* If you are looking for "dn_lookup": Yes, it used to be here!
* It has gone now since it was a major speed bottleneck in
* lookup_groupmem (its only use). It has been replaced by
@@ -641,9 +682,10 @@ done:
tokenGroups are not available. */
static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const char *user_dn,
+ const char *user_dn,
DOM_SID *primary_group,
- size_t *p_num_groups, DOM_SID **user_sids)
+ size_t *p_num_groups,
+ DOM_SID **user_sids)
{
ADS_STATUS rc;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -652,15 +694,15 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
size_t num_groups = 0;
DOM_SID *group_sids = NULL;
int i;
- char **strings;
- size_t num_strings = 0;
+ char **strings = NULL;
+ size_t num_strings = 0, num_sids = 0;
DEBUG(3,("ads: lookup_usergroups_memberof\n"));
if ( !winbindd_can_contact_domain( domain ) ) {
- DEBUG(10,("lookup_usergroups_memberof: No incoming trust for domain %s\n",
- domain->name));
+ DEBUG(10,("lookup_usergroups_memberof: No incoming trust for "
+ "domain %s\n", domain->name));
return NT_STATUS_OK;
}
@@ -668,19 +710,19 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
if (!ads) {
domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
+ return NT_STATUS_UNSUCCESSFUL;
}
- rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
- ADS_EXTENDED_DN_HEX_STRING,
+ rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
+ ADS_EXTENDED_DN_HEX_STRING,
&strings, &num_strings);
if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n",
- user_dn, ads_errstr(rc)));
+ DEBUG(1,("lookup_usergroups_memberof ads_search "
+ "member=%s: %s\n", user_dn, ads_errstr(rc)));
return ads_ntstatus(rc);
}
-
+
*user_sids = NULL;
num_groups = 0;
@@ -693,21 +735,26 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);
if (!group_sids) {
- TALLOC_FREE(strings);
status = NT_STATUS_NO_MEMORY;
goto done;
}
for (i=0; i<num_strings; i++) {
-
- if (!ads_get_sid_from_extended_dn(mem_ctx, strings[i],
- ADS_EXTENDED_DN_HEX_STRING,
- &(group_sids)[i])) {
- TALLOC_FREE(group_sids);
- TALLOC_FREE(strings);
- status = NT_STATUS_NO_MEMORY;
- goto done;
+ rc = ads_get_sid_from_extended_dn(mem_ctx, strings[i],
+ ADS_EXTENDED_DN_HEX_STRING,
+ &(group_sids)[i]);
+ if (!ADS_ERR_OK(rc)) {
+ /* ignore members without SIDs */
+ if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+ NT_STATUS_NOT_FOUND)) {
+ continue;
+ }
+ else {
+ status = ads_ntstatus(rc);
+ goto done;
+ }
}
+ num_sids++;
}
if (i == 0) {
@@ -716,7 +763,7 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
goto done;
}
- for (i=0; i<num_strings; i++) {
+ for (i=0; i<num_sids; i++) {
/* ignore Builtin groups from ADS - Guenther */
if (sid_check_is_in_builtin(&group_sids[i])) {
@@ -728,14 +775,17 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
-
+
}
*p_num_groups = num_groups;
status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
- DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n", user_dn));
+ DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n",
+ user_dn));
+
done:
+ TALLOC_FREE(strings);
TALLOC_FREE(group_sids);
return status;
@@ -894,13 +944,25 @@ done:
return status;
}
+/* Lookup aliases a user is member of - use rpc methods */
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID *sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ return reconnect_methods.lookup_useraliases(domain, mem_ctx,
+ num_sids, sids,
+ num_aliases,
+ alias_rids);
+}
+
/*
find the members of a group, given a group rid and domain
*/
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ const DOM_SID *group_sid, uint32 *num_names,
+ DOM_SID **sid_mem, char ***names,
uint32 **name_types)
{
ADS_STATUS rc;
@@ -921,7 +983,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
uint32 num_nocache = 0;
TALLOC_CTX *tmp_ctx = NULL;
- DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
+ DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
sid_string_dbg(group_sid)));
*num_names = 0;
@@ -935,12 +997,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
- domain->name));
+ domain->name));
return NT_STATUS_OK;
}
ads = ads_cached_connection(domain);
-
+
if (!ads) {
domain->last_status = NT_STATUS_SERVER_DISABLED;
goto done;
@@ -952,8 +1014,8 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
}
/* search for all members of the group */
- if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)",
- sidbinstr)))
+ if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)",
+ sidbinstr)))
{
SAFE_FREE(sidbinstr);
DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n"));
@@ -966,21 +1028,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
args.val = ADS_EXTENDED_DN_HEX_STRING;
args.critical = True;
- rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
+ rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
ldap_exp, &args, "member", &members, &num_members);
if (!ADS_ERR_OK(rc)) {
DEBUG(0,("ads_ranged_search failed with: %s\n", ads_errstr(rc)));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
- }
-
+ }
+
DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
-
+
/* Now that we have a list of sids, we need to get the
* lists of names and name_types belonging to these sids.
- * even though conceptually not quite clean, we use the
- * RPC call lsa_lookup_sids for this since it can handle a
+ * even though conceptually not quite clean, we use the
+ * RPC call lsa_lookup_sids for this since it can handle a
* list of sids. ldap calls can just resolve one sid at a time.
*
* At this stage, the sids are still hidden in the exetended dn
@@ -988,7 +1050,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
* stated above: In extracting the sids from the member strings,
* we try to resolve as many sids as possible from the
* cache. Only the rest is passed to the lsa_lookup_sids call. */
-
+
if (num_members) {
(*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
(*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
@@ -1015,11 +1077,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
char *name, *domain_name;
DOM_SID sid;
- if (!ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, &sid)) {
- status = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val,
+ &sid);
+ if (!ADS_ERR_OK(rc)) {
+ if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+ NT_STATUS_NOT_FOUND)) {
+ /* Group members can be objects, like Exchange
+ * Public Folders, that don't have a SID. Skip
+ * them. */
+ continue;
+ }
+ else {
+ status = ads_ntstatus(rc);
+ goto done;
+ }
}
- if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
+ if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name,
+ &name_type)) {
DEBUG(10,("ads: lookup_groupmem: got sid %s from "
"cache\n", sid_string_dbg(&sid)));
sid_copy(&(*sid_mem)[*num_names], &sid);
@@ -1052,23 +1126,46 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
goto done;
}
- status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
+ status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
&lsa_policy,
- num_nocache,
- sid_mem_nocache,
- &domains_nocache,
- &names_nocache,
+ num_nocache,
+ sid_mem_nocache,
+ &domains_nocache,
+ &names_nocache,
&name_types_nocache);
+ if (!(NT_STATUS_IS_OK(status) ||
+ NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)))
+ {
+ DEBUG(1, ("lsa_lookupsids call failed with %s "
+ "- retrying...\n", nt_errstr(status)));
+
+ status = cm_connect_lsa(domain, tmp_ctx, &cli,
+ &lsa_policy);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
+ &lsa_policy,
+ num_nocache,
+ sid_mem_nocache,
+ &domains_nocache,
+ &names_nocache,
+ &name_types_nocache);
+ }
+
if (NT_STATUS_IS_OK(status) ||
- NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
+ NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
{
- /* Copy the entries over from the "_nocache" arrays
- * to the result arrays, skipping the gaps the
+ /* Copy the entries over from the "_nocache" arrays
+ * to the result arrays, skipping the gaps the
* lookup_sids call left. */
for (i=0; i < num_nocache; i++) {
- if (((names_nocache)[i] != NULL) &&
- ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
+ if (((names_nocache)[i] != NULL) &&
+ ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
{
sid_copy(&(*sid_mem)[*num_names],
&sid_mem_nocache[i]);
@@ -1150,6 +1247,22 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
return ads_ntstatus(rc);
}
+/* find the lockout policy of a domain - use rpc methods */
+static NTSTATUS lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo12 *policy)
+{
+ return reconnect_methods.lockout_policy(domain, mem_ctx, policy);
+}
+
+/* find the password policy of a domain - use rpc methods */
+static NTSTATUS password_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *policy)
+{
+ return reconnect_methods.password_policy(domain, mem_ctx, policy);
+}
+
/* get a list of trusted domains */
static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -1340,16 +1453,16 @@ struct winbindd_methods ads_methods = {
query_user_list,
enum_dom_groups,
enum_local_groups,
- msrpc_name_to_sid,
- msrpc_sid_to_name,
- msrpc_rids_to_names,
+ name_to_sid,
+ sid_to_name,
+ rids_to_names,
query_user,
lookup_usergroups,
- msrpc_lookup_useraliases,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
- msrpc_lockout_policy,
- msrpc_password_policy,
+ lockout_policy,
+ password_policy,
trusted_domains,
};
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 360e915bc4..2f4a6ffe56 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -4222,7 +4222,14 @@ do_query:
nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
+ DEBUG(10, ("nss_get_info returned %s\n", nt_errstr(nt_status)));
+
if ( NT_STATUS_IS_OK(nt_status) ) {
+ DEBUG(10, ("result:\n\thomedir = '%s'\n", *homedir));
+ DEBUGADD(10, ("\tshell = '%s'\n", *shell));
+ DEBUGADD(10, ("\tgecos = '%s'\n", *gecos));
+ DEBUGADD(10, ("\tgid = '%u'\n", *p_gid));
+
wcache_save_user_pwinfo( domain, nt_status, user_sid,
*homedir, *shell, *gecos, *p_gid );
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 03d1e043bf..9153585c26 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1279,6 +1279,7 @@ static bool fork_domain_child(struct winbindd_child *child)
}
if (child->domain && child->domain->primary &&
+ !lp_use_kerberos_keytab() &&
lp_server_role() == ROLE_DOMAIN_MEMBER) {
struct timeval next_change;
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index 8e56138bb5..3422fdba1c 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -585,7 +585,7 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
}
/* Real work goes here. Create a list of group names to
- expand startign with the initial one. Pass that to
+ expand starting with the initial one. Pass that to
expand_groups() which returns a list of more group names
to expand. Do this up to the max search depth. */
@@ -922,7 +922,7 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
&mapped_name);
- /* basiuc whitespace reversal */
+ /* basic whitespace reversal */
if (NT_STATUS_IS_OK(nt_status)) {
s->group_name = talloc_asprintf(s->state->mem_ctx,
"%s%c%s",
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
index d8c67dc21c..94a8c78a85 100644
--- a/source3/winbindd/winbindd_idmap.c
+++ b/source3/winbindd/winbindd_idmap.c
@@ -111,6 +111,65 @@ enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+static void winbindd_remove_mapping_recv(TALLOC_CTX *mem_ctx, bool success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, bool succ) = (void (*)(void *, bool))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger idmap_remove_mapping\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap_remove_mapping returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx,
+ const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_REMOVE_MAPPING;
+ request.data.dual_idmapset.id = map->xid.id;
+ request.data.dual_idmapset.type = map->xid.type;
+ sid_to_fstring(request.data.dual_idmapset.sid, map->sid);
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_remove_mapping_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_remove_mapping(
+ struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: dual_idmapremove\n", (unsigned long)state->pid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
+ return WINBINDD_ERROR;
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+ map.status = ID_MAPPED;
+
+ result = idmap_remove_mapping(&map);
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, bool success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -486,6 +545,10 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
.struct_cmd = WINBINDD_DUAL_SET_MAPPING,
.struct_fn = winbindd_dual_set_mapping,
},{
+ .name = "DUAL_REMOVE_MAPPING",
+ .struct_cmd = WINBINDD_DUAL_REMOVE_MAPPING,
+ .struct_fn = winbindd_dual_remove_mapping,
+ },{
.name = "DUAL_SET_HWMS",
.struct_cmd = WINBINDD_DUAL_SET_HWM,
.struct_fn = winbindd_dual_set_hwm,
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 9ff3899661..597d48aad0 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1854,17 +1854,28 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
|| state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
- DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
- state->request.data.auth_crap.lm_resp_len,
- state->request.data.auth_crap.nt_resp_len));
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB ||
+ state->request.extra_len != state->request.data.auth_crap.nt_resp_len) {
+ DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
+ state->request.data.auth_crap.lm_resp_len,
+ state->request.data.auth_crap.nt_resp_len));
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
}
lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp,
state->request.data.auth_crap.lm_resp_len);
- nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp,
- state->request.data.auth_crap.nt_resp_len);
+
+ if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) {
+ nt_resp = data_blob_talloc(state->mem_ctx,
+ state->request.extra_data.data,
+ state->request.data.auth_crap.nt_resp_len);
+ } else {
+ nt_resp = data_blob_talloc(state->mem_ctx,
+ state->request.data.auth_crap.nt_resp,
+ state->request.data.auth_crap.nt_resp_len);
+ }
/* what domain should we contact? */
@@ -2106,9 +2117,15 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
got_info = true;
}
+ /* atm the pidl generated rpccli_samr_ChangePasswordUser3 function will
+ * return with NT_STATUS_BUFFER_TOO_SMALL for w2k dcs as w2k just
+ * returns with 4byte error code (NT_STATUS_NOT_SUPPORTED) which is too
+ * short to comply with the samr_ChangePasswordUser3 idl - gd */
+
/* only fallback when the chgpasswd_user3 call is not supported */
if ((NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) ||
+ (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) {
DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n",
diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c
index 5677c01be1..101854ae94 100644
--- a/source3/winbindd/winbindd_passdb.c
+++ b/source3/winbindd/winbindd_passdb.c
@@ -267,6 +267,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
}
if ( !pdb_getsampwsid( user, user_sid ) ) {
+ TALLOC_FREE( user );
return NT_STATUS_NO_SUCH_USER;
}
@@ -638,13 +639,13 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
sid_type_lookup(lsa_names[i].type)));
continue;
}
- if (!((*names)[i] = talloc_strdup((*names),
+ if (!((*names)[num_mapped] = talloc_strdup((*names),
lsa_names[i].name))) {
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
- (*name_types)[i] = lsa_names[i].type;
+ (*name_types)[num_mapped] = lsa_names[i].type;
num_mapped += 1;
}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 65ad47dd03..9de385e3b3 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -353,6 +353,11 @@ void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
void *private_data);
enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data);
+enum winbindd_result winbindd_dual_remove_mapping(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state);
void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
void (*cont)(void *private_data, bool success),
void *private_data);
@@ -462,40 +467,6 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
/* The following definitions come from winbindd/winbindd_reconnect.c */
-/* The following definitions come from winbindd/winbindd_rpc.c */
-
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- enum winbindd_cmd original_cmd,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type);
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **domain_name,
- char **name,
- enum lsa_SidType *type);
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *rids,
- size_t num_rids,
- char **domain_name,
- char ***names,
- enum lsa_SidType **types);
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids);
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy);
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy);
-
/* The following definitions come from winbindd/winbindd_sid.c */
void winbindd_lookupsid(struct winbindd_cli_state *state);
@@ -505,6 +476,7 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state);
void winbindd_sid_to_gid(struct winbindd_cli_state *state);
void winbindd_sids_to_unixids(struct winbindd_cli_state *state);
void winbindd_set_mapping(struct winbindd_cli_state *state);
+void winbindd_remove_mapping(struct winbindd_cli_state *state);
void winbindd_set_hwm(struct winbindd_cli_state *state);
void winbindd_uid_to_sid(struct winbindd_cli_state *state);
void winbindd_gid_to_sid(struct winbindd_cli_state *state);
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index d966e50159..0070bde2cc 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -265,13 +265,13 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
}
/* convert a single name to a sid in a domain */
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- enum winbindd_cmd original_cmd,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type)
+static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ enum winbindd_cmd original_cmd,
+ const char *domain_name,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *type)
{
NTSTATUS result;
DOM_SID *sids = NULL;
@@ -331,12 +331,12 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
/*
convert a domain SID to a user or group name
*/
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **domain_name,
- char **name,
- enum lsa_SidType *type)
+static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ char **domain_name,
+ char **name,
+ enum lsa_SidType *type)
{
char **domains;
char **names;
@@ -384,14 +384,14 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *rids,
- size_t num_rids,
- char **domain_name,
- char ***names,
- enum lsa_SidType **types)
+static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ uint32 *rids,
+ size_t num_rids,
+ char **domain_name,
+ char ***names,
+ enum lsa_SidType **types)
{
char **domains;
NTSTATUS result;
@@ -636,10 +636,13 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids)
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+
+static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID *sids,
+ uint32 *num_aliases,
+ uint32 **alias_rids)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol;
@@ -1102,9 +1105,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
}
/* find the lockout policy for a domain */
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy)
+static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo12 *lockout_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
@@ -1143,9 +1146,9 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
}
/* find the password policy for a domain */
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy)
+static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *password_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index 274786fa63..641b18ebbd 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -370,7 +370,8 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state)
range from random SIDs. */
backend:
- winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );
+ winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv,
+ state );
}
static void set_mapping_recv(void *private_data, bool success)
@@ -415,6 +416,48 @@ void winbindd_set_mapping(struct winbindd_cli_state *state)
set_mapping_recv, state);
}
+static void remove_mapping_recv(void *private_data, bool success)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (!success) {
+ DEBUG(5, ("Could not remove sid mapping\n"));
+ request_error(state);
+ return;
+ }
+
+ request_ok(state);
+}
+
+void winbindd_remove_mapping(struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+
+ DEBUG(3, ("[%5lu]: remove id map\n", (unsigned long)state->pid));
+
+ if ( ! state->privileged) {
+ DEBUG(0, ("Only root is allowed to remove mappings!\n"));
+ request_error(state);
+ return;
+ }
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.sid));
+ request_error(state);
+ return;
+ }
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+
+ winbindd_remove_mapping_async(state->mem_ctx, &map,
+ remove_mapping_recv, state);
+}
+
static void set_hwm_recv(void *private_data, bool success)
{
struct winbindd_cli_state *state =