diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd.c | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 49 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_idmap.c | 194 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_idmap_tdb.c | 459 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_sid.c | 25 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 28 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 9 |
7 files changed, 711 insertions, 58 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 1be5a18c7c..ff21a4644f 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -128,6 +128,7 @@ static void winbindd_status(void) static void print_winbindd_status(void) { winbindd_status(); + winbindd_idmap_status(); winbindd_cm_status(); } @@ -145,7 +146,7 @@ static void terminate(void) { pstring path; - idmap_close(); + winbindd_idmap_close(); /* Remove socket file */ snprintf(path, sizeof(path), "%s/%s", @@ -754,7 +755,7 @@ BOOL winbind_setup_common(void) /* Winbind daemon initialisation */ - if (!idmap_init()) + if (!winbindd_idmap_init()) return False; /* Unblock all signals we are interested in as they may have been diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 02114a3891..b3ded2a2f4 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -193,9 +193,8 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) enum SID_NAME_USE name_type; fstring name_domain, name_group; char *tmp, *gr_mem; + gid_t gid; int gr_mem_len; - unid_t id; - int id_type; /* Ensure null termination */ state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0'; @@ -211,6 +210,11 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) if (!parse_domain_user(tmp, name_domain, name_group)) return WINBINDD_ERROR; + /* fail if we are a PDC and this is our domain; should be done by passdb */ + + if ( lp_server_role() == ROLE_DOMAIN_PDC && 0==StrCaseCmp( domain->name, lp_workgroup()) ) + return WINBINDD_ERROR; + /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { @@ -234,14 +238,13 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, &group_sid))) { + if (!winbindd_idmap_get_gid_from_sid(&group_sid, &gid)) { DEBUG(1, ("error converting unix gid to sid\n")); return WINBINDD_ERROR; } if (!fill_grent(&state->response.data.gr, name_domain, - name_group, id.gid) || + name_group, gid) || !fill_grent_mem(domain, &group_sid, name_type, &state->response.data.gr.num_gr_mem, &gr_mem, &gr_mem_len)) { @@ -269,7 +272,6 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) fstring group_name; int gr_mem_len; char *gr_mem; - unid_t id; DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid, state->request.data.gid)); @@ -281,8 +283,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) return WINBINDD_ERROR; /* Get rid from gid */ - id.gid = state->request.data.gid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(&group_sid, id, ID_GROUPID))) { + + if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &group_sid)) { DEBUG(1, ("could not convert gid %d to rid\n", state->request.data.gid)); return WINBINDD_ERROR; @@ -408,6 +410,9 @@ static BOOL get_sam_group_entries(struct getent_state *ent) if (ent->got_sam_entries) return False; + + if ( lp_server_role() == ROLE_DOMAIN_PDC && 0==StrCaseCmp(lp_workgroup(), ent->domain_name)) + return False; if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)", ent->domain_name))) { @@ -547,8 +552,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) char *gr_mem, *new_gr_mem_list; DOM_SID group_sid; struct winbindd_domain *domain; - unid_t id; - int id_type; /* Do we need to fetch another chunk of groups? */ @@ -595,8 +598,9 @@ enum winbindd_result 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); - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, &group_sid))) { + if (!winbindd_idmap_get_gid_from_sid( + &group_sid, + &group_gid)) { DEBUG(1, ("could not look up gid for group %s\n", name_list[ent->sam_entry_index].acct_name)); @@ -604,7 +608,6 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) ent->sam_entry_index++; goto tryagain; } - group_gid = id.gid; DEBUG(10, ("got gid %d for group %x\n", group_gid, name_list[ent->sam_entry_index].rid)); @@ -746,6 +749,11 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) for (domain = domain_list(); domain; domain = domain->next) { struct getent_state groups; + + /* fail if we are a PDC and this is our domain; should be done by passdb */ + + if ( lp_server_role() == ROLE_DOMAIN_PDC && 0==StrCaseCmp( domain->name, lp_workgroup()) ) + continue; ZERO_STRUCT(groups); @@ -838,6 +846,11 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) name_user)) goto done; + /* fail if we are a PDC and this is our domain; should be done by passdb */ + + if ( lp_server_role() == ROLE_DOMAIN_PDC && 0==StrCaseCmp( name_domain, lp_workgroup()) ) + return WINBINDD_ERROR; + /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { @@ -874,18 +887,16 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - unid_t id; - int id_type; - - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, user_gids[i]))) { + if (!winbindd_idmap_get_gid_from_sid( + user_gids[i], + &gid_list[num_gids])) { fstring sid_string; DEBUG(1, ("unable to convert group sid %s to gid\n", sid_to_string(sid_string, user_gids[i]))); continue; } - gid_list[num_gids] = id.gid; + num_gids++; } diff --git a/source3/nsswitch/winbindd_idmap.c b/source3/nsswitch/winbindd_idmap.c new file mode 100644 index 0000000000..3b23089200 --- /dev/null +++ b/source3/nsswitch/winbindd_idmap.c @@ -0,0 +1,194 @@ +/* + Unix SMB/CIFS implementation. + Winbind ID Mapping + Copyright (C) Tim Potter 2000 + Copyright (C) Anthony Liguori <aliguor@us.ibm.com> 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 "winbindd.h" + +static struct { + const char *name; + /* Function to create a member of the idmap_methods list */ + BOOL (*reg_meth)(struct winbindd_idmap_methods **methods); + struct winbindd_idmap_methods *methods; +} builtin_winbindd_idmap_functions[] = { + { "tdb", winbind_idmap_reg_tdb, NULL }, + { NULL, NULL, NULL } +}; + +/* singleton pattern: uberlazy evaluation */ +static struct winbindd_idmap_methods *impl; + +static struct winbindd_idmap_methods *get_impl(const char *name) +{ + int i = 0; + struct winbindd_idmap_methods *ret = NULL; + + while (builtin_winbindd_idmap_functions[i].name && + strcmp(builtin_winbindd_idmap_functions[i].name, name)) { + i++; + } + + 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_winbindd_idmap_functions[i].methods; + } + + return ret; +} + +/* Initialize backend */ +BOOL winbindd_idmap_init(void) +{ + BOOL ret = False; + + DEBUG(3, ("winbindd_idmap_init: using '%s' as backend\n", + lp_winbind_backend())); + + if (!impl) { + impl = get_impl(lp_winbind_backend()); + if (!impl) { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } + } + + if (impl) { + ret = impl->init(); + } + + DEBUG(3, ("winbind_idmap_init: returning %s\n", ret ? "true" : "false")); + + return ret; +} + +/* Get UID from SID */ +BOOL winbindd_idmap_get_uid_from_sid(DOM_SID *sid, uid_t *uid) +{ + BOOL ret = False; + + if (!impl) { + impl = get_impl(lp_winbind_backend()); + if (!impl) { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } + } + + if (impl) { + ret = impl->get_uid_from_sid(sid, uid); + } + + return ret; +} + +/* Get GID from SID */ +BOOL winbindd_idmap_get_gid_from_sid(DOM_SID *sid, gid_t *gid) +{ + BOOL ret = False; + + if (!impl) { + impl = get_impl(lp_winbind_backend()); + if (!impl) { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } + } + + if (impl) { + ret = impl->get_gid_from_sid(sid, gid); + } + + return ret; +} + +/* Get SID from UID */ +BOOL winbindd_idmap_get_sid_from_uid(uid_t uid, DOM_SID *sid) +{ + BOOL ret = False; + + if (!impl) { + impl = get_impl(lp_winbind_backend()); + if (!impl) { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } + } + + if (impl) { + ret = impl->get_sid_from_uid(uid, sid); + } + + return ret; +} + +/* Get SID from GID */ +BOOL winbindd_idmap_get_sid_from_gid(gid_t gid, DOM_SID *sid) +{ + BOOL ret = False; + + if (!impl) { + 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_winbind_backend())); + } + + return ret; +} + +/* Close backend */ +BOOL winbindd_idmap_close(void) +{ + BOOL ret = False; + + if (!impl) { + impl = get_impl(lp_winbind_backend()); + } + + if (impl) { + ret = impl->close(); + } else { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } + + return ret; +} + +/* Dump backend status */ +void winbindd_idmap_status(void) +{ + if (!impl) { + impl = get_impl(lp_winbind_backend()); + } + + if (impl) { + impl->status(); + } else { + DEBUG(0, ("winbindd_idmap_init: could not load backend '%s'\n", + lp_winbind_backend())); + } +} diff --git a/source3/nsswitch/winbindd_idmap_tdb.c b/source3/nsswitch/winbindd_idmap_tdb.c new file mode 100644 index 0000000000..12d6972bae --- /dev/null +++ b/source3/nsswitch/winbindd_idmap_tdb.c @@ -0,0 +1,459 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon - user related function + + Copyright (C) Tim Potter 2000 + Copyright (C) Anthony Liguori 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 "winbindd.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_WINBIND + +/* High water mark keys */ +#define HWM_GROUP "GROUP HWM" +#define HWM_USER "USER HWM" + +/* idmap version determines auto-conversion */ +#define IDMAP_VERSION 2 + +/* Globals */ +static TDB_CONTEXT *idmap_tdb; + +/* convert one record to the new format */ +static int tdb_convert_fn(TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data, + void *ignored) +{ + struct winbindd_domain *domain; + char *p; + DOM_SID sid; + uint32 rid; + fstring keystr; + fstring dom_name; + TDB_DATA key2; + + p = strchr(key.dptr, '/'); + if (!p) + return 0; + + *p = 0; + fstrcpy(dom_name, key.dptr); + *p++ = '/'; + + domain = find_domain_from_name(dom_name); + if (!domain) { + /* We must delete the old record. */ + DEBUG(0, + ("winbindd: tdb_convert_fn : Unable to find domain %s\n", + dom_name)); + DEBUG(0, + ("winbindd: tdb_convert_fn : deleting record %s\n", + key.dptr)); + tdb_delete(idmap_tdb, key); + return 0; + } + + rid = atoi(p); + + sid_copy(&sid, &domain->sid); + sid_append_rid(&sid, rid); + + sid_to_string(keystr, &sid); + key2.dptr = keystr; + key2.dsize = strlen(keystr) + 1; + + if (tdb_store(idmap_tdb, key2, data, TDB_INSERT) != 0) { + /* not good! */ + DEBUG(0, + ("winbindd: tdb_convert_fn : Unable to update record %s\n", + key2.dptr)); + DEBUG(0, + ("winbindd: tdb_convert_fn : conversion failed - idmap corrupt ?\n")); + return -1; + } + + if (tdb_store(idmap_tdb, data, key2, TDB_REPLACE) != 0) { + /* not good! */ + DEBUG(0, + ("winbindd: tdb_convert_fn : Unable to update record %s\n", + data.dptr)); + DEBUG(0, + ("winbindd: tdb_convert_fn : conversion failed - idmap corrupt ?\n")); + return -1; + } + + tdb_delete(idmap_tdb, key); + + return 0; +} + +/***************************************************************************** + Convert the idmap database from an older version. +*****************************************************************************/ +static BOOL tdb_idmap_convert(void) +{ + int32 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION"); + BOOL bigendianheader = + (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False; + + if (vers == IDMAP_VERSION) + return True; + + if (((vers == -1) && bigendianheader) + || (IREV(vers) == IDMAP_VERSION)) { + /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */ + /* + * high and low records were created on a + * big endian machine and will need byte-reversing. + */ + + int32 wm; + + wm = tdb_fetch_int32(idmap_tdb, HWM_USER); + + if (wm != -1) { + wm = IREV(wm); + } else + wm = server_state.uid_low; + + if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) { + DEBUG(0, + ("tdb_idmap_convert: Unable to byteswap user hwm in idmap database\n")); + return False; + } + + wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP); + if (wm != -1) { + wm = IREV(wm); + } else + wm = server_state.gid_low; + + if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) { + DEBUG(0, + ("tdb_idmap_convert: Unable to byteswap group hwm in idmap database\n")); + return False; + } + } + + /* the old format stored as DOMAIN/rid - now we store the SID direct */ + tdb_traverse(idmap_tdb, tdb_convert_fn, NULL); + + if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == + -1) { + DEBUG(0, + ("tdb_idmap_convert: Unable to byteswap group hwm in idmap database\n")); + return False; + } + + return True; +} + +/* Allocate either a user or group id from the pool */ +static BOOL tdb_allocate_id(uid_t * id, BOOL isgroup) +{ + int hwm; + + /* Get current high water mark */ + if ((hwm = tdb_fetch_int32(idmap_tdb, + isgroup ? HWM_GROUP : HWM_USER)) == + -1) { + return False; + } + + /* Return next available uid in list */ + if ((isgroup && (hwm > server_state.gid_high)) || + (!isgroup && (hwm > server_state.uid_high))) { + DEBUG(0, + ("winbind %sid range full!\n", isgroup ? "g" : "u")); + return False; + } + + if (id) { + *id = hwm; + } + + hwm++; + + /* Store new high water mark */ + tdb_store_int32(idmap_tdb, isgroup ? HWM_GROUP : HWM_USER, hwm); + + return True; +} + +/* Get a sid from an id */ +static BOOL tdb_get_sid_from_id(int id, DOM_SID * sid, BOOL isgroup) +{ + TDB_DATA key, data; + fstring keystr; + BOOL result = False; + + slprintf(keystr, sizeof(keystr), "%s %d", isgroup ? "GID" : "UID", + id); + + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(idmap_tdb, key); + + if (data.dptr) { + result = string_to_sid(sid, data.dptr); + SAFE_FREE(data.dptr); + } + + return result; +} + +/* Get an id from a sid */ +static BOOL tdb_get_id_from_sid(DOM_SID * sid, uid_t * id, BOOL isgroup) +{ + TDB_DATA data, key; + fstring keystr; + BOOL result = False; + + /* Check if sid is present in database */ + sid_to_string(keystr, sid); + + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(idmap_tdb, key); + + if (data.dptr) { + fstring scanstr; + int the_id; + + /* Parse and return existing uid */ + fstrcpy(scanstr, isgroup ? "GID" : "UID"); + fstrcat(scanstr, " %d"); + + if (sscanf(data.dptr, scanstr, &the_id) == 1) { + /* Store uid */ + if (id) { + *id = the_id; + } + + result = True; + } + + SAFE_FREE(data.dptr); + } else { + + /* Allocate a new id for this sid */ + if (id && tdb_allocate_id(id, isgroup)) { + fstring keystr2; + + /* Store new id */ + slprintf(keystr2, sizeof(keystr2), "%s %d", + isgroup ? "GID" : "UID", *id); + + data.dptr = keystr2; + data.dsize = strlen(keystr2) + 1; + + tdb_store(idmap_tdb, key, data, TDB_REPLACE); + tdb_store(idmap_tdb, data, key, TDB_REPLACE); + + result = True; + } + } + + return result; +} + +/***************************************************************************** + Initialise idmap database. +*****************************************************************************/ +static BOOL tdb_idmap_init(void) +{ + SMB_STRUCT_STAT stbuf; + + /* move to the new database on first startup */ + if (!file_exist(lock_path("idmap.tdb"), &stbuf)) { + if (file_exist(lock_path("winbindd_idmap.tdb"), &stbuf)) { + char *cmd = NULL; + + /* lazy file copy */ + if (asprintf(&cmd, "cp -p %s/winbindd_idmap.tdb %s/idmap.tdb", lp_lockdir(), lp_lockdir()) != -1) { + system(cmd); + free(cmd); + } + if (!file_exist(lock_path("idmap.tdb"), &stbuf)) { + DEBUG(0, ("idmap_init: Unable to make a new database copy\n")); + return False; + } + } + } + + /* Open tdb cache */ + if (!(idmap_tdb = tdb_open_log(lock_path("idmap.tdb"), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, + 0600))) { + DEBUG(0, + ("winbindd_idmap_init: Unable to open idmap database\n")); + return False; + } + + /* possibly convert from an earlier version */ + if (!tdb_idmap_convert()) { + DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n")); + return False; + } + + /* Create high water marks for group and user id */ + if (tdb_fetch_int32(idmap_tdb, HWM_USER) == -1) { + if (tdb_store_int32 + (idmap_tdb, HWM_USER, server_state.uid_low) == -1) { + DEBUG(0, + ("winbindd_idmap_init: Unable to initialise user hwm in idmap database\n")); + return False; + } + } + + if (tdb_fetch_int32(idmap_tdb, HWM_GROUP) == -1) { + if (tdb_store_int32 + (idmap_tdb, HWM_GROUP, server_state.gid_low) == -1) { + DEBUG(0, + ("winbindd_idmap_init: Unable to initialise group hwm in idmap database\n")); + return False; + } + } + + return True; +} + +/* Get a sid from a uid */ +static BOOL tdb_get_sid_from_uid(uid_t uid, DOM_SID * sid) +{ + return tdb_get_sid_from_id((int) uid, sid, False); +} + +/* Get a sid from a gid */ +static BOOL tdb_get_sid_from_gid(gid_t gid, DOM_SID * sid) +{ + return tdb_get_sid_from_id((int) gid, sid, True); +} + +/* Get a uid from a sid */ +static BOOL tdb_get_uid_from_sid(DOM_SID * sid, uid_t * uid) +{ + return tdb_get_id_from_sid(sid, uid, False); +} + +/* Get a gid from a group sid */ +static BOOL tdb_get_gid_from_sid(DOM_SID * sid, gid_t * gid) +{ + return tdb_get_id_from_sid(sid, gid, True); +} + +/* Close the tdb */ +static BOOL tdb_idmap_close(void) +{ + if (idmap_tdb) + return (tdb_close(idmap_tdb) == 0); + return True; +} + + +/* Dump status information to log file. Display different stuff based on + the debug level: + + Debug Level Information Displayed + ================================================================= + 0 Percentage of [ug]id range allocated + 0 High water marks (next allocated ids) +*/ + +#define DUMP_INFO 0 + +static void tdb_idmap_status(void) +{ + int user_hwm, group_hwm; + + DEBUG(0, ("winbindd idmap status:\n")); + + /* Get current high water marks */ + + if ((user_hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { + DEBUG(DUMP_INFO, + ("\tCould not get userid high water mark!\n")); + } + + if ((group_hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { + DEBUG(DUMP_INFO, + ("\tCould not get groupid high water mark!\n")); + } + + /* Display next ids to allocate */ + + if (user_hwm != -1) { + DEBUG(DUMP_INFO, + ("\tNext userid to allocate is %d\n", user_hwm)); + } + + if (group_hwm != -1) { + DEBUG(DUMP_INFO, + ("\tNext groupid to allocate is %d\n", group_hwm)); + } + + /* Display percentage of id range already allocated. */ + + if (user_hwm != -1) { + int num_users = user_hwm - server_state.uid_low; + int total_users = + server_state.uid_high - server_state.uid_low; + + DEBUG(DUMP_INFO, + ("\tUser id range is %d%% full (%d of %d)\n", + num_users * 100 / total_users, num_users, + total_users)); + } + + if (group_hwm != -1) { + int num_groups = group_hwm - server_state.gid_low; + int total_groups = + server_state.gid_high - server_state.gid_low; + + DEBUG(DUMP_INFO, + ("\tGroup id range is %d%% full (%d of %d)\n", + num_groups * 100 / total_groups, num_groups, + total_groups)); + } + + /* Display complete mapping of users and groups to rids */ +} + +struct winbindd_idmap_methods tdb_idmap_methods = { + tdb_idmap_init, + + tdb_get_sid_from_uid, + tdb_get_sid_from_gid, + + tdb_get_uid_from_sid, + tdb_get_gid_from_sid, + + tdb_idmap_close, + + tdb_idmap_status +}; + +BOOL winbind_idmap_reg_tdb(struct winbindd_idmap_methods **meth) +{ + *meth = &tdb_idmap_methods; + + return True; +} diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index f01f20bb34..41bda7e5bc 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -98,6 +98,11 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) name_domain = state->request.data.name.dom_name; name_user = state->request.data.name.name; + /* fail if we are a PDC and this is our domain; should be done by passdb */ + + if ( lp_server_role() == ROLE_DOMAIN_PDC && 0==StrCaseCmp( name_domain, lp_workgroup()) ) + return WINBINDD_ERROR; + if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(0, ("could not find domain entry for domain %s\n", name_domain)); @@ -122,8 +127,6 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state) enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) { DOM_SID sid; - unid_t id; - int id_type; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; @@ -139,13 +142,11 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) } /* Find uid for this sid and return it */ - id_type = ID_USERID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, &sid))) { + if (!winbindd_idmap_get_uid_from_sid(&sid, &state->response.data.uid)) { DEBUG(1, ("Could not get uid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } - state->response.data.uid = id.uid; return WINBINDD_OK; } @@ -156,8 +157,6 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state) enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) { DOM_SID sid; - unid_t id; - int id_type; /* Ensure null termination */ state->request.data.sid[sizeof(state->request.data.sid)-1]='\0'; @@ -172,13 +171,11 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) } /* Find gid for this sid and return it */ - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, &sid))) { + if (!winbindd_idmap_get_gid_from_sid(&sid, &state->response.data.gid)) { DEBUG(1, ("Could not get gid for sid %s\n", state->request.data.sid)); return WINBINDD_ERROR; } - state->response.data.gid = id.gid; return WINBINDD_OK; } @@ -188,7 +185,6 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state) enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; - unid_t id; /* Bug out if the uid isn't in the winbind range */ @@ -201,8 +197,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) state->request.data.uid)); /* Lookup rid for this uid */ - id.uid = state->request.data.uid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(&sid, id, ID_USERID))) { + if (!winbindd_idmap_get_sid_from_uid(state->request.data.uid, &sid)) { DEBUG(1, ("Could not convert uid %d to rid\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -219,7 +214,6 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state) enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) { DOM_SID sid; - unid_t id; /* Bug out if the gid isn't in the winbind range */ @@ -232,8 +226,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state) state->request.data.gid)); /* Lookup sid for this uid */ - id.gid = state->request.data.gid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(&sid, id, ID_GROUPID))) { + if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &sid)) { DEBUG(1, ("Could not convert gid %d to sid\n", state->request.data.gid)); return WINBINDD_ERROR; diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index dd66275390..d2bd231918 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -36,29 +36,25 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name, fstring output_username; pstring homedir; fstring sid_string; - unid_t id; - int id_type; if (!pw || !dom_name || !user_name) return False; /* Resolve the uid number */ - - id_type = ID_USERID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, user_sid))) { + + if (!winbindd_idmap_get_uid_from_sid(user_sid, + &pw->pw_uid)) { DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid))); return False; } - pw->pw_uid = id.uid; /* Resolve the gid number */ - - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, group_sid))) { + + if (!winbindd_idmap_get_gid_from_sid(group_sid, + &pw->pw_gid)) { DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid))); return False; } - pw->pw_gid = id.gid; /* Username */ @@ -182,10 +178,9 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) fstring user_name; enum SID_NAME_USE name_type; WINBIND_USERINFO user_info; + gid_t gid; TALLOC_CTX *mem_ctx; NTSTATUS status; - unid_t id; - int id_type; /* Bug out if the uid isn't in the winbind range */ @@ -198,8 +193,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Get rid from uid */ - id.uid = state->request.data.uid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(&user_sid, id, ID_USERID))) { + if (!winbindd_idmap_get_sid_from_uid(state->request.data.uid, + &user_sid)) { DEBUG(1, ("could not convert uid %d to SID\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -241,10 +236,9 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) return WINBINDD_ERROR; } - /* Check group has a gid number */ + /* Resolve gid number */ - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, user_info.group_sid))) { + if (!winbindd_idmap_get_gid_from_sid(user_info.group_sid, &gid)) { DEBUG(1, ("error getting group id for user %s\n", user_name)); talloc_destroy(mem_ctx); return WINBINDD_ERROR; diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index ac0b317b42..ef030e2c7b 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -126,7 +126,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const /* see if this is a native mode win2k domain, but only for our own domain */ - if ( strequal( lp_workgroup(), domain_name) ) { + if ( lp_server_role() != ROLE_DOMAIN_PDC && strequal( lp_workgroup(), domain_name) ) { domain->native_mode = cm_check_for_native_mode_win2k( domain_name ); DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain_name, domain->native_mode ? "native" : "mixed" )); @@ -211,6 +211,7 @@ BOOL init_domain_list(void) /* Add ourselves as the first entry */ domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL); + if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) { DEBUG(1, ("Could not fetch sid for our domain %s\n", domain->name)); @@ -219,7 +220,7 @@ BOOL init_domain_list(void) /* get any alternate name for the primary domain */ cache_methods.alternate_name(domain); - + /* do an initial scan for trusted domains */ rescan_trusted_domains(True); @@ -380,12 +381,12 @@ BOOL winbindd_param_init(void) { /* Parse winbind uid and winbind_gid parameters */ - if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) { + if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) { DEBUG(0, ("winbind uid range missing or invalid\n")); return False; } - if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) { + if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) { DEBUG(0, ("winbind gid range missing or invalid\n")); return False; } |