*
* 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
+ * 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,
* 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.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
/* 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) )
{
ADS_STATUS schema_status;
/************************************************************************
***********************************************************************/
-static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom, const char *params)
+static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
{
struct idmap_ad_context *ctx;
char *config_option;
- const char *range;
- ADS_STRUCT *ads;
-
- /* verify AD is reachable (not critical, we may just be offline at start) */
- if ( (ads = ad_idmap_cached_connection()) == NULL ) {
- DEBUG(1, ("WARNING: Could not init an AD connection! Mapping might not work.\n"));
- }
+ const char *range = NULL;
+ const char *schema_mode = NULL;
- if ( (ctx = talloc_zero(dom, struct idmap_ad_context)) == NULL ) {
+ if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
}
}
}
- /* idmap AD can work well only if it is the default module (trusts)
- * with additional BUILTIN and alloc using TDB */
- if ( ! dom->default_domain) {
- DEBUG(1, ("WARNING: idmap_ad is not configured as the default domain.\n"
- "For best results we suggest you to configure this module as\n"
- "default and configure BULTIN to use idmap_tdb\n"
- "ex: idmap domains = BUILTIN %s\n"
- " idmap alloc config: range = 5000 - 9999\n"
- " idmap config %s: default = yes\n"
- " idmap config %s: backend = ad\n"
- " idmap config %s: range = 10000 - 10000000 #this is optional\n"
- "NOTE: make sure the ranges do not overlap\n",
- dom->name, dom->name, dom->name, dom->name));
- }
-
- if ( !dom->readonly ) {
- DEBUG(1, ("WARNING: forcing to readonly, as idmap_ad can't write on AD.\n"));
- dom->readonly = true;
+ /* 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;
+ else if ( strequal(schema_mode, "sfu20" ) )
+ ad_map_type = WB_POSIX_MAP_SFU20;
+ else if ( strequal(schema_mode, "rfc2307" ) )
+ ad_map_type = WB_POSIX_MAP_RFC2307;
+ else
+ DEBUG(0,("idmap_ad_initialize: Unknown schema_mode (%s)\n",
+ schema_mode));
}
dom->private_data = ctx;
+ dom->initialized = True;
talloc_free(config_option);
NULL, /* gidnumber */
NULL };
LDAPMessage *res = NULL;
+ LDAPMessage *entry = NULL;
char *filter = NULL;
int idx = 0;
int bidx = 0;
char *u_filter = NULL;
char *g_filter = NULL;
+ /* Only do query if we are online */
+ if (idmap_is_offline()) {
+ return NT_STATUS_FILE_IS_OFFLINE;
+ }
+
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ad_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
if ( (memctx = talloc_new(ctx)) == NULL ) {
break;
default:
- DEBUG(3, ("Unknown ID type\n"));
+ DEBUG(3, ("Error: mapping requested but Unknown ID type\n"));
ids[idx]->status = ID_UNKNOWN;
continue;
}
}
filter = talloc_asprintf_append(filter, ")");
CHECK_ALLOC_DONE(filter);
- DEBUG(10, ("Filter: [%s]\n", filter));
+
rc = ads_search_retry(ads, &res, filter, attrs);
if (!ADS_ERR_OK(rc)) {
DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
DEBUG(10, ("No IDs found\n"));
}
- for (i = 0; i < count; i++) {
- LDAPMessage *entry = NULL;
+ entry = res;
+ for (i = 0; (i < count) && entry; i++) {
DOM_SID sid;
enum id_type type;
struct id_map *map;
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, res);
+ entry = ads_first_entry(ads, entry);
} else { /* following ones */
entry = ads_next_entry(ads, entry);
}
- if ( ! entry) {
+
+ if ( !entry ) {
DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
- continue;
+ break;
}
/* first check if the SID is present */
ret = NT_STATUS_OK;
- /* mark all unknown ones as unmapped */
+ /* mark all unknown/expired ones as unmapped */
for (i = 0; ids[i]; i++) {
- if (ids[i]->status == ID_UNKNOWN)
+ if (ids[i]->status != ID_MAPPED)
ids[i]->status = ID_UNMAPPED;
}
NULL, /* attr_gidnumber */
NULL };
LDAPMessage *res = NULL;
+ LDAPMessage *entry = NULL;
char *filter = NULL;
int idx = 0;
int bidx = 0;
int i;
char *sidstr;
+ /* Only do query if we are online */
+ if (idmap_is_offline()) {
+ return NT_STATUS_FILE_IS_OFFLINE;
+ }
+
+ /* Initilization my have been deferred because we were offline */
+ if ( ! dom->initialized) {
+ ret = idmap_ad_initialize(dom);
+ if ( ! NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+ }
+
ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
if ( (memctx = talloc_new(ctx)) == NULL ) {
DEBUG(10, ("No IDs found\n"));
}
- for (i = 0; i < count; i++) {
- LDAPMessage *entry = NULL;
+ entry = res;
+ for (i = 0; (i < count) && entry; i++) {
DOM_SID sid;
enum id_type type;
struct id_map *map;
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, res);
+ entry = ads_first_entry(ads, entry);
} else { /* following ones */
entry = ads_next_entry(ads, entry);
}
- if ( ! entry) {
+
+ if ( !entry ) {
DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n"));
- continue;
+ break;
}
/* first check if the SID is present */
ret = NT_STATUS_OK;
- /* mark all unknwon ones as unmapped */
+ /* mark all unknwoni/expired ones as unmapped */
for (i = 0; ids[i]; i++) {
- if (ids[i]->status == ID_UNKNOWN)
+ if (ids[i]->status != ID_MAPPED)
ids[i]->status = ID_UNMAPPED;
}
}
/*
- * nss_info_{sfu,rfc2307}
+ * nss_info_{sfu,sfu20,rfc2307}
*/
/************************************************************************
- Initialize the {sfu,rfc2307} state
+ Initialize the {sfu,sfu20,rfc2307} state
***********************************************************************/
static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
return NT_STATUS_NOT_SUPPORTED;
}
- ad_map_type = WB_POSIX_MAP_SFU;
+ ad_map_type = WB_POSIX_MAP_SFU;
- if ( !ad_idmap_ads )
- return idmap_ad_initialize( NULL, NULL );
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS nss_sfu20_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_SFU20) )
+ {
+ DEBUG(0,("nss_sfu20_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_SFU20;
return NT_STATUS_OK;
}
return NT_STATUS_NOT_SUPPORTED;
}
- ad_map_type = WB_POSIX_MAP_RFC2307;
-
- if ( !ad_idmap_ads )
- return idmap_ad_initialize( NULL, NULL );
+ ad_map_type = WB_POSIX_MAP_RFC2307;
return NT_STATUS_OK;
}
{
ADS_STRUCT *ads_internal = 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 */
.close_fn = nss_ad_close
};
+static struct nss_info_methods nss_sfu20_methods = {
+ .init = nss_sfu20_init,
+ .get_nss_info = nss_ad_get_info,
+ .close_fn = nss_ad_close
+};
+
+
/************************************************************************
Initialize the plugins
static NTSTATUS status_idmap_ad = NT_STATUS_UNSUCCESSFUL;
static NTSTATUS status_nss_rfc2307 = NT_STATUS_UNSUCCESSFUL;
static NTSTATUS status_nss_sfu = NT_STATUS_UNSUCCESSFUL;
+ static NTSTATUS status_nss_sfu20 = NT_STATUS_UNSUCCESSFUL;
/* Always register the AD method first in order to get the
idmap_domain interface called */
return status_nss_sfu;
}
+ if ( !NT_STATUS_IS_OK( status_nss_sfu20 ) ) {
+ status_nss_sfu20 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
+ "sfu20", &nss_sfu20_methods );
+ if ( !NT_STATUS_IS_OK(status_nss_sfu20) )
+ return status_nss_sfu20;
+ }
+
return NT_STATUS_OK;
}