From 75cace04fdcb672cc6c3c3ec8403206f2b222c50 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 1 May 2003 11:47:48 +0000 Subject: [PATCH] *id_to_*id call reshape to return NTSTATUS errors plus internal fixes 1st stage (This used to be commit 6d036761e565bc93964bb3c939d5b7d78d5778a3) --- source3/auth/auth_rhosts.c | 2 +- source3/auth/auth_util.c | 24 ++-- source3/nsswitch/winbindd_group.c | 26 ++-- source3/nsswitch/winbindd_sid.c | 20 +-- source3/nsswitch/winbindd_user.c | 19 +-- source3/pam_smbpass/pam_smb_passwd.c | 4 +- source3/pam_smbpass/support.c | 2 +- source3/passdb/passdb.c | 8 +- source3/rpc_server/srv_samr_nt.c | 2 +- source3/rpc_server/srv_util.c | 2 +- source3/sam/idmap.c | 30 ----- source3/sam/idmap_tdb.c | 17 ++- source3/sam/idmap_util.c | 183 +++++++++++++++++---------- source3/smbd/posix_acls.c | 8 +- source3/smbd/uid.c | 2 +- source3/utils/pdbedit.c | 2 + 16 files changed, 174 insertions(+), 177 deletions(-) diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c index 0861d9747bd..34110831161 100644 --- a/source3/auth/auth_rhosts.c +++ b/source3/auth/auth_rhosts.c @@ -139,7 +139,7 @@ static BOOL check_hosts_equiv(SAM_ACCOUNT *account) char *fname = NULL; fname = lp_hosts_equiv(); - if (!sid_to_uid(pdb_get_user_sid(account), &uid)) + if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(account), &uid))) return False; /* note: don't allow hosts.equiv on root */ diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 56a1e9bb960..e8f2af41f32 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -611,21 +611,21 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token; int i; - if (!uid_to_sid(&user_sid, uid)) { + if (NT_STATUS_IS_ERR(uid_to_sid(&user_sid, uid))) { return NULL; } - if (!gid_to_sid(&group_sid, gid)) { + if (NT_STATUS_IS_ERR(gid_to_sid(&group_sid, gid))) { return NULL; } - group_sids = malloc(sizeof(DOM_SID) * ngroups); + group_sids = malloc(sizeof(DOM_SID) * ngroups); if (!group_sids) { DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n")); return NULL; } for (i = 0; i < ngroups; i++) { - if (!gid_to_sid(&(group_sids)[i], (groups)[i])) { + if (NT_STATUS_IS_ERR(gid_to_sid(&(group_sids)[i], (groups)[i]))) { DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i])); SAFE_FREE(group_sids); return NULL; @@ -648,7 +648,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, * If this samba server is a DC of the domain the user belongs to, it returns * both domain groups and local / builtin groups. If the user is in a trusted * domain, or samba is a member server of a domain, then this function returns - * local and builtin groups the user is a member of. + * local and builtin groups the user is a member of. * * currently this is a hack, as there is no sam implementation that is capable * of groups. @@ -665,7 +665,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass, *n_groups = 0; *groups = NULL; - if (!sid_to_uid(pdb_get_user_sid(sampass), &uid) || !sid_to_gid(pdb_get_group_sid(sampass), &gid)) { + if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass), &uid)) || NT_STATUS_IS_ERR(sid_to_gid(pdb_get_group_sid(sampass), &gid))) { DEBUG(0, ("get_user_groups_from_local_sam: error fetching uid or gid for user!\n")); return NT_STATUS_UNSUCCESSFUL; } @@ -706,7 +706,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass, *n_groups = n_unix_groups; for (i = 0; i < *n_groups; i++) { - if (!gid_to_sid(&(*groups)[i], (*unix_groups)[i])) { + if (NT_STATUS_IS_ERR(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) { DEBUG(1, ("get_user_groups_from_local_sam: failed to convert gid %ld to a sid!\n", (long int)(*unix_groups)[i+1])); SAFE_FREE(*groups); SAFE_FREE(*unix_groups); @@ -723,6 +723,8 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass, static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) { + NTSTATUS ret; + *server_info = malloc(sizeof(**server_info)); if (!*server_info) { DEBUG(0,("make_server_info: malloc failed!\n")); @@ -732,10 +734,10 @@ static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACC (*server_info)->sam_fill_level = SAM_FILL_ALL; (*server_info)->sam_account = sampass; - if (!sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid))) - return NT_STATUS_UNSUCCESSFUL; - if (!sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid))) - return NT_STATUS_UNSUCCESSFUL; + if (NT_STATUS_IS_ERR(ret = sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid)))) + return ret; + if (NT_STATUS_IS_ERR(ret = sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid)))) + return ret; return NT_STATUS_OK; } diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 02114a38910..14ebb784668 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -194,8 +194,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) fstring name_domain, name_group; char *tmp, *gr_mem; int gr_mem_len; - unid_t id; - int id_type; + gid_t gid; /* Ensure null termination */ state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0'; @@ -234,14 +233,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 (NT_STATUS_IS_ERR(sid_to_gid(&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 +267,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 +278,7 @@ 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 (NT_STATUS_IS_ERR(uid_to_sid(&group_sid, state->request.data.gid))) { DEBUG(1, ("could not convert gid %d to rid\n", state->request.data.gid)); return WINBINDD_ERROR; @@ -547,8 +543,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 +589,7 @@ 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 (NT_STATUS_IS_ERR(sid_to_gid(&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 +597,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)); @@ -874,18 +866,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; + gid_t gid; - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, user_gids[i]))) { + if (NT_STATUS_IS_ERR(sid_to_gid(user_gids[i], &gid))) { 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; + gid_list[num_gids] = gid; num_gids++; } diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index f01f20bb345..f5dd904dc16 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -122,8 +122,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 +137,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 (NT_STATUS_IS_ERR(sid_to_uid(&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 +152,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 +166,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 (NT_STATUS_IS_ERR(sid_to_gid(&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 +180,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 +192,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 (NT_STATUS_IS_ERR(uid_to_sid(&sid, state->request.data.uid))) { DEBUG(1, ("Could not convert uid %d to rid\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -219,7 +209,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 +221,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 (NT_STATUS_IS_ERR(gid_to_sid(&sid, state->request.data.gid))) { 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 dd662753907..dc07bc42e74 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -36,29 +36,23 @@ 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 (NT_STATUS_IS_ERR(sid_to_uid(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 (NT_STATUS_IS_ERR(sid_to_gid(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 */ @@ -184,8 +178,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) WINBIND_USERINFO user_info; TALLOC_CTX *mem_ctx; NTSTATUS status; - unid_t id; - int id_type; + gid_t gid; /* Bug out if the uid isn't in the winbind range */ @@ -198,8 +191,7 @@ 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 (NT_STATUS_IS_ERR(uid_to_sid(&user_sid, state->request.data.uid))) { DEBUG(1, ("could not convert uid %d to SID\n", state->request.data.uid)); return WINBINDD_ERROR; @@ -243,8 +235,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state) /* Check group has a gid number */ - id_type = ID_GROUPID; - if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &id_type, user_info.group_sid))) { + if (NT_STATUS_IS_ERR(sid_to_gid(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/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c index 1d022af16c1..3d82927e168 100644 --- a/source3/pam_smbpass/pam_smb_passwd.c +++ b/source3/pam_smbpass/pam_smb_passwd.c @@ -298,8 +298,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags, uid_t uid; /* password updated */ - if (!sid_to_uid(pdb_get_user_sid(sampass), &uid)) { - _log_err( LOG_NOTICE, "Unable to get uid for user %s", + if (NT_STATUS_IS_ERR(sid_to_uid(sampass, &uid))) { + _log_err( LOG_NOTICE "Unable to get uid for user %s", pdb_get_username(sampass)); _log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)", user, uidtoname(getuid()), getuid()); diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c index d3232237ac2..32aba7dd5be 100644 --- a/source3/pam_smbpass/support.c +++ b/source3/pam_smbpass/support.c @@ -399,7 +399,7 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass, service ? service : "**unknown**", name); new->count = 1; } - if (!sid_to_uid(pdb_get_user_sid(sampass), &(new->id))) { + if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass, &(new->id), &type)))) { _log_err(LOG_NOTICE, "failed auth request by %s for service %s as %s", uidtoname(getuid()), diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index b13ecf7a33e..8631888fafb 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -556,10 +556,6 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) return (True); } -/******************************************************************* - Converts NT user RID to a UNIX uid. - ********************************************************************/ - static int algorithmic_rid_base(void) { static int rid_offset = 0; @@ -582,6 +578,9 @@ static int algorithmic_rid_base(void) return rid_offset; } +/******************************************************************* + Converts NT user RID to a UNIX uid. + ********************************************************************/ uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) { @@ -589,7 +588,6 @@ uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER); } - /******************************************************************* converts UNIX uid to an NT User RID. ********************************************************************/ diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index d2e4ff26149..69ac60a7db0 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3396,7 +3396,7 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD } /* check a real user exist before we run the script to add a user to a group */ - if (!sid_to_uid(pdb_get_user_sid(sam_user), &uid)) { + if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) { pdb_free_sam(&sam_user); return NT_STATUS_NO_SUCH_USER; } diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index f948088737d..f96ccaef672 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -129,7 +129,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui fstrcpy(user_name, pdb_get_username(sam_pass)); grid=pdb_get_group_rid(sam_pass); - if (!sid_to_gid(pdb_get_group_sid(sam_pass), &gid)) { + if (NT_STATUS_IS_ERR(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) { /* this should never happen */ DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n")); pdb_free_sam(&sam_pass); diff --git a/source3/sam/idmap.c b/source3/sam/idmap.c index e0634681de1..9695e7b764e 100644 --- a/source3/sam/idmap.c +++ b/source3/sam/idmap.c @@ -102,35 +102,6 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type) lazy_initialize_idmap(); - if (!lp_idmap_only()) { - if (id_type & ID_USERID) { - uid_t low, high; - if (!lp_idmap_uid(&low, &high)) { - DEBUG(0, ("idmap uid range missing or invalid\n")); - DEBUGADD(0, ("idmap will be unable to map SIDs\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (low > id.uid || high < id.uid) { - DEBUG(0, ("uid not in range and idmap only is flase - not storing the mapping\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } else if (id_type & ID_GROUPID) { - gid_t low, high; - if (!lp_idmap_gid(&low, &high)) { - DEBUG(0, ("idmap gid range missing or invalid\n")); - DEBUGADD(0, ("idmap will be unable to map SIDs\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (low > id.gid || high < id.gid) { - DEBUG(0, ("uid not in range and idmap only is flase - not storing the mapping\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } else { - DEBUG(0, ("Wrong ID Type, mapping failed!")); - return NT_STATUS_UNSUCCESSFUL; - } - } - 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")); @@ -239,4 +210,3 @@ void idmap_status(void) local_map->status(); if (remote_map) remote_map->status(); } - diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index f85d2db0864..ab86eaf4ebf 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -213,7 +213,7 @@ idok: static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) { - TDB_DATA ksid, kid; + TDB_DATA ksid, kid, data; fstring ksidstr; fstring kidstr; @@ -235,6 +235,20 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type) kid.dptr = kidstr; kid.dsize = strlen(kidstr) + 1; + /* *DELETE* prevoius mappings if any. + * This is done both SID and [U|G]ID passed in */ + + data = tdb_fetch(idmap_tdb, ksid); + if (data.dptr) { + tdb_delete(idmap_tdb, data); + tdb_delete(idmap_tdb, ksid); + } + data = tdb_fetch(idmap_tdb, kid); + if (data.dptr) { + tdb_delete(idmap_tdb, data); + tdb_delete(idmap_tdb, kid); + } + if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) { DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb))); return NT_STATUS_UNSUCCESSFUL; @@ -427,4 +441,3 @@ NTSTATUS idmap_reg_tdb(struct idmap_methods **meth) return NT_STATUS_OK; } - diff --git a/source3/sam/idmap_util.c b/source3/sam/idmap_util.c index 3086ee21136..5d089d3bafb 100644 --- a/source3/sam/idmap_util.c +++ b/source3/sam/idmap_util.c @@ -112,146 +112,189 @@ BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high) /***************************************************************** *THE CANONICAL* convert uid_t to SID function. - Tries winbind first - then uses local lookup. + check idmap if uid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs Returns SID pointer. *****************************************************************/ -DOM_SID *uid_to_sid(DOM_SID *sid, uid_t uid) +NTSTATUS uid_to_sid(DOM_SID *sid, uid_t uid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; unid_t id; + int flags; DEBUG(10,("uid_to_sid: uid = [%d]\n", uid)); - if (idmap_check_ugid_is_in_free_range(uid)) { - id.uid = uid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_USERID))) { - DEBUG(10, ("uid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); - return NULL; + flags = ID_USERID; + if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(uid)) { + flags |= ID_NOMAP; + } + + id.uid = uid; + if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) { + DEBUG(10, ("uid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); + if (flags & ID_NOMAP) { + sid_copy(sid, get_global_sam_sid()); + sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid)); + + DEBUG(10,("uid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)uid, sid_string_static(sid))); + ret = NT_STATUS_OK; } - } else { - sid_copy(sid, get_global_sam_sid()); - sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid)); - - DEBUG(10,("uid_to_sid: algorithmic %u -> %s\n", (unsigned int)uid, sid_string_static(sid))); } - return sid; - + + return ret; } /***************************************************************** *THE CANONICAL* convert gid_t to SID function. - Tries winbind first - then uses local lookup. + check idmap if gid is in idmap range, otherwise falls back to + the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs Returns SID pointer. *****************************************************************/ -DOM_SID *gid_to_sid(DOM_SID *sid, gid_t gid) +NTSTATUS gid_to_sid(DOM_SID *sid, gid_t gid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; GROUP_MAP map; unid_t id; + int flags; DEBUG(10,("gid_to_sid: gid = [%d]\n", gid)); - if (idmap_check_ugid_is_in_free_range(gid)) { - id.gid = gid; - if (NT_STATUS_IS_ERR(idmap_get_sid_from_id(sid, id, ID_GROUPID))) { - DEBUG(10, ("gid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); - return NULL; - } - } else { - if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { - sid_copy(sid, &map.sid); - } else { - sid_copy(sid, get_global_sam_sid()); - sid_append_rid(sid, pdb_gid_to_group_rid(gid)); - } + flags = ID_GROUPID; + if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(gid)) { + flags |= ID_NOMAP; + } + + id.gid = gid; + if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) { + DEBUG(10, ("gid_to_sid: Failed to map sid = [%s]\n", sid_string_static(sid))); + if (flags & ID_NOMAP) { + if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { + sid_copy(sid, &map.sid); + } else { + sid_copy(sid, get_global_sam_sid()); + sid_append_rid(sid, pdb_gid_to_group_rid(gid)); + } - DEBUG(10,("gid_to_sid: algorithmic %u -> %s\n", (unsigned int)gid, sid_string_static(sid))); + DEBUG(10,("gid_to_sid: Fall back to algorithmic mapping: %u -> %s\n", (unsigned int)gid, sid_string_static(sid))); + ret = NT_STATUS_OK; + } } - return sid; + return ret; } /***************************************************************** *THE CANONICAL* convert SID to uid function. - Tries winbind first - then uses local lookup. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + A special cache is used for uids that maps to Wellknown SIDs Returns True if this name is a user sid and the conversion - was done correctly, False if not. sidtype is set by this function. + was done correctly, False if not. *****************************************************************/ -BOOL sid_to_uid(const DOM_SID *sid, uid_t *uid) +NTSTATUS sid_to_uid(const DOM_SID *sid, uid_t *uid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL fallback = False; uint32 rid; unid_t id; - int type; + int flags; DEBUG(10,("sid_to_uid: sid = [%s]\n", sid_string_static(sid))); - if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { - if (!idmap_check_rid_is_in_free_range(rid)) { - if (!fallback_pdb_rid_is_user(rid)) { - DEBUG(3, ("sid_to_uid: RID %u is *NOT* a user\n", (unsigned)rid)); - return False; + flags = ID_USERID; + if (!lp_idmap_only()) { + if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + if (!idmap_check_rid_is_in_free_range(rid)) { + flags |= ID_NOMAP; + fallback = True; } - *uid = fallback_pdb_user_rid_to_uid(rid); - return True; } } - type = ID_USERID; - if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) { + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) { DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid)); *uid = id.uid; - return True; + ret = NT_STATUS_OK; + } else if (fallback) { + DEBUG(10,("sid_to_uid: Fall back to algorithmic mapping\n")); + if (!fallback_pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_uid: SID %s is *NOT* a user\n", sid_string_static(sid))); + ret = NT_STATUS_UNSUCCESSFUL; + } else { + *uid = fallback_pdb_user_rid_to_uid(rid); + DEBUG(10,("sid_to_uid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*uid))); + ret = NT_STATUS_OK; + } } - return False; + return ret; } /***************************************************************** *THE CANONICAL* convert SID to gid function. - Tries winbind first - then uses local lookup. + if it is a foreign sid or it is in idmap rid range check idmap, + otherwise falls back to the legacy algorithmic mapping. + Group mapping is used for gids that maps to Wellknown SIDs Returns True if this name is a user sid and the conversion was done correctly, False if not. *****************************************************************/ -BOOL sid_to_gid(const DOM_SID *sid, gid_t *gid) +NTSTATUS sid_to_gid(const DOM_SID *sid, gid_t *gid) { + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL fallback = False; uint32 rid; unid_t id; - int type; + int flags; DEBUG(10,("sid_to_gid: sid = [%s]\n", sid_string_static(sid))); - if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + flags = ID_GROUPID; + if (!lp_idmap_only()) { + if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) { + if (!idmap_check_rid_is_in_free_range(rid)) { + flags |= ID_NOMAP; + fallback = True; + } + } + } + + if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) { + DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid)); + *gid = id.gid; + ret = NT_STATUS_OK; + } else if (fallback) { GROUP_MAP map; BOOL result; + DEBUG(10,("sid_to_gid: Fall back to algorithmic mapping\n")); + + /* the group mapping code should register mappings in idmap + * and have the following if() eliminated */ if (pdb_getgrsid(&map, *sid, MAPPING_WITHOUT_PRIV)) { /* the SID is in the mapping table but not mapped */ - if (map.gid==(gid_t)-1) - return False; - - *gid = map.gid; - return True; + if (map.gid==(gid_t)-1) { + ret = NT_STATUS_UNSUCCESSFUL; + } else { + *gid = map.gid; + ret = NT_STATUS_OK; + } } else { - if (!idmap_check_rid_is_in_free_range(rid)) { - if (fallback_pdb_rid_is_user(rid)) { - DEBUG(3, ("sid_to_gid: RID %u is *NOT* a group\n", (unsigned)rid)); - return False; - } + if (fallback_pdb_rid_is_user(rid)) { + DEBUG(3, ("sid_to_gid: SID %s is *NOT* a group\n", sid_string_static(sid))); + ret = NT_STATUS_UNSUCCESSFUL; + } else { *gid = pdb_group_rid_to_gid(rid); - return True; + DEBUG(10,("sid_to_gid: mapping: %s -> %u\n", sid_string_static(sid), (unsigned int)(*gid))); + ret = NT_STATUS_OK; } } } - type = ID_GROUPID; - if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &type, sid))) { - DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid)); - *gid = id.gid; - return True; - } - - return False; + return ret; } - diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 6e1e70ae96d..6925b35246e 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -468,7 +468,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, if (security_info_sent & OWNER_SECURITY_INFORMATION) { sid_copy(&owner_sid, psd->owner_sid); - if (!sid_to_uid( &owner_sid, puser)) { + if (NT_STATUS_IS_ERR(sid_to_uid(&owner_sid, puser))) { #if ACL_FORCE_UNMAPPABLE /* this allows take ownership to work reasonably */ extern struct current_user current_user; @@ -488,7 +488,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, if (security_info_sent & GROUP_SECURITY_INFORMATION) { sid_copy(&grp_sid, psd->grp_sid); - if (!sid_to_gid( &grp_sid, pgrp)) { + if (NT_STATUS_IS_ERR(sid_to_gid( &grp_sid, pgrp))) { #if ACL_FORCE_UNMAPPABLE /* this allows take group ownership to work reasonably */ extern struct current_user current_user; @@ -1001,10 +1001,10 @@ static BOOL create_canon_ace_lists(files_struct *fsp, if (nt4_compatible_acls()) psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY; - } else if (sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid)) { + } else if (NT_STATUS_IS_OK(sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid))) { current_ace->owner_type = GID_ACE; current_ace->type = SMB_ACL_GROUP; - } else if (sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid)) { + } else if (NT_STATUS_IS_OK(sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid))) { current_ace->owner_type = UID_ACE; current_ace->type = SMB_ACL_USER; } else { diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7fc49a35e22..c68d00025c6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -407,7 +407,7 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER for (i = 0; i < ptok->num_sids; i++) { gid_t new_grp; - if (sid_to_gid(&ptok->user_sids[i], &new_grp)) { + if (NT_STATUS_IS_OK(sid_to_gid(&ptok->user_sids[i], &new_grp))) { /* * Don't add the gid_t if it is already in the current group * list. Some UNIXen don't like the same group more than once. diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 170d2a03f17..4cb3db52b7f 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -158,6 +158,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst char lm_passwd[33]; char nt_passwd[33]; + uid = -1; sid_to_uid(pdb_get_user_sid(sam_pwent), &uid); pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent)); @@ -170,6 +171,7 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)pdb_get_pass_last_set_time(sam_pwent)); } else { + uid = -1; sid_to_uid(pdb_get_user_sid(sam_pwent), &uid); printf ("%s:%d:%s\n", pdb_get_username(sam_pwent), uid, pdb_get_fullname(sam_pwent)); } -- 2.34.1