From 94bfc6ff0fdeef9afb4de703e5da802db497f75f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 23 Oct 2004 13:23:54 +0000 Subject: r3145: Add experimental idmap_rid-Plugin. Written by Sumit Bose and myself a while ago. idmap_rid does a direct, static mapping between RIDs and UIDs/GIDs using the idmap-range as offset. It does thus allow to have a unified mapping over several winbindd-systems without having the need of a central LDAP-Server (and all related dependencies and problems this solution can bring). Compile: ./configure --with-shared-modules=idmap_rid Usage: idmap backend = idmap_rid idmp_rid does even allow you to have multiple mappings (for trusted domains). This is a rather problemtic feature and will be turned off by default rather soon. The problem is that ranges can quickly overlap when not measured with caution. idmap backend = idmap_rid:"MYDOMAIN=1000-9999 OTHER=10000-19999" Will valgrind idmap_rid later today and fix a couple of things. Guenther (This used to be commit 49a238bd37105bf1a33d4a230ca594c4cf304dd3) --- source3/Makefile.in | 5 + source3/configure.in | 1 + source3/sam/idmap_rid.c | 513 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 519 insertions(+) create mode 100644 source3/sam/idmap_rid.c diff --git a/source3/Makefile.in b/source3/Makefile.in index b6fe22b593..3a32bab1ba 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1137,6 +1137,11 @@ bin/smbpasswd.@SHLIBEXT@: passdb/pdb_smbpasswd.@PICSUFFIX@ @$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_smbpasswd.@PICSUFFIX@ \ @SONAMEFLAG@`basename $@` +bin/idmap_rid.@SHLIBEXT@: sam/idmap_rid.@PICSUFFIX@ + @echo "Building plugin $@" + @$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_rid.@PICSUFFIX@ \ + @SONAMEFLAG@`basename $@` + bin/weird.@SHLIBEXT@: $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) @echo "Building plugin $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(DEVEL_HELP_WEIRD_OBJ:.o=.@PICSUFFIX@) \ diff --git a/source3/configure.in b/source3/configure.in index 6a36fbcdea..df78765559 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -4457,6 +4457,7 @@ SMB_SUBSYSTEM(RPC,smbd/server.o) SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP) SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP) +SMB_MODULE(idmap_rid, sam/idmap_rid.o, "bin/idmap_rid.$SHLIBEXT", IDMAP) SMB_SUBSYSTEM(IDMAP,sam/idmap.o) SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET) diff --git a/source3/sam/idmap_rid.c b/source3/sam/idmap_rid.c new file mode 100644 index 0000000000..0a81475378 --- /dev/null +++ b/source3/sam/idmap_rid.c @@ -0,0 +1,513 @@ +/* + * idmap_rid: static map between Active Directory/NT RIDs and RFC 2307 accounts + * Copyright (C) Guenther Deschner, 2004 + * Copyright (C) Sumit Bose, 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * TODO: + * - use str_list_copy to work on a either space or comma-separated list + * - assure somehow that we cannot swap uids/gids (difficult without any + * knowledge about the sid-type) + * - fix memory allocation + * - further cleanup + * - add spnego-login + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_IDMAP + +NTSTATUS init_module(void); + +struct dom_entry { + char *name; + char *sid; + int min_id; + int max_id; +}; + +typedef struct trust_dom_array { + int number; + struct dom_entry *dom; +} trust_dom_array; + +static trust_dom_array trust; + +static NTSTATUS rid_idmap_parse(char *init_param, + uint32 num_domains, + char **domain_names, + DOM_SID *domain_sids, + uid_t u_low, + uid_t u_high) +{ + char *p, *e; + int i; + trust.number = 0; + trust.dom = NULL; + fstring sid_str; + BOOL known_domain = False; + p = init_param; + + /* init sizes */ + trust.dom = (struct dom_entry *) malloc(sizeof(struct dom_entry)); + if (trust.dom == NULL) + return NT_STATUS_NO_MEMORY; + + trust.dom[0].sid = (char *) malloc(strlen(sid_str)); + if (trust.dom[0].sid == NULL) + return NT_STATUS_NO_MEMORY; + + trust.dom[0].name = (char *) malloc(strlen(p)); + if (trust.dom[0].name == NULL) + return NT_STATUS_NO_MEMORY; + + /* falling back to automatic mapping when there were no options given */ + if (!*init_param) { + + DEBUG(3,("rid_idmap_parse: no domain list given, falling back to automatic mapping for own domain:\n")); + + sid_to_string(sid_str, &domain_sids[num_domains-1]); + trust.dom[0].name = domain_names[num_domains-1]; + trust.dom[0].sid = strdup(sid_str); + trust.dom[0].min_id = u_low; + trust.dom[0].max_id = u_high; + trust.number = 1; + DEBUGADD(3,("rid_idmap_parse:\tdomain: [%s], sid: [%s], range=[%d-%d]\n", + trust.dom[0].name, trust.dom[0].sid, trust.dom[0].min_id, trust.dom[0].max_id)); + return NT_STATUS_OK; + } + + /* scan through the init_param-list */ + for(;;) { + + DEBUG(3,("rid_idmap_parse: parsing entry: %d\n", trust.number)); + + /* reinit sizes */ + trust.dom = (struct dom_entry *) realloc(trust.dom,sizeof(struct dom_entry)*(trust.number+1)); + if ( trust.dom == NULL ) + return NT_STATUS_NO_MEMORY; + + trust.dom[trust.number].sid = (char *) malloc(strlen(p)); + trust.dom[trust.number].name = (char *) malloc(strlen(p)); + if (trust.dom[trust.number].sid == NULL || trust.dom[trust.number].name == NULL) + return NT_STATUS_NO_MEMORY; + + + if ( (e = strchr(p,'=')) == NULL ) { + DEBUG(0, ("rid_idmap_parse: no '=' sign found in domain list [%s]\n", init_param)); + return NT_STATUS_INVALID_PARAMETER; + } + *e = '\0'; + + /* add the name */ + i=0; + do { + if ( *p != ' ' && *p != '\t' ) { + trust.dom[trust.number].name[i++] = *p; + } + p++; + } while(*p); + + trust.dom[trust.number].name[i++] = '\0'; + DEBUGADD(3,("rid_idmap_parse:\tentry %d has name: [%s]\n", trust.number, trust.dom[trust.number].name)); + + /* add the domain-sid */ + for (i=0; i trust.dom[i].max_id) { + DEBUG(0, ("rid_idmap_init: min_id has to be smaller than max_id for %s\n",trust.dom[i].name)); + return NT_STATUS_INVALID_PARAMETER; + } + if (trust.dom[i].min_id < u_low || trust.dom[i].max_id > u_high) { + DEBUG(0, ("rid_idmap_init: mapping of domain %s (%d-%d) has to fit into global idmap range (%d-%d).\n", + trust.dom[i].name, trust.dom[i].min_id, trust.dom[i].max_id, u_low, u_high)); + return NT_STATUS_INVALID_PARAMETER; + } + } + + /* check for overlaps */ + for(i=0;i= unid.uid ) + break; + } + + if (i == trust.number) { + DEBUG(0,("no range found for uid: %d\n",unid.uid)); + return NT_STATUS_NOT_IMPLEMENTED; + } + + /* use lower-end of idmap-range as offset for users and groups*/ + (unsigned long)unid.uid -= trust.dom[i].min_id; + + string_to_sid(&sidstr,trust.dom[i].sid); + sid_copy(sid, &sidstr); + if (!sid_append_rid( sid, (unsigned long)unid.uid )) { + DEBUG(0,("rid_idmap_get_sid_from_id: could not append rid to domain sid\n")); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(3, ("rid_idmap_get_sid_from_id: mapped POSIX %s %d to SID [%s]\n", + (id_type == ID_GROUPID) ? "GID" : "UID", unid.uid, + sid_to_string(sid_string, sid))); + + return NT_STATUS_OK; +} + +static NTSTATUS rid_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_SID *sid) +{ + fstring sid_string; + int i; + uint32 rid; + DOM_SID sidstr; + + if (unid == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* check if we have a mapping for the sid*/ + for(i=0;iuid = rid + trust.dom[i].min_id; + + if (unid->uid > trust.dom[i].max_id) { + DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d too high for mapping of domain: %s\n", rid, trust.dom[i].name)); + return NT_STATUS_INVALID_PARAMETER; + } + if (unid->uid < trust.dom[i].min_id) { + DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d too low for mapping of domain: %s\n", rid, trust.dom[i].name)); + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG(3,("rid_idmap_get_id_from_sid: mapped SID [%s] to POSIX %s %d\n", + sid_to_string(sid_string, sid), + (*id_type == ID_GROUPID) ? "GID" : "UID", unid->uid)); + + return NT_STATUS_OK; + +} + +static NTSTATUS rid_idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS rid_idmap_close(void) +{ + int i; + for(i=0;i