1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-02 09:47:23 +03:00

idmap rewrite

(This used to be commit 30a180f2fce8cf6a3e5548f6bba453272ba70b33)
This commit is contained in:
Volker Lendecke 2008-07-13 12:07:40 +02:00
parent 8d4bd2d960
commit 340ab6a256
20 changed files with 708 additions and 1103 deletions

View File

@ -36,19 +36,15 @@
struct idmap_domain {
const char *name;
bool default_domain;
bool readonly;
void *private_data;
struct idmap_methods *methods;
bool initialized;
const char *params;
void *private_data;
};
/* Filled out by IDMAP backends */
struct idmap_methods {
/* Called when backend is first loaded */
NTSTATUS (*init)(struct idmap_domain *dom);
NTSTATUS (*init)(struct idmap_domain *dom, const char *params);
/* Map an array of uids/gids to SIDs. The caller specifies
the uid/gid and type. Gets back the SID. */

View File

@ -194,8 +194,7 @@ struct global {
bool bWinbindOfflineLogon;
bool bWinbindNormalizeNames;
bool bWinbindRpcOnly;
char **szIdmapDomains;
char **szIdmapBackend; /* deprecated */
char *szIdmapBackend;
char *szIdmapAllocBackend;
char *szAddShareCommand;
char *szChangeShareCommand;
@ -4255,18 +4254,9 @@ static struct parm_struct parm_table[] = {
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
{
.label = "idmap domains",
.type = P_LIST,
.p_class = P_GLOBAL,
.ptr = &Globals.szIdmapDomains,
.special = NULL,
.enum_list = NULL,
.flags = FLAG_ADVANCED,
},
{
.label = "idmap backend",
.type = P_LIST,
.type = P_STRING,
.p_class = P_GLOBAL,
.ptr = &Globals.szIdmapBackend,
.special = NULL,
@ -4825,6 +4815,7 @@ static void init_globals(bool first_time_only)
Globals.bKernelOplocks = True;
Globals.bAllowTrustedDomains = True;
string_set(&Globals.szIdmapBackend, "tdb");
string_set(&Globals.szTemplateShell, "/bin/false");
string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
@ -5091,8 +5082,7 @@ FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)

File diff suppressed because it is too large Load Diff

View File

@ -160,7 +160,8 @@ static ADS_STRUCT *ad_idmap_cached_connection(void)
/************************************************************************
***********************************************************************/
static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
const char *params)
{
struct idmap_ad_context *ctx;
char *config_option;
@ -206,7 +207,6 @@ static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom)
}
dom->private_data = ctx;
dom->initialized = True;
talloc_free(config_option);
@ -277,14 +277,6 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
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 ) {
@ -496,14 +488,6 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
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 ) {

View File

@ -59,7 +59,7 @@ bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
char *key;
char *value;
time_t timeout;
bool ret;
bool ret = true;
key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
if (key == NULL) {
@ -71,7 +71,9 @@ bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
return false;
}
ZERO_STRUCTP(sid);
ret = string_to_sid(sid, value);
if (value[0] != '-') {
ret = string_to_sid(sid, value);
}
SAFE_FREE(value);
if (ret) {
*expired = (timeout <= time(NULL));
@ -96,10 +98,15 @@ void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid)
}
if (uid != -1) {
fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid);
sid_to_fstring(value, sid);
timeout = is_null_sid(sid)
? lp_idmap_negative_cache_time()
: lp_idmap_cache_time();
if (is_null_sid(sid)) {
/* negative uid mapping */
fstrcpy(value, "-");
timeout = lp_idmap_negative_cache_time();
}
else {
sid_to_fstring(value, sid);
timeout = lp_idmap_cache_time();
}
gencache_set(key, value, now + timeout);
}
}
@ -140,7 +147,7 @@ bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
char *key;
char *value;
time_t timeout;
bool ret;
bool ret = true;
key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
if (key == NULL) {
@ -152,7 +159,9 @@ bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
return false;
}
ZERO_STRUCTP(sid);
ret = string_to_sid(sid, value);
if (value[0] != '-') {
ret = string_to_sid(sid, value);
}
SAFE_FREE(value);
if (ret) {
*expired = (timeout <= time(NULL));
@ -177,10 +186,15 @@ void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
}
if (gid != -1) {
fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid);
sid_to_fstring(value, sid);
timeout = is_null_sid(sid)
? lp_idmap_negative_cache_time()
: lp_idmap_cache_time();
if (is_null_sid(sid)) {
/* negative gid mapping */
fstrcpy(value, "-");
timeout = lp_idmap_negative_cache_time();
}
else {
sid_to_fstring(value, sid);
timeout = lp_idmap_cache_time();
}
gencache_set(key, value, now + timeout);
}
}

