1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-05 20:58:40 +03:00

THE Idmap patch :-)

includes a --with-idmap=no switch to disable idmap usage if you find
problems.

cosmetic fixes and param aliases to separate winbind from idamp roles.

A temporarily remote idmap winbind compatibility backend.
As I have time I will further change code to not call directly winbind
(partly done but not tested) and a specilized module will be built in place
for the current glue hack.

The patch has been tested locally in my limited time, the patch is simple and
clear and should not reserve problems, if any just disable it.

As usual, comments and fisex are welcome :-)

Simo.
This commit is contained in:
Simo Sorce -
parent d84a3fc522
commit 0278132047
17 changed files with 405 additions and 164 deletions

View File

@ -279,6 +279,8 @@ DEVEL_HELP_OBJ = modules/developer.o
SAM_STATIC_MODULES = sam/sam_plugin.o sam/sam_skel.o sam/sam_ads.o
IDMAP_OBJ = sam/idmap.o sam/idmap_tdb.o sam/idmap_winbind.o
SAM_OBJ = sam/account.o sam/get_set_account.o sam/get_set_group.o \
sam/get_set_domain.o sam/interface.o $(SAM_STATIC_MODULES)
@ -336,7 +338,8 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ)
$(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(IDMAP_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
@ -401,14 +404,15 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
$(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ)
$(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \
$(IDMAP_OBJ)
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
$(POPT_LIB_OBJ)
$(POPT_LIB_OBJ) $(IDMAP_OBJ)
SMBGROUPEDIT_OBJ = utils/smbgroupedit.o $(GROUPDB_OBJ) $(PARAM_OBJ) \
$(LIBSAMBA_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
$(LIBSAMBA_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(IDMAP_OBJ)
RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
@ -420,7 +424,8 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
$(IDMAP_OBJ)
PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
@ -467,7 +472,8 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ)
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
$(IDMAP_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ) $(KRBCLIENT_OBJ)
@ -544,7 +550,8 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ)
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
$(IDMAP_OBJ)
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \
$(LIB_OBJ) $(NSSWINS_OBJ)
@ -936,7 +943,7 @@ nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ)
bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @BUILD_POPT@
@$(LINK) -o $@ $(WINBINDD_OBJ) $(IDMAP_OBJ) $(DYNEXP) $(LIBS) @BUILD_POPT@
nsswitch/libns_winbind.@SHLIBEXT@: $(WINBIND_NSS_PICOBJS)
@echo "Linking $@"

View File

@ -2442,6 +2442,27 @@ AC_ARG_WITH(ldapsam,
AC_MSG_RESULT(no)
)
#################################################
# check for IDMAP
AC_DEFINE(WITH_IDMAP,1, [Include IDMAP support])
AC_MSG_CHECKING(whether to use IDMAP only for [ug]id mapping)
AC_ARG_WITH(idmap,
[ --with-idmap Include experimental IDMAP support (default=yes)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(WITH_IDMAP,1,[Whether to include experimental IDMAP support])
;;
no)
AC_MSG_RESULT(no)
AC_DEFINE(WITH_IDMAP,0,[Whether to include experimental IDMAP support])
;;
esac ],
AC_MSG_RESULT(yes)
)
########################################################################################
##
## END OF TESTS FOR SAM BACKENDS.

View File

@ -44,7 +44,7 @@ struct idmap_methods {
NTSTATUS (*init)(const char *init_str);
NTSTATUS (*get_sid_from_id)(DOM_SID *sid, unid_t id, int id_type);
NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, DOM_SID *sid);
NTSTATUS (*get_id_from_sid)(unid_t *id, int *id_type, const DOM_SID *sid);
NTSTATUS (*set_mapping)(DOM_SID *sid, unid_t id, int id_type);
/* Called when backend is unloaded */

View File

@ -798,6 +798,8 @@ extern int errno;
#include "gums.h"
#include "idmap.h"
#include "session.h"
#include "asn_1.h"

View File

@ -339,7 +339,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
goto err;
}
if (!lp_winbind_gid(&gid_low, &gid_high)) {
if (!lp_idmap_gid(&gid_low, &gid_high)) {
DEBUG(4, ("winbind gid range not configured, therefore %s cannot be a winbind group\n", gname));
goto err;
}

View File

@ -203,7 +203,7 @@ typedef struct {
} CLI_POLICY_HND;
/* Filled out by IDMAP backends */
struct idmap_methods {
struct winbindd_idmap_methods {
/* Called when backend is first loaded */
BOOL (*init)(void);

View File

@ -24,33 +24,33 @@
static struct {
const char *name;
/* Function to create a member of the idmap_methods list */
BOOL (*reg_meth)(struct idmap_methods **methods);
struct idmap_methods *methods;
} builtin_idmap_functions[] = {
BOOL (*reg_meth)(struct winbindd_idmap_methods **methods);
struct winbindd_idmap_methods *methods;
} builtin_winbindd_idmap_functions[] = {
{ "tdb", winbind_idmap_reg_tdb, NULL },
/* { "ldap", winbind_idmap_reg_ldap, NULL },*/
{ NULL, NULL, NULL }
};
/* singleton pattern: uberlazy evaluation */
static struct idmap_methods *impl;
static struct winbindd_idmap_methods *impl;
static struct idmap_methods *get_impl(const char *name)
static struct winbindd_idmap_methods *get_impl(const char *name)
{
int i = 0;
struct idmap_methods *ret = NULL;
struct winbindd_idmap_methods *ret = NULL;
while (builtin_idmap_functions[i].name &&
strcmp(builtin_idmap_functions[i].name, name)) {
while (builtin_winbindd_idmap_functions[i].name &&
strcmp(builtin_winbindd_idmap_functions[i].name, name)) {
i++;
}
if (builtin_idmap_functions[i].name) {
if (!builtin_idmap_functions[i].methods) {
builtin_idmap_functions[i].reg_meth(&builtin_idmap_functions[i].methods);
if (builtin_winbindd_idmap_functions[i].name) {
if (!builtin_winbindd_idmap_functions[i].methods) {
builtin_winbindd_idmap_functions[i].reg_meth(&builtin_winbindd_idmap_functions[i].methods);
}
ret = builtin_idmap_functions[i].methods;
ret = builtin_winbindd_idmap_functions[i].methods;
}
return ret;
@ -62,13 +62,13 @@ BOOL winbindd_idmap_init(void)
BOOL ret = False;
DEBUG(3, ("winbindd_idmap_init: using '%s' as backend\n",
lp_idmap_backend()));
lp_winbind_backend()));
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
if (!impl) {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
}
@ -87,10 +87,10 @@ BOOL winbindd_idmap_get_uid_from_sid(DOM_SID *sid, uid_t *uid)
BOOL ret = False;
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
if (!impl) {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
}
@ -107,10 +107,10 @@ BOOL winbindd_idmap_get_gid_from_sid(DOM_SID *sid, gid_t *gid)
BOOL ret = False;
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
if (!impl) {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
}
@ -127,10 +127,10 @@ BOOL winbindd_idmap_get_sid_from_uid(uid_t uid, DOM_SID *sid)
BOOL ret = False;
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
if (!impl) {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
}
@ -147,14 +147,14 @@ BOOL winbindd_idmap_get_sid_from_gid(gid_t gid, DOM_SID *sid)
BOOL ret = False;
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
}
if (impl) {
ret = impl->get_sid_from_gid(gid, sid);
} else {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
return ret;
@ -166,14 +166,14 @@ BOOL winbindd_idmap_close(void)
BOOL ret = False;
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
}
if (impl) {
ret = impl->close();
} else {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
return ret;
@ -183,14 +183,13 @@ BOOL winbindd_idmap_close(void)
void winbindd_idmap_status(void)
{
if (!impl) {
impl = get_impl(lp_idmap_backend());
impl = get_impl(lp_winbind_backend());
}
if (impl) {
impl->status();
} else {
DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n",
lp_idmap_backend()));
lp_winbind_backend()));
}
}

View File

@ -419,7 +419,7 @@ static void tdb_idmap_status(void)
/* Display complete mapping of users and groups to rids */
}
struct idmap_methods tdb_idmap_methods = {
struct winbindd_idmap_methods tdb_idmap_methods = {
tdb_idmap_init,
tdb_get_sid_from_uid,
@ -433,7 +433,7 @@ struct idmap_methods tdb_idmap_methods = {
tdb_idmap_status
};
BOOL winbind_idmap_reg_tdb(struct idmap_methods **meth)
BOOL winbind_idmap_reg_tdb(struct winbindd_idmap_methods **meth)
{
*meth = &tdb_idmap_methods;

View File

@ -380,12 +380,12 @@ BOOL winbindd_param_init(void)
{
/* Parse winbind uid and winbind_gid parameters */
if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) {
DEBUG(0, ("winbind uid range missing or invalid\n"));
return False;
}
if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) {
DEBUG(0, ("winbind gid range missing or invalid\n"));
return False;
}

View File

@ -162,8 +162,8 @@ typedef struct
BOOL bUtmp;
#endif
char *szSourceEnv;
char *szWinbindUID;
char *szWinbindGID;
char *szIdmapUID;
char *szIdmapGID;
char *szNonUnixAccountRange;
int AlgorithmicRidBase;
char *szTemplateHomedir;
@ -172,7 +172,8 @@ typedef struct
BOOL bWinbindEnumUsers;
BOOL bWinbindEnumGroups;
BOOL bWinbindUseDefaultDomain;
char *szIDMapBackend;
char *szWinbindBackend;
char *szIdmapBackend;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
@ -551,8 +552,8 @@ static BOOL handle_include(const char *pszParmValue, char **ptr);
static BOOL handle_copy(const char *pszParmValue, char **ptr);
static BOOL handle_source_env(const char *pszParmValue, char **ptr);
static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr);
static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr);
static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
static BOOL handle_debug_list( const char *pszParmValue, char **ptr );
static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
@ -751,7 +752,7 @@ static struct parm_struct parm_table[] = {
{"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
@ -1116,8 +1117,10 @@ static struct parm_struct parm_table[] = {
{"Winbind options", P_SEP, P_SEPARATOR},
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
{"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
{"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@ -1125,6 +1128,7 @@ static struct parm_struct parm_table[] = {
{"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind backend", P_STRING, P_GLOBAL, &Globals.szWinbindBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
@ -1469,7 +1473,7 @@ static void init_globals(void)
Globals.bWinbindEnumGroups = True;
Globals.bWinbindUseDefaultDomain = False;
string_set(&Globals.szIDMapBackend, "tdb");
string_set(&Globals.szWinbindBackend, "tdb");
Globals.name_cache_timeout = 660; /* In seconds */
@ -1646,7 +1650,9 @@ FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
FN_GLOBAL_STRING(lp_winbind_backend, &Globals.szWinbindBackend)
FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
#ifdef WITH_LDAP_SAMCONFIG
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
@ -2804,49 +2810,49 @@ static BOOL handle_copy(const char *pszParmValue, char **ptr)
}
/***************************************************************************
Handle winbind/non unix account uid and gid allocation parameters. The format of these
Handle idmap/non unix account uid and gid allocation parameters. The format of these
parameters is:
[global]
winbind uid = 1000-1999
winbind gid = 700-899
idmap uid = 1000-1999
idmap gid = 700-899
We only do simple parsing checks here. The strings are parsed into useful
structures in the winbind daemon code.
structures in the idmap daemon code.
***************************************************************************/
/* Some lp_ routines to return winbind [ug]id information */
/* Some lp_ routines to return idmap [ug]id information */
static uid_t winbind_uid_low, winbind_uid_high;
static gid_t winbind_gid_low, winbind_gid_high;
static uid_t idmap_uid_low, idmap_uid_high;
static gid_t idmap_gid_low, idmap_gid_high;
static uint32 non_unix_account_low, non_unix_account_high;
BOOL lp_winbind_uid(uid_t *low, uid_t *high)
BOOL lp_idmap_uid(uid_t *low, uid_t *high)
{
if (winbind_uid_low == 0 || winbind_uid_high == 0)
if (idmap_uid_low == 0 || idmap_uid_high == 0)
return False;
if (low)
*low = winbind_uid_low;
*low = idmap_uid_low;
if (high)
*high = winbind_uid_high;
*high = idmap_uid_high;
return True;
}
BOOL lp_winbind_gid(gid_t *low, gid_t *high)
BOOL lp_idmap_gid(gid_t *low, gid_t *high)
{
if (winbind_gid_low == 0 || winbind_gid_high == 0)
if (idmap_gid_low == 0 || idmap_gid_high == 0)
return False;
if (low)
*low = winbind_gid_low;
*low = idmap_gid_low;
if (high)
*high = winbind_gid_high;
*high = idmap_gid_high;
return True;
}
@ -2865,9 +2871,9 @@ BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
return True;
}
/* Do some simple checks on "winbind [ug]id" parameter values */
/* Do some simple checks on "idmap [ug]id" parameter values */
static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr)
{
uint32 low, high;
@ -2878,13 +2884,13 @@ static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
string_set(ptr, pszParmValue);
winbind_uid_low = low;
winbind_uid_high = high;
idmap_uid_low = low;
idmap_uid_high = high;
return True;
}
static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr)
{
uint32 low, high;
@ -2895,8 +2901,8 @@ static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
string_set(ptr, pszParmValue);
winbind_gid_low = low;
winbind_gid_high = high;
idmap_gid_low = low;
idmap_gid_high = high;
return True;
}

View File

@ -915,7 +915,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
struct sys_grent *grp;
struct passwd *pw;
gid_t winbind_gid_low, winbind_gid_high;
BOOL winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
/* local aliases */
/* we return the UNIX groups here. This seems to be the right */

View File

@ -112,7 +112,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
*prids=NULL;
*numgroups=0;
winbind_groups_exist = lp_winbind_gid(&winbind_gid_low, &winbind_gid_high);
winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n",

View File

@ -17,8 +17,7 @@
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.
*/
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
#include "includes.h"
@ -34,14 +33,13 @@ static struct {
} remote_idmap_functions[] = {
{ "tdb", idmap_reg_tdb, NULL },
/* { "ldap", idmap_reg_ldap, NULL },*/
{ "winbind", idmap_reg_winbind, NULL },
{ NULL, NULL, NULL }
};
static struct idmap_methods *local_cache;
static struct idmap_methods *remote_repo;
static struct idmap_methods *local_map;
static struct idmap_methods *remote_map;
static struct idmap_methods *get_methods(const char *name)
{
@ -64,48 +62,33 @@ static struct idmap_methods *get_methods(const char *name)
return ret;
}
/* Load idmap backend functions */
BOOL load_methods(void)
/* Initialize backend */
BOOL idmap_init(const char *remote_backend)
{
if (!local_cache) {
idmap_reg_tdb(&local_cache);
if (!local_map) {
idmap_reg_tdb(&local_map);
local_map->init("idmap.tdb");
}
if (!remote_repo && lp_idmap_backend()) {
DEBUG(3, ("load_methods: using '%s' as remote backend\n", lp_idmap_backend()));
if (!remote_map && remote_backend && *remote_backend != 0) {
DEBUG(3, ("load_methods: using '%s' as remote backend\n", remote_backend));
remote_repo = get_methods(lp_idmap_backend());
if (!remote_repo) {
DEBUG(0, ("load_methods: could not load remote backend '%s'\n", lp_idmap_backend()));
remote_map = get_methods(remote_backend);
if (!remote_map) {
DEBUG(0, ("load_methods: could not load remote backend '%s'\n", remote_backend));
return False;
}
remote_map->init("");
}
idmap_init();
return True;
}
/* Initialize backend */
NTSTATUS idmap_init(void)
NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
{
NTSTATUS ret;
ret = remote_repo->init("idmap.tdb");
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_init: init failed!\n"));
}
return ret;
}
static NTSTATUS idmap_set_mapping(DOM_SID *sid, unid_t id, int id_type)
{
NTSTATUS ret;
if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
ret = local_cache->set_mapping(sid, id, id_type);
ret = local_map->set_mapping(sid, id, id_type);
if (NT_STATUS_IS_ERR(ret)) {
DEBUG (0, ("idmap_set_mapping: Error, unable to modify local cache!\n"));
return ret;
@ -113,8 +96,8 @@ static NTSTATUS idmap_set_mapping(DOM_SID *sid, unid_t id, int id_type)
/* Being able to update the remote cache is seldomly right.
Generally this is a forbidden operation. */
if (!(id_type & ID_CACHE) && (remote_repo != NULL)) {
remote_repo->set_mapping(sid, id, id_type);
if (!(id_type & ID_CACHE) && (remote_map != NULL)) {
remote_map->set_mapping(sid, id, id_type);
if (NT_STATUS_IS_ERR(ret)) {
DEBUG (0, ("idmap_set_mapping: Error, unable to modify remote cache!\n"));
}
@ -124,23 +107,22 @@ static NTSTATUS idmap_set_mapping(DOM_SID *sid, unid_t id, int id_type)
}
/* Get ID from SID */
NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
{
NTSTATUS ret;
int loc_type;
if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
loc_type = *id_type;
if (remote_repo) { /* We have a central remote idmap */
if (remote_map) { /* We have a central remote idmap */
loc_type |= ID_NOMAP;
}
ret = local_cache->get_id_from_sid(id, &loc_type, sid);
ret = local_map->get_id_from_sid(id, &loc_type, sid);
if (NT_STATUS_IS_ERR(ret)) {
if (remote_repo) {
ret = remote_repo->get_id_from_sid(id, id_type, sid);
if (remote_map) {
ret = remote_map->get_id_from_sid(id, id_type, sid);
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_get_id_from_sid: error fetching id!\n"));
return ret;
} else {
loc_type |= ID_CACHE;
idmap_set_mapping(sid, *id, loc_type);
@ -159,18 +141,17 @@ NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
NTSTATUS ret;
int loc_type;
if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
loc_type = id_type;
if (remote_repo) {
if (remote_map) {
loc_type = id_type | ID_NOMAP;
}
ret = local_cache->get_sid_from_id(sid, id, loc_type);
ret = local_map->get_sid_from_id(sid, id, loc_type);
if (NT_STATUS_IS_ERR(ret)) {
if (remote_repo) {
ret = remote_repo->get_sid_from_id(sid, id, id_type);
if (remote_map) {
ret = remote_map->get_sid_from_id(sid, id, id_type);
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_get_sid_from_id: unable to fetch sid!\n"));
return ret;
} else {
loc_type |= ID_CACHE;
idmap_set_mapping(sid, id, loc_type);
@ -186,15 +167,13 @@ NTSTATUS idmap_close(void)
{
NTSTATUS ret;
if (!load_methods()) return NT_STATUS_UNSUCCESSFUL;
ret = local_cache->close();
ret = local_map->close();
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_close: failed to close local cache!\n"));
}
if (remote_repo) {
ret = remote_repo->close();
if (remote_map) {
ret = remote_map->close();
if (NT_STATUS_IS_ERR(ret)) {
DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n"));
}
@ -206,9 +185,7 @@ NTSTATUS idmap_close(void)
/* Dump backend status */
void idmap_status(void)
{
if (load_methods()) {
local_cache->status();
remote_repo->status();
}
local_map->status();
if (remote_map) remote_map->status();
}

View File

@ -37,7 +37,7 @@
/* Globals */
static TDB_CONTEXT *idmap_tdb;
struct idmap_state {
static struct idmap_state {
/* User and group id pool */
@ -183,7 +183,7 @@ static BOOL tdb_idmap_convert(const char *idmap_name)
#endif
/* Allocate either a user or group id from the pool */
static NTSTATUS tdb_allocate_id(unid_t *id, int id_type)
static NTSTATUS db_allocate_id(unid_t *id, int id_type)
{
int hwm;
@ -229,7 +229,7 @@ static NTSTATUS tdb_allocate_id(unid_t *id, int id_type)
}
/* Get a sid from an id */
static NTSTATUS tdb_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
TDB_DATA key, data;
fstring keystr;
@ -239,13 +239,13 @@ static NTSTATUS tdb_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
switch (id_type & ID_TYPEMASK) {
case ID_USERID:
slprintf(keystr, sizeof(keystr), "UID %d", id.uid);
break;
slprintf(keystr, sizeof(keystr), "UID %d", id.uid);
break;
case ID_GROUPID:
slprintf(keystr, sizeof(keystr), "GID %d", id.gid);
break;
slprintf(keystr, sizeof(keystr), "GID %d", id.gid);
break;
default:
return NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_UNSUCCESSFUL;
}
key.dptr = keystr;
@ -264,7 +264,7 @@ static NTSTATUS tdb_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
}
/* Get an id from a sid */
static NTSTATUS tdb_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
{
TDB_DATA data, key;
fstring keystr;
@ -288,7 +288,7 @@ static NTSTATUS tdb_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
/* Parse and return existing uid */
fstrcpy(scanstr, "UID %d");
if (sscanf(data.dptr, scanstr, (*id).uid) == 1) {
if (sscanf(data.dptr, scanstr, &((*id).uid)) == 1) {
/* uid ok? */
if (type == ID_EMPTY) {
*id_type = ID_USERID;
@ -302,7 +302,7 @@ static NTSTATUS tdb_get_id_from_sid(unid_t *id, int *id_type, DOM_SID *sid)
/* Parse and return existing gid */
fstrcpy(scanstr, "GID %d");
if (sscanf(data.dptr, scanstr, (*id).gid) == 1) {
if (sscanf(data.dptr, scanstr, &((*id).gid)) == 1) {
/* gid ok? */
if (type == ID_EMPTY) {
*id_type = ID_GROUPID;
@ -318,7 +318,7 @@ idok:
|| (*id_type & ID_TYPEMASK) == ID_GROUPID)) {
/* Allocate a new id for this sid */
ret = tdb_allocate_id(id, *id_type);
ret = db_allocate_id(id, *id_type);
if (NT_STATUS_IS_OK(ret)) {
fstring keystr2;
@ -332,11 +332,11 @@ idok:
data.dptr = keystr2;
data.dsize = strlen(keystr2) + 1;
if (tdb_store(idmap_tdb, key, data, TDB_INSERT) == -1) {
if (tdb_store(idmap_tdb, key, data, TDB_REPLACE) == -1) {
/* TODO: print tdb error !! */
return NT_STATUS_UNSUCCESSFUL;
}
if (tdb_store(idmap_tdb, data, key, TDB_INSERT) == -1) {
if (tdb_store(idmap_tdb, data, key, TDB_REPLACE) == -1) {
/* TODO: print tdb error !! */
return NT_STATUS_UNSUCCESSFUL;
}
@ -344,11 +344,11 @@ idok:
ret = NT_STATUS_OK;
}
}
return ret;
}
static NTSTATUS tdb_set_mapping(DOM_SID *sid, unid_t id, int id_type)
static NTSTATUS db_set_mapping(DOM_SID *sid, unid_t id, int id_type)
{
TDB_DATA ksid, kid;
fstring ksidstr;
@ -387,7 +387,7 @@ static NTSTATUS tdb_set_mapping(DOM_SID *sid, unid_t id, int id_type)
/*****************************************************************************
Initialise idmap database.
*****************************************************************************/
static NTSTATUS tdb_idmap_init(const char *db_name)
static NTSTATUS db_idmap_init(const char *db_name)
{
/* Open tdb cache */
if (!(idmap_tdb = tdb_open_log(lock_path(db_name), 0,
@ -425,7 +425,7 @@ static NTSTATUS tdb_idmap_init(const char *db_name)
}
/* Close the tdb */
static NTSTATUS tdb_idmap_close(void)
static NTSTATUS db_idmap_close(void)
{
if (idmap_tdb) {
if (tdb_close(idmap_tdb) == 0) {
@ -449,7 +449,7 @@ static NTSTATUS tdb_idmap_close(void)
#define DUMP_INFO 0
static void tdb_idmap_status(void)
static void db_idmap_status(void)
{
int user_hwm, group_hwm;
@ -506,20 +506,20 @@ static void tdb_idmap_status(void)
/* Display complete mapping of users and groups to rids */
}
struct idmap_methods tdb_idmap_methods = {
struct idmap_methods db_methods = {
tdb_idmap_init,
tdb_get_sid_from_id,
tdb_get_id_from_sid,
tdb_set_mapping,
tdb_idmap_close,
tdb_idmap_status
db_idmap_init,
db_get_sid_from_id,
db_get_id_from_sid,
db_set_mapping,
db_idmap_close,
db_idmap_status
};
NTSTATUS idmap_reg_tdb(struct idmap_methods **meth)
{
*meth = &tdb_idmap_methods;
*meth = &db_methods;
return NT_STATUS_OK;
}

108
source/sam/idmap_winbind.c Normal file
View File

@ -0,0 +1,108 @@
/*
Unix SMB/CIFS implementation.
idmap Winbind backend
Copyright (C) Simo Sorce 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
/* Get a sid from an id */
static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type) {
switch (id_type & ID_TYPEMASK) {
case ID_USERID:
if (winbind_uid_to_sid(sid, id.uid)) {
return NT_STATUS_OK;
}
break;
case ID_GROUPID:
if (winbind_gid_to_sid(sid, id.gid)) {
return NT_STATUS_OK;
}
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
return NT_STATUS_UNSUCCESSFUL;
}
/* Get an id from a sid */
static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid) {
switch (*id_type & ID_TYPEMASK) {
case ID_USERID:
if (winbind_sid_to_uid(&((*id).uid), sid)) {
return NT_STATUS_OK;
}
break;
case ID_GROUPID:
if (winbind_sid_to_gid(&((*id).gid), sid)) {
return NT_STATUS_OK;
}
break;
default:
if (winbind_sid_to_uid(&((*id).uid), sid) ||
winbind_sid_to_gid(&((*id).gid), sid)) {
return NT_STATUS_OK;
}
}
return NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS db_set_mapping(DOM_SID *sid, unid_t id, int id_type) {
return NT_STATUS_UNSUCCESSFUL;
}
/*****************************************************************************
Initialise idmap database.
*****************************************************************************/
static NTSTATUS db_init(const char *db_name) {
return NT_STATUS_OK;
}
/* Close the tdb */
static NTSTATUS db_close(void) {
return NT_STATUS_OK;
}
static void db_status(void) {
return;
}
struct idmap_methods winbind_methods = {
db_init,
db_get_sid_from_id,
db_get_id_from_sid,
db_set_mapping,
db_close,
db_status
};
NTSTATUS idmap_reg_winbind(struct idmap_methods **meth)
{
*meth = &winbind_methods;
return NT_STATUS_OK;
}

View File

@ -856,6 +856,9 @@ static BOOL init_structs(void )
if (!init_registry())
exit(1);
if (!idmap_init(lp_idmap_backend()))
exit(1);
if(!initialize_password_db(False))
exit(1);

View File

@ -722,6 +722,33 @@ static void store_gid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sid
DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
{
#ifdef WITH_IDMAP
unid_t id;
DEBUG(10,("uid_to_sid: uid = [%d]\n", uid));
id.uid = uid;
if (NT_STATUS_IS_OK(idmap_get_sid_from_id(psid, id, ID_USERID))) {
DEBUG(10, ("uid_to_sid: sid = [%s]\n", sid_string_static(psid)));
return psid;
}
/* If mapping is not found in idmap try with traditional method,
then stores the result in idmap.
We may add a switch in future to allow smooth migrations to
idmap-only db ---Simo */
become_root();
psid = local_uid_to_sid(psid, uid);
unbecome_root();
DEBUG(10,("uid_to_sid: algorithmic %u -> %s\n", (unsigned int)uid, sid_string_static(psid)));
if (psid)
idmap_set_mapping(psid, id, ID_USERID);
return psid;
#else
uid_t low, high;
enum SID_NAME_USE sidtype;
fstring sid;
@ -729,7 +756,7 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
if (fetch_sid_from_uid_cache(psid, &sidtype, uid))
return psid;
if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) {
if (lp_idmap_uid(&low, &high) && uid >= low && uid <= high) {
if (winbind_uid_to_sid(psid, uid)) {
DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
@ -751,6 +778,7 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
store_uid_sid_cache(psid, SID_NAME_USER, uid);
return psid;
#endif
}
/*****************************************************************
@ -761,6 +789,33 @@ DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
{
#ifdef WITH_IDMAP
unid_t id;
DEBUG(10,("gid_to_sid: gid = [%d]\n", gid));
id.gid = gid;
if (NT_STATUS_IS_OK(idmap_get_sid_from_id(psid, id, ID_GROUPID))) {
DEBUG(10, ("gid_to_sid: sid = [%s]\n", sid_string_static(psid)));
return psid;
}
/* If mapping is not found in idmap try with traditional method,
then stores the result in idmap.
We may add a switch in future to allow smooth migrations to
idmap-only db ---Simo */
become_root();
psid = local_gid_to_sid(psid, gid);
unbecome_root();
DEBUG(10,("gid_to_sid: algorithmic %u -> %s\n", (unsigned int)gid, sid_string_static(psid)));
if (psid)
idmap_set_mapping(psid, id, ID_GROUPID);
return psid;
#else
gid_t low, high;
enum SID_NAME_USE sidtype;
fstring sid;
@ -768,7 +823,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
if (fetch_sid_from_gid_cache(psid, &sidtype, gid))
return psid;
if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) {
if (lp_idmap_gid(&low, &high) && gid >= low && gid <= high) {
if (winbind_gid_to_sid(psid, gid)) {
DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
@ -789,6 +844,7 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid);
return psid;
#endif
}
/*****************************************************************
@ -800,6 +856,35 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
{
#ifdef WITH_IDMAP
unid_t id;
int type;
DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(psid)));
*sidtype = SID_NAME_USER;
type = ID_USERID;
if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, psid))) {
DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid));
*puid = id.uid;
return True;
}
if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
BOOL result;
become_root();
result = local_sid_to_uid(puid, psid, sidtype);
unbecome_root();
if (result) {
id.uid = *puid;
DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid));
idmap_set_mapping(psid, id, ID_USERID);
return True;
}
}
return False;
#else
fstring sid_str;
if (fetch_uid_from_cache(puid, psid, *sidtype))
@ -873,6 +958,7 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
store_uid_sid_cache(psid, *sidtype, *puid);
return True;
#endif
}
/*****************************************************************
@ -884,6 +970,37 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype)
BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
{
#ifdef WITH_IDMAP
unid_t id;
int type;
DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(psid)));
*sidtype = SID_NAME_ALIAS;
type = ID_GROUPID;
if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, psid))) {
DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid));
*pgid = id.gid;
return True;
}
if (sid_compare_domain(get_global_sam_sid(), psid) == 0) {
BOOL result;
become_root();
result = local_sid_to_gid(pgid, psid, sidtype);
unbecome_root();
if (result) {
id.gid = *pgid;
DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid));
idmap_set_mapping(psid, id, ID_GROUPID);
return True;
}
}
return False;
#else
fstring dom_name, name, sid_str;
enum SID_NAME_USE name_type;
@ -944,5 +1061,6 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype)
store_gid_sid_cache(psid, *sidtype, *pgid);
return True;
#endif
}