Add and delete aliases via srv_samr_nt. For that I added a RID allocation call
authorVolker Lendecke <vlendec@samba.org>
Sun, 14 Mar 2004 10:24:19 +0000 (10:24 +0000)
committerVolker Lendecke <vlendec@samba.org>
Sun, 14 Mar 2004 10:24:19 +0000 (10:24 +0000)
to winbindd. idmap_allocate_rid wants information about whether this will be a
user or a group, I did not export this to the winbind interface.

The reason for idmap to get that info is to keep consistent with the
algorithmic convention to alloc only even rids for users and odd rids for
groups. I'm not fully convinced that this really gains us anything. Any real
good arguments?

Volker
(This used to be commit 7f62cf933cad69799204bfdc773e08ff0dde0b20)

source3/groupdb/mapping.c
source3/nsswitch/wb_client.c
source3/nsswitch/wbinfo.c
source3/nsswitch/winbindd.c
source3/nsswitch/winbindd_nss.h
source3/nsswitch/winbindd_sid.c
source3/rpc_server/srv_samr_nt.c

index 818a4acb847521893925b61eb54f14a431c5f546..cbf022f377257ed0ccb1b2d0bf39d64d8872c61d 100644 (file)
@@ -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,
index 90e4584daba026676b7d0f42acea0de2e13e9527..32dfc8decac7848fbec2919eb27f92c88de9a922 100644 (file)
@@ -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 */
-
 /***********************************************************************/
 
index 772332ee59272fe981fb1675c4592765a0ad0cec..af2a0ce7c6943d666307d8b0a4340f8d33ee5854 100644 (file)
@@ -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");
index 8a0d0f757355613618284e4155f40477b3916597..c4319d493a34a0a0cb1ec7059e5d91e4375079a0 100644 (file)
@@ -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 */
 
index 0d110b8afa87fb503cde0264cd2e6d5341e60a05..745a29facc6507ecf6f5a451f01a6d4d41b7cafe 100644 (file)
@@ -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;
index 8ff6cfd2714b65bee6d9e1724587d78d0aac7d2a..d4206558c5ec6d6e775e2b55a3fa131d5d7b353c 100644 (file)
@@ -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;
+}
index 8861ce84c200c8a4c56efcf301a925941a6f8cad..b1147e50ef595209dd551859589d607a092ef0d6 100644 (file)
@@ -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)