View File

@ -33,6 +33,29 @@
#include "smbldap.h"
static char *idmap_fetch_secret(const char *backend, bool alloc,
const char *domain, const char *identity)
{
char *tmp, *ret;
int r;
if (alloc) {
r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend);
} else {
r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain);
}
if (r < 0)
return NULL;
strupper_m(tmp); /* make sure the key is case insensitive */
ret = secrets_fetch_generic(tmp, identity);
SAFE_FREE(tmp);
return ret;
}
struct idmap_ldap_context {
struct smbldap_state *smbldap_state;
char *url;
@ -760,7 +783,8 @@ static int idmap_ldap_close_destructor(struct idmap_ldap_context *ctx)
Initialise idmap database.
********************************/
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom,
const char *params)
{
NTSTATUS ret;
struct idmap_ldap_context *ctx = NULL;
@ -798,9 +822,9 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
}
}
if (dom->params && *(dom->params)) {
if (params != NULL) {
/* assume location is the only parameter */
ctx->url = talloc_strdup(ctx, dom->params);
ctx->url = talloc_strdup(ctx, params);
} else {
tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL);
@ -848,7 +872,6 @@ static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom)
talloc_set_destructor(ctx, idmap_ldap_close_destructor);
dom->private_data = ctx;
dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@ -909,14 +932,6 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
/* Initilization my have been deferred because we were offline */
if ( ! dom->initialized) {
ret = idmap_ldap_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
@ -1138,14 +1153,6 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
/* Initilization my have been deferred because we were offline */
if ( ! dom->initialized) {
ret = idmap_ldap_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
memctx = talloc_new(ctx);
@ -1350,14 +1357,6 @@ static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,
return NT_STATUS_FILE_IS_OFFLINE;
}
/* Initilization my have been deferred because we were offline */
if ( ! dom->initialized) {
ret = idmap_ldap_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);
switch(map->xid.type) {

View File

@ -29,9 +29,9 @@
Initialise idmap database.
*****************************/
static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom)
static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
const char *params)
{
dom->initialized = True;
return NT_STATUS_OK;
}
@ -44,10 +44,6 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
if (! dom->initialized) {
return NT_STATUS_UNSUCCESSFUL;
}
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
@ -134,10 +130,6 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma
TALLOC_CTX *ctx;
int i;
if (! dom->initialized) {
return NT_STATUS_UNSUCCESSFUL;
}
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));

View File

