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;
/* 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;
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;
}
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,
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. */
}
/***********************************************************************/
-#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)
return (result == NSS_STATUS_SUCCESS);
}
-#endif /* JERRY */
-
/***********************************************************************/
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)
{ "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" },
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");
{ 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 */
/* Update this when you change the interface. */
-#define WINBIND_INTERFACE_VERSION 9
+#define WINBIND_INTERFACE_VERSION 10
/* Socket commands */
WINBINDD_SID_TO_GID,
WINBINDD_UID_TO_SID,
WINBINDD_GID_TO_SID,
+ WINBINDD_ALLOCATE_RID,
/* Miscellaneous other stuff */
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;
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;
+}
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__));
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;
DOM_SID dom_sid;
DOM_SID info_sid;
fstring name;
- fstring sid_string;
struct group *grp;
struct samr_info *info;
uint32 acc_granted;
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)