summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/groupdb/mapping.c42
-rw-r--r--source3/nsswitch/wb_client.c28
-rw-r--r--source3/nsswitch/wbinfo.c19
-rw-r--r--source3/nsswitch/winbindd.c1
-rw-r--r--source3/nsswitch/winbindd_nss.h5
-rw-r--r--source3/nsswitch/winbindd_sid.c20
-rw-r--r--source3/rpc_server/srv_samr_nt.c59
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)