@ -28,9 +28,8 @@
Initialise idmap database.
*****************************/
static NTSTATUS idmap_pdb_init(struct idmap_domain *dom)
static NTSTATUS idmap_pdb_init(struct idmap_domain *dom, const char *params)
{
dom->initialized = True;
return NT_STATUS_OK;
}
@ -42,10 +41,6 @@ static NTSTATUS idmap_pdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
{
int i;
if (! dom->initialized) {
return NT_STATUS_UNSUCCESSFUL;
}
for (i = 0; ids[i]; i++) {
/* unmapped by default */
@ -78,10 +73,6 @@ static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
{
int i;
if (! dom->initialized) {
return NT_STATUS_UNSUCCESSFUL;
}
for (i = 0; ids[i]; i++) {
enum lsa_SidType type;
union unid_t id;

View File

@ -36,7 +36,8 @@ struct idmap_rid_context {
we support multiple domains in the new idmap
*****************************************************************************/
static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom,
const char *params)
{
NTSTATUS ret;
struct idmap_rid_context *ctx;
@ -95,7 +96,6 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom)
ctx->domain_name = talloc_strdup( ctx, dom->name );
dom->private_data = ctx;
dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@ -171,14 +171,6 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
/* Initilization my have been deferred because of an error, retry or fail */
if ( ! dom->initialized) {
ret = idmap_rid_initialize(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
@ -213,14 +205,6 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
/* Initilization my have been deferred because of an error, retry or fail */
if ( ! dom->initialized) {
ret = idmap_rid_initialize(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);

View File

@ -585,7 +585,7 @@ struct idmap_tdb_context {
Initialise idmap database.
*****************************/
static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
{
NTSTATUS ret;
struct idmap_tdb_context *ctx;
@ -619,7 +619,6 @@ static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom)
}
dom->private_data = ctx;
dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@ -774,14 +773,6 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
@ -820,14 +811,6 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma
NTSTATUS ret;
int i;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
@ -868,14 +851,6 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
char *ksidstr, *kidstr;
fstring tmp;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}
@ -983,14 +958,6 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
char *ksidstr, *kidstr;
fstring tmp;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}
@ -1171,14 +1138,6 @@ static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **ma
struct dump_data *data;
NTSTATUS ret = NT_STATUS_OK;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
data = TALLOC_ZERO_P(ctx, struct dump_data);
@ -1229,6 +1188,8 @@ NTSTATUS idmap_tdb_init(void)
{
NTSTATUS ret;
DEBUG(10, ("calling idmap_tdb_init\n"));
/* FIXME: bad hack to actually register also the alloc_tdb module without changining configure.in */
ret = idmap_alloc_tdb_init();
if (! NT_STATUS_IS_OK(ret)) {

View File

@ -431,7 +431,8 @@ static NTSTATUS tdb2_delete_bystring(const char *keystr)
/*
Initialise idmap database.
*/
static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
const char *params)
{
NTSTATUS ret;
struct idmap_tdb2_context *ctx;
@ -464,7 +465,6 @@ static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)
}
dom->private_data = ctx;
dom->initialized = True;
talloc_free(config_option);
return NT_STATUS_OK;
@ -725,14 +725,6 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb2_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
@ -770,14 +762,6 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m
NTSTATUS ret;
int i;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb2_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
@ -819,14 +803,6 @@ static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id
struct db_record *update_lock = NULL;
struct db_record *rec = NULL;
/* make sure we initialized */
if ( ! dom->initialized) {
ret = idmap_tdb2_db_init(dom);
if ( ! NT_STATUS_IS_OK(ret)) {
return ret;
}
}
if (!map || !map->sid) {
return NT_STATUS_INVALID_PARAMETER;
}

View File

@ -27,28 +27,50 @@
If mapping is not possible returns an error.
*****************************************************************/
NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
{
NTSTATUS ret;
struct id_map map;
bool expired;
DEBUG(10,("uid = [%lu]\n", (unsigned long)uid));
if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
expired ? " (expired)": ""));
if (expired && idmap_is_online()) {
DEBUG(10, ("revalidating expired entry\n"));
goto backend;
}
if (is_null_sid(sid)) {
DEBUG(10, ("Returning negative cache entry\n"));
return NT_STATUS_NONE_MAPPED;
}
DEBUG(10, ("Returning positive cache entry\n"));
return NT_STATUS_OK;
}
backend:
map.sid = sid;
map.xid.type = ID_TYPE_UID;
map.xid.id = uid;
ret = idmap_backends_unixid_to_sid(&map);
ret = idmap_backends_unixid_to_sid(domname, &map);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid));
return ret;
}
if (map.status != ID_MAPPED) {
struct dom_sid null_sid;
ZERO_STRUCT(null_sid);
idmap_cache_set_sid2uid(&null_sid, uid);
DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid));
return NT_STATUS_NONE_MAPPED;
}
idmap_cache_set_sid2uid(sid, uid);
return NT_STATUS_OK;
}
@ -57,28 +79,50 @@ NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
If mapping is not possible returns an error.
*****************************************************************/
NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
{
NTSTATUS ret;
struct id_map map;
bool expired;
DEBUG(10,("gid = [%lu]\n", (unsigned long)gid));
if (idmap_cache_find_uid2sid(gid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
expired ? " (expired)": ""));
if (expired && idmap_is_online()) {
DEBUG(10, ("revalidating expired entry\n"));
goto backend;
}
if (is_null_sid(sid)) {
DEBUG(10, ("Returning negative cache entry\n"));
return NT_STATUS_NONE_MAPPED;
}
DEBUG(10, ("Returning positive cache entry\n"));
return NT_STATUS_OK;
}
backend:
map.sid = sid;
map.xid.type = ID_TYPE_GID;
map.xid.id = gid;
ret = idmap_backends_unixid_to_sid(&map);
ret = idmap_backends_unixid_to_sid(domname, &map);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid));
return ret;
}
if (map.status != ID_MAPPED) {
struct dom_sid null_sid;
ZERO_STRUCT(null_sid);
idmap_cache_set_sid2uid(&null_sid, gid);
DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid));
return NT_STATUS_NONE_MAPPED;
}
idmap_cache_set_sid2uid(sid, gid);
return NT_STATUS_OK;
}
@ -87,34 +131,61 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
If mapping is not possible or SID maps to a GID returns an error.
*****************************************************************/
NTSTATUS idmap_sid_to_uid(DOM_SID *sid, uid_t *uid)
NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
{
NTSTATUS ret;
struct id_map map;
bool expired;
DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid)));
if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
(int)(*uid), expired ? " (expired)": ""));
if (expired && idmap_is_online()) {
DEBUG(10, ("revalidating expired entry\n"));
goto backend;
}
if ((*uid) == -1) {
DEBUG(10, ("Returning negative cache entry\n"));
return NT_STATUS_NONE_MAPPED;
}
DEBUG(10, ("Returning positive cache entry\n"));
return NT_STATUS_OK;
}
backend:
map.sid = sid;
map.xid.type = ID_TYPE_UID;
ret = idmap_backends_sid_to_unixid(&map);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping sid [%s] to uid\n",
sid_string_dbg(sid)));
ret = idmap_backends_sid_to_unixid(dom_name, &map);
if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
if (map.xid.type != ID_TYPE_UID) {
DEBUG(10, ("sid [%s] not mapped to a uid "
"[%u,%u,%u]\n",
sid_string_dbg(sid),
map.status,
map.xid.type,
map.xid.id));
idmap_cache_set_sid2uid(sid, -1);
return NT_STATUS_NONE_MAPPED;
}
goto done;
}
ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("idmap_new_mapping failed: %s\n",
nt_errstr(ret)));
idmap_cache_set_sid2uid(sid, -1);
return ret;
}
if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_UID)) {
DEBUG(10, ("sid [%s] not mapped to an uid [%u,%u,%u]\n",
sid_string_dbg(sid),
map.status,
map.xid.type,
map.xid.id));
return NT_STATUS_NONE_MAPPED;
}
*uid = map.xid.id;
done:
*uid = (uid_t)map.xid.id;
idmap_cache_set_sid2uid(sid, *uid);
return NT_STATUS_OK;
}
@ -123,32 +194,59 @@ NTSTATUS idmap_sid_to_uid(DOM_SID *sid, uid_t *uid)
If mapping is not possible or SID maps to a UID returns an error.
*****************************************************************/
NTSTATUS idmap_sid_to_gid(DOM_SID *sid, gid_t *gid)
NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
{
NTSTATUS ret;
struct id_map map;
bool expired;
DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid)));
if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
(int)(*gid), expired ? " (expired)": ""));
if (expired && idmap_is_online()) {
DEBUG(10, ("revalidating expired entry\n"));
goto backend;
}
if ((*gid) == -1) {
DEBUG(10, ("Returning negative cache entry\n"));
return NT_STATUS_NONE_MAPPED;
}
DEBUG(10, ("Returning positive cache entry\n"));
return NT_STATUS_OK;
}
backend:
map.sid = sid;
map.xid.type = ID_TYPE_GID;
ret = idmap_backends_sid_to_unixid(&map);
if ( ! NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("error mapping sid [%s] to gid\n",
sid_string_dbg(sid)));
ret = idmap_backends_sid_to_unixid(domname, &map);
if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {
if (map.xid.type != ID_TYPE_GID) {
DEBUG(10, ("sid [%s] not mapped to a gid "
"[%u,%u,%u]\n",
sid_string_dbg(sid),
map.status,
map.xid.type,
map.xid.id));
idmap_cache_set_sid2gid(sid, -1);
return NT_STATUS_NONE_MAPPED;
}
goto done;
}
ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(10, ("idmap_new_mapping failed: %s\n",
nt_errstr(ret)));
idmap_cache_set_sid2gid(sid, -1);
return ret;
}
if ((map.status != ID_MAPPED) || (map.xid.type != ID_TYPE_GID)) {
DEBUG(10, ("sid [%s] not mapped to a gid [%u,%u]\n",
sid_string_dbg(sid),
map.status,
map.xid.type));
return NT_STATUS_NONE_MAPPED;
}
done:
*gid = map.xid.id;
idmap_cache_set_sid2gid(sid, *gid);
return NT_STATUS_OK;
}

