diff options
-rw-r--r-- | source3/groupdb/mapping.c | 42 | ||||
-rw-r--r-- | source3/nsswitch/wb_client.c | 28 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 19 | ||||
-rw-r--r-- | source3/nsswitch/winbindd.c | 1 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_nss.h | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_sid.c | 20 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 59 |
7 files changed, 116 insertions, 58 deletions
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index 818a4acb84..cbf022f377 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -362,7 +362,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map) Remove a group mapping entry. ****************************************************************************/ -static BOOL group_map_remove(DOM_SID sid) +static BOOL group_map_remove(const DOM_SID *sid) { TDB_DATA kbuf, dbuf; pstring key; @@ -375,7 +375,7 @@ static BOOL group_map_remove(DOM_SID sid) /* the key is the SID, retrieving is direct */ - sid_to_string(string_sid, &sid); + sid_to_string(string_sid, sid); slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid); kbuf.dptr = key; @@ -1266,7 +1266,7 @@ NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods, NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods, DOM_SID sid) { - return group_map_remove(sid) ? + return group_map_remove(&sid) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } @@ -1289,13 +1289,45 @@ NTSTATUS pdb_default_find_alias(struct pdb_methods *methods, NTSTATUS pdb_default_create_alias(struct pdb_methods *methods, const char *name, uint32 *rid) { - return NT_STATUS_ACCESS_DENIED; + DOM_SID sid; + enum SID_NAME_USE type; + uint32 new_rid; + gid_t gid; + + if (lookup_name(get_global_sam_name(), name, &sid, &type)) + return NT_STATUS_ALIAS_EXISTS; + + if (!winbind_allocate_rid(&new_rid)) + return NT_STATUS_ACCESS_DENIED; + + sid_copy(&sid, get_global_sam_sid()); + sid_append_rid(&sid, new_rid); + + /* Here we allocate the gid */ + if (!winbind_sid_to_gid(&gid, &sid)) { + DEBUG(0, ("Could not get gid for new RID\n")); + return NT_STATUS_ACCESS_DENIED; + } + + if (!add_initial_entry(gid, sid_string_static(&sid), SID_NAME_ALIAS, + name, "")) { + DEBUG(0, ("Could not add group mapping entry for alias %s\n", + name)); + return NT_STATUS_ACCESS_DENIED; + } + + *rid = new_rid; + + return NT_STATUS_OK; } NTSTATUS pdb_default_delete_alias(struct pdb_methods *methods, const DOM_SID *sid) { - return NT_STATUS_ACCESS_DENIED; + if (!group_map_remove(sid)) + return NT_STATUS_ACCESS_DENIED; + + return NT_STATUS_OK; } NTSTATUS pdb_default_enum_aliases(struct pdb_methods *methods, diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c index 90e4584dab..32dfc8deca 100644 --- a/source3/nsswitch/wb_client.c +++ b/source3/nsswitch/wb_client.c @@ -235,6 +235,30 @@ BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid) return (result == NSS_STATUS_SUCCESS); } +BOOL winbind_allocate_rid(uint32 *rid) +{ + struct winbindd_request request; + struct winbindd_response response; + int result; + + /* Initialise request */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + /* Make request */ + + result = winbindd_request(WINBINDD_ALLOCATE_RID, &request, &response); + + if (result != NSS_STATUS_SUCCESS) + return False; + + /* Copy out result */ + *rid = response.data.rid; + + return True; +} + /* Fetch the list of groups a user is a member of from winbindd. This is used by winbind_getgroups. */ @@ -595,8 +619,6 @@ BOOL winbind_delete_group( const char *group ) } /***********************************************************************/ -#if 0 /* not needed currently since winbindd_acct was added -- jerry */ - /* Call winbindd to convert SID to uid. Do not allocate */ BOOL winbind_sid_to_uid_query(uid_t *puid, const DOM_SID *sid) @@ -667,7 +689,5 @@ BOOL winbind_sid_to_gid_query(gid_t *pgid, const DOM_SID *sid) return (result == NSS_STATUS_SUCCESS); } -#endif /* JERRY */ - /***********************************************************************/ diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 772332ee59..af2a0ce7c6 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -436,6 +436,18 @@ static BOOL wbinfo_sid_to_gid(char *sid) return True; } +static BOOL wbinfo_allocate_rid(void) +{ + uint32 rid; + + if (!winbind_allocate_rid(&rid)) + return False; + + d_printf("New rid: %d\n", rid); + + return True; +} + /* Convert sid to string */ static BOOL wbinfo_lookupsid(char *sid) @@ -983,6 +995,7 @@ int main(int argc, char **argv) { "gid-to-sid", 'G', POPT_ARG_INT, &int_arg, 'G', "Converts gid to sid", "GID" }, { "sid-to-uid", 'S', POPT_ARG_STRING, &string_arg, 'S', "Converts sid to uid", "SID" }, { "sid-to-gid", 'Y', POPT_ARG_STRING, &string_arg, 'Y', "Converts sid to gid", "SID" }, + { "allocate-rid", 'A', POPT_ARG_NONE, 0, 'A', "Get a new RID out of idmap" }, { "create-user", 'c', POPT_ARG_STRING, &string_arg, 'c', "Create a local user account", "name" }, { "delete-user", 'x', POPT_ARG_STRING, &string_arg, 'x', "Delete a local user account", "name" }, { "create-group", 'C', POPT_ARG_STRING, &string_arg, 'C', "Create a local group", "name" }, @@ -1102,6 +1115,12 @@ int main(int argc, char **argv) goto done; } break; + case 'A': + if (!wbinfo_allocate_rid()) { + d_printf("Could not allocate a RID\n"); + goto done; + } + break; case 't': if (!wbinfo_check_secret()) { d_printf("Could not check secret\n"); diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index 8a0d0f7573..c4319d493a 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -255,6 +255,7 @@ static struct dispatch_table dispatch_table[] = { { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" }, { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" }, { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" }, + { WINBINDD_ALLOCATE_RID, winbindd_allocate_rid, "ALLOCATE_RID" }, /* Miscellaneous */ diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h index 0d110b8afa..745a29facc 100644 --- a/source3/nsswitch/winbindd_nss.h +++ b/source3/nsswitch/winbindd_nss.h @@ -36,7 +36,7 @@ /* Update this when you change the interface. */ -#define WINBIND_INTERFACE_VERSION 9 +#define WINBIND_INTERFACE_VERSION 10 /* Socket commands */ @@ -84,6 +84,7 @@ enum winbindd_cmd { WINBINDD_SID_TO_GID, WINBINDD_UID_TO_SID, WINBINDD_GID_TO_SID, + WINBINDD_ALLOCATE_RID, /* Miscellaneous other stuff */ @@ -266,7 +267,7 @@ struct winbindd_response { char nt_session_key[16]; char first_8_lm_hash[8]; } auth; - uint32 rid; /* create user or group */ + uint32 rid; /* create user or group or allocate rid */ struct { fstring name; fstring alt_name; diff --git a/source3/nsswitch/winbindd_sid.c b/source3/nsswitch/winbindd_sid.c index 8ff6cfd271..d4206558c5 100644 --- a/source3/nsswitch/winbindd_sid.c +++ b/source3/nsswitch/winbindd_sid.c @@ -434,3 +434,23 @@ done: return WINBINDD_OK; } + +enum winbindd_result winbindd_allocate_rid(struct winbindd_cli_state *state) +{ + if ( !state->privileged ) { + DEBUG(2, ("winbindd_allocate_rid: non-privileged access " + "denied!\n")); + return WINBINDD_ERROR; + } + + /* We tell idmap to always allocate a user RID. There might be a good + * reason to keep RID allocation for users to even and groups to + * odd. This needs discussion I think. For now only allocate user + * rids. */ + + if (!NT_STATUS_IS_OK(idmap_allocate_rid(&state->response.data.rid, + USER_RID_TYPE))) + return WINBINDD_ERROR; + + return WINBINDD_OK; +} diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 8861ce84c2..b1147e50ef 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3708,12 +3708,6 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u) { DOM_SID alias_sid; - DOM_SID dom_sid; - uint32 alias_rid; - fstring alias_sid_str; - gid_t gid; - struct group *grp; - GROUP_MAP map; uint32 acc_granted; DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__)); @@ -3725,38 +3719,18 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) { return r_u->status; } - - sid_copy(&dom_sid, &alias_sid); - sid_to_string(alias_sid_str, &dom_sid); - sid_split_rid(&dom_sid, &alias_rid); - DEBUG(10, ("sid is %s\n", alias_sid_str)); + DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid))); - /* we check if it's our SID before deleting */ - if (!sid_equal(&dom_sid, get_global_sam_sid())) + if (!sid_check_is_in_our_domain(&alias_sid)) return NT_STATUS_NO_SUCH_ALIAS; - + DEBUG(10, ("lookup on Local SID\n")); - if(!get_local_group_from_sid(&alias_sid, &map)) - return NT_STATUS_NO_SUCH_ALIAS; - - gid=map.gid; - - /* check if group really exists */ - if ( (grp=getgrgid(gid)) == NULL) - return NT_STATUS_NO_SUCH_ALIAS; - - /* we can delete the UNIX group */ - smb_delete_group(grp->gr_name); - - /* check if the group has been successfully deleted */ - if ( (grp=getgrgid(gid)) != NULL) + /* Have passdb delete the alias */ + if (!pdb_delete_alias(&alias_sid)) return NT_STATUS_ACCESS_DENIED; - /* don't check if we removed it as it could be an un-mapped group */ - pdb_delete_group_mapping_entry(alias_sid); - if (!close_policy_hnd(p, &q_u->alias_pol)) return NT_STATUS_OBJECT_NAME_INVALID; @@ -3834,7 +3808,6 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S DOM_SID dom_sid; DOM_SID info_sid; fstring name; - fstring sid_string; struct group *grp; struct samr_info *info; uint32 acc_granted; @@ -3855,26 +3828,18 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1); - /* check if group already exists */ - if ( (grp=getgrnam(name)) != NULL) - return NT_STATUS_ALIAS_EXISTS; - - /* we can create the UNIX group */ - if (smb_create_group(name, &gid) != 0) - return NT_STATUS_ACCESS_DENIED; - - /* check if the group has been successfully created */ - if ((grp=getgrgid(gid)) == NULL) + /* Have passdb create the alias */ + if (!pdb_create_alias(name, &r_u->rid)) return NT_STATUS_ACCESS_DENIED; - r_u->rid=pdb_gid_to_group_rid(grp->gr_gid); - sid_copy(&info_sid, get_global_sam_sid()); sid_append_rid(&info_sid, r_u->rid); - sid_to_string(sid_string, &info_sid); - /* add the group to the mapping table */ - if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL)) + if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid))) + return NT_STATUS_ACCESS_DENIED; + + /* check if the group has been successfully created */ + if ((grp=getgrgid(gid)) == NULL) return NT_STATUS_ACCESS_DENIED; if ((info = get_samr_info_by_sid(&info_sid)) == NULL) |