View File

@ -1144,12 +1144,6 @@ int main(int argc, char **argv, char **envp)
namecache_enable();
/* Winbind daemon initialisation */
if ( ! NT_STATUS_IS_OK(idmap_init_cache()) ) {
DEBUG(1, ("Could not init idmap cache!\n"));
}
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */

View File

@ -196,6 +196,13 @@ struct winbindd_domain {
void *private_data;
/*
* idmap config settings, used to tell the idmap child which
* special domain config to use for a mapping
*/
bool have_idmap_config;
uint32_t id_range_low, id_range_high;
/* A working DC */
fstring dcname;
struct sockaddr_storage dcaddr;

View File

@ -1033,6 +1033,8 @@ static bool fork_domain_child(struct winbindd_child *child)
/* Child */
DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
/* Stop zombies in children */
CatchChild();

View File

@ -231,7 +231,8 @@ static bool fill_grent_mem_domusers( TALLOC_CTX *mem_ctx,
if (sys_getpeereid(state->sock, &ret_uid)==0) {
/* We know who's asking - look up their SID if
it's one we've mapped before. */
status = idmap_uid_to_sid(&querying_user_sid, ret_uid);
status = idmap_uid_to_sid(domain->name,
&querying_user_sid, ret_uid);
if (NT_STATUS_IS_OK(status)) {
pquerying_user_sid = &querying_user_sid;
DEBUG(10,("fill_grent_mem_domain_users: "
@ -1224,7 +1225,8 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
sid_copy(&group_sid, &domain->sid);
sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &group_gid))) {
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(domain->name, &group_sid,
&group_gid))) {
union unid_t id;
enum lsa_SidType type;

View File

@ -197,8 +197,28 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
void *private_data)
{
struct winbindd_request request;
struct winbindd_domain *domain;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_SID2UID;
domain = find_domain_from_sid(sid);
if (domain != NULL) {
DEBUG(10, ("winbindd_sid2uid_async found domain %s, "
"have_idmap_config = %d\n", domain->name,
(int)domain->have_idmap_config));
}
else {
DEBUG(10, ("winbindd_sid2uid_async did not find a domain for "
"%s\n", sid_string_dbg(sid)));
}
if ((domain != NULL) && (domain->have_idmap_config)) {
fstrcpy(request.domain_name, domain->name);
}
sid_to_fstring(request.data.dual_sid2id.sid, sid);
do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv,
(void *)cont, private_data);
@ -219,9 +239,12 @@ enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
return WINBINDD_ERROR;
}
/* Find uid for this sid and return it, possibly ask the slow remote idmap */
result = idmap_sid_to_uid(state->request.domain_name, &sid,
&state->response.data.uid);
result = idmap_sid_to_uid(&sid, &(state->response.data.uid));
DEBUG(10, ("winbindd_dual_sid2uid: 0x%08x - %s - %u\n",
NT_STATUS_V(result), sid_string_dbg(&sid),
state->response.data.uid));
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
@ -253,8 +276,16 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
void *private_data)
{
struct winbindd_request request;
struct winbindd_domain *domain;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_SID2GID;
domain = find_domain_from_sid(sid);
if ((domain != NULL) && (domain->have_idmap_config)) {
fstrcpy(request.domain_name, domain->name);
}
sid_to_fstring(request.data.dual_sid2id.sid, sid);
DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
@ -281,7 +312,8 @@ enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
/* Find gid for this sid and return it, possibly ask the slow remote idmap */
result = idmap_sid_to_gid(&sid, &state->response.data.gid);
result = idmap_sid_to_gid(state->request.domain_name, &sid,
&state->response.data.gid);
DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n",
NT_STATUS_V(result), sid_string_dbg(&sid),
@ -319,11 +351,21 @@ void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
void (*cont)(void *private_data, bool success, const char *sid),
void *private_data)
{
struct winbindd_domain *domain;
struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_UID2SID;
request.data.uid = uid;
for (domain = domain_list(); domain != NULL; domain = domain->next) {
if (domain->have_idmap_config
&& (uid >= domain->id_range_low)
&& (uid <= domain->id_range_high)) {
fstrcpy(request.domain_name, domain->name);
}
}
do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv,
(void *)cont, private_data);
}
@ -339,7 +381,8 @@ enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
(unsigned long) state->request.data.uid));
/* Find sid for this uid and return it, possibly ask the slow remote idmap */
result = idmap_uid_to_sid(&sid, state->request.data.uid);
result = idmap_uid_to_sid(state->request.domain_name, &sid,
state->request.data.uid);
if (NT_STATUS_IS_OK(result)) {
sid_to_fstring(state->response.data.sid.sid, &sid);
@ -376,11 +419,21 @@ void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
void (*cont)(void *private_data, bool success, const char *sid),
void *private_data)
{
struct winbindd_domain *domain;
struct winbindd_request request;
ZERO_STRUCT(request);
request.cmd = WINBINDD_DUAL_GID2SID;
request.data.gid = gid;
for (domain = domain_list(); domain != NULL; domain = domain->next) {
if (domain->have_idmap_config
&& (gid >= domain->id_range_low)
&& (gid <= domain->id_range_high)) {
fstrcpy(request.domain_name, domain->name);
}
}
do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv,
(void *)cont, private_data);
}
@ -396,7 +449,8 @@ enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
(unsigned long) state->request.data.gid));
/* Find sid for this gid and return it, possibly ask the slow remote idmap */
result = idmap_gid_to_sid(&sid, state->request.data.gid);
result = idmap_gid_to_sid(state->request.domain_name, &sid,
state->request.data.gid);
if (NT_STATUS_IS_OK(result)) {
sid_to_fstring(state->response.data.sid.sid, &sid);

View File

@ -166,12 +166,10 @@ static void sid2uid_recv(void *private_data, bool success, uid_t uid)
if (!success) {
DEBUG(5, ("Could not convert sid %s\n",
state->request.data.sid));
idmap_cache_set_sid2uid(&sid, -1);
request_error(state);
return;
}
idmap_cache_set_sid2uid(&sid, uid);
state->response.data.uid = uid;
request_ok(state);
}
@ -209,6 +207,10 @@ static void sid2uid_lookupsid_recv( void *private_data, bool success,
return;
fail:
/*
* We have to set the cache ourselves here, the child which is
* normally responsible was not queried yet.
*/
idmap_cache_set_sid2uid(&sid, -1);
request_error(state);
return;
@ -273,12 +275,10 @@ static void sid2gid_recv(void *private_data, bool success, gid_t gid)
if (!success) {
DEBUG(5, ("Could not convert sid %s\n",
state->request.data.sid));
idmap_cache_set_sid2gid(&sid, -1);
request_error(state);
return;
}
idmap_cache_set_sid2gid(&sid, gid);
state->response.data.gid = gid;
request_ok(state);
}
@ -319,6 +319,10 @@ static void sid2gid_lookupsid_recv( void *private_data, bool success,
return;
fail:
/*
* We have to set the cache ourselves here, the child which is
* normally responsible was not queried yet.
*/
idmap_cache_set_sid2gid(&sid, -1);
request_error(state);
return;
@ -516,7 +520,7 @@ static void gid2sid_recv(void *private_data, bool success, const char *sidstr)
return;
}
DEBUG(10,("gid2sid: gid %lu has sid %s\n",
(unsigned long)(state->request.data.gid), sid));
(unsigned long)(state->request.data.gid), sidstr));
idmap_cache_set_sid2gid(&sid, state->request.data.gid);
fstrcpy(state->response.data.sid.sid, sidstr);

View File

@ -79,7 +79,8 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name,
/* Resolve the uid number */
if (!NT_STATUS_IS_OK(idmap_sid_to_uid(user_sid, &pw->pw_uid))) {
if (!NT_STATUS_IS_OK(idmap_sid_to_uid(dom_name, user_sid,
&pw->pw_uid))) {
DEBUG(1, ("error getting user id for sid %s\n",
sid_string_dbg(user_sid)));
return False;
@ -87,7 +88,8 @@ static bool winbindd_fill_pwent(char *dom_name, char *user_name,
/* Resolve the gid number */
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(group_sid, &pw->pw_gid))) {
if (!NT_STATUS_IS_OK(idmap_sid_to_gid(dom_name, group_sid,
&pw->pw_gid))) {
DEBUG(1, ("error getting group id for sid %s\n",
sid_string_dbg(group_sid)));
return False;

View File

@ -109,6 +109,8 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
{
struct winbindd_domain *domain;
const char *alternative_name = NULL;
char *idmap_config_option;
const char *param;
/* ignore alt_name if we are not in an AD domain */
@ -181,12 +183,44 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
if (sid) {
sid_copy(&domain->sid, sid);
}
/* Link to domain list */
DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *);
wcache_tdc_add_domain( domain );
idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
domain->name);
if (idmap_config_option == NULL) {
DEBUG(0, ("talloc failed, not looking for idmap config\n"));
goto done;
}
param = lp_parm_const_string(-1, idmap_config_option, "range", NULL);
DEBUG(10, ("%s : range = %s\n", idmap_config_option,
param ? param : "not defined"));
if (param != NULL) {
unsigned low_id, high_id;
if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) {
DEBUG(1, ("invalid range syntax in %s: %s\n",
idmap_config_option, param));
goto done;
}
if (low_id > high_id) {
DEBUG(1, ("invalid range in %s: %s\n",
idmap_config_option, param));
goto done;
}
domain->have_idmap_config = true;
domain->id_range_low = low_id;
domain->id_range_high = high_id;
}
done:
DEBUG(2,("Added domain %s %s %s\n",
domain->name, domain->alt_name,
&domain->sid?sid_string_dbg(&domain->sid):""));