summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_lookup.c592
-rw-r--r--source3/rpc_server/srv_lsa.c507
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c245
-rw-r--r--source3/rpc_server/srv_netlog.c934
-rw-r--r--source3/rpc_server/srv_pipe.c1510
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c371
-rw-r--r--source3/rpc_server/srv_reg.c59
-rw-r--r--source3/rpc_server/srv_samr.c2436
-rw-r--r--source3/rpc_server/srv_srvsvc.c640
-rw-r--r--source3/rpc_server/srv_util.c323
-rw-r--r--source3/rpc_server/srv_wkssvc.c10
11 files changed, 3146 insertions, 4481 deletions
diff --git a/source3/rpc_server/srv_lookup.c b/source3/rpc_server/srv_lookup.c
index 193c7931ab..e6df9933bf 100644
--- a/source3/rpc_server/srv_lookup.c
+++ b/source3/rpc_server/srv_lookup.c
@@ -52,6 +52,44 @@ extern fstring global_sam_name;
extern DOM_SID global_sam_sid;
extern DOM_SID global_sid_S_1_5_20;
+/*
+ * A list of the rids of well known BUILTIN and Domain users
+ * and groups.
+ */
+
+rid_name builtin_alias_rids[] =
+{
+ { BUILTIN_ALIAS_RID_ADMINS , "Administrators" },
+ { BUILTIN_ALIAS_RID_USERS , "Users" },
+ { BUILTIN_ALIAS_RID_GUESTS , "Guests" },
+ { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" },
+
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" },
+ { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" },
+ { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" },
+ { 0 , NULL }
+};
+
+/* array lookup of well-known Domain RID users. */
+rid_name domain_user_rids[] =
+{
+ { DOMAIN_USER_RID_ADMIN , "Administrator" },
+ { DOMAIN_USER_RID_GUEST , "Guest" },
+ { 0 , NULL }
+};
+
+/* array lookup of well-known Domain RID groups. */
+rid_name domain_group_rids[] =
+{
+ { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" },
+ { DOMAIN_GROUP_RID_USERS , "Domain Users" },
+ { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
+ { 0 , NULL }
+};
+
+
int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
{
int count;
@@ -72,27 +110,17 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
uint32 status;
uint32 rid;
- DOM_SID sid;
uint8 type;
uint8 attr = mem[count].attr;
char *name = mem[count].name;
become_root(True);
- status = lookup_name(name, &sid, &type);
+ status = lookup_grp_rid(name, &rid, &type);
unbecome_root(True);
- if (status == 0x0 && !sid_front_equal(&global_sam_sid, &sid))
- {
- fstring sid_str;
- sid_to_string(sid_str, &sid);
- DEBUG(1,("make_dom_gids: unknown sid %s for groupname %s\n",
- sid_str, name));
- }
- else if (status == 0x0)
+ if (status == 0x0)
{
- sid_split_rid(&sid, &rid);
-
gids = (DOM_GID *)Realloc( gids, sizeof(DOM_GID) * (count+1) );
if (gids == NULL)
@@ -110,7 +138,7 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
}
else
{
- DEBUG(1,("make_dom_gids: unknown groupname %s\n", name));
+ DEBUG(1,("make_dom_gids: unknown group name %s\n", name));
}
}
@@ -140,286 +168,282 @@ int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid)
/*******************************************************************
- lookup_builtin_sid
+ lookup_builtin_names
********************************************************************/
-uint32 lookup_builtin_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_builtin_names(uint32 rid, char *name, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_wk_user_sid (sid, name, type) : status;
- status = (status != 0x0) ? lookup_wk_group_sid(sid, name, type) : status;
- status = (status != 0x0) ? lookup_wk_alias_sid(sid, name, type) : status;
+ status = (status != 0x0) ? lookup_wk_user_name (rid, name, type) : status;
+ status = (status != 0x0) ? lookup_wk_group_name(rid, name, type) : status;
+ status = (status != 0x0) ? lookup_wk_alias_name(rid, name, type) : status;
return status;
}
/*******************************************************************
- lookup_added_sid - names that have been added to the SAM database by admins.
+ lookup_added_name - names that have been added to the SAM database by admins.
********************************************************************/
-uint32 lookup_added_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_added_name(uint32 rid, char *name, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_user_sid (sid, name, type) : status;
- status = (status != 0x0) ? lookup_group_sid(sid, name, type) : status;
- status = (status != 0x0) ? lookup_alias_sid(sid, name, type) : status;
+ status = (status != 0x0) ? lookup_user_name (rid, name, type) : status;
+ status = (status != 0x0) ? lookup_group_name(rid, name, type) : status;
+ status = (status != 0x0) ? lookup_alias_name(rid, name, type) : status;
return status;
}
/*******************************************************************
- lookup_sid
+ lookup_name
********************************************************************/
-uint32 lookup_sid(DOM_SID *sid, char *name, uint8 *type)
+uint32 lookup_name(uint32 rid, char *name, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_builtin_sid(sid, name, type) : status;
- status = (status != 0x0) ? lookup_added_sid (sid, name, type) : status;
+ status = (status != 0x0) ? lookup_builtin_names(rid, name, type) : status;
+ status = (status != 0x0) ? lookup_added_name (rid, name, type) : status;
return status;
}
/*******************************************************************
- lookup_wk_group_sid
+ lookup_wk_group_name
********************************************************************/
-uint32 lookup_wk_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
+uint32 lookup_wk_group_name(uint32 rid, char *group_name, uint8 *type)
{
- uint32 rid;
- DOM_SID tmp;
- char *mapped;
+ int i = 0;
+ (*type) = SID_NAME_WKN_GRP;
- (*type) = SID_NAME_DOM_GRP;
-
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ DEBUG(5,("lookup_wk_group_name: rid: %d", rid));
- if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+ while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
{
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ i++;
}
- DEBUG(5,("lookup_wk_group_sid: rid: %d", rid));
-
- /* look up the well-known domain group rids first */
- mapped = lookup_wk_group_rid(rid);
- if(mapped == NULL)
+ if (domain_group_rids[i].rid != 0)
{
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ fstrcpy(group_name, domain_group_rids[i].name);
+ DEBUG(5,(" = %s\n", group_name));
+ return 0x0;
}
- fstrcpy(group_name, mapped);
- DEBUG(5,(" = %s\n", group_name));
- return 0x0;
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup_group_sid
+ lookup_group_name
********************************************************************/
-uint32 lookup_group_sid(DOM_SID *sid, char *group_name, uint8 *type)
+uint32 lookup_group_name(uint32 rid, char *group_name, uint8 *type)
{
- pstring sid_str;
- uint32 rid;
- DOM_SID tmp;
- DOMAIN_GRP *grp = NULL;
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ DOM_SID sid;
- (*type) = SID_NAME_DOM_GRP;
+ DEBUG(5,("lookup_group_name: rid: 0x%x", rid));
- sid_to_string(sid_str, sid);
- DEBUG(5,("lookup_group_sid: sid: %s", sid_str));
+ sid_copy (&sid, &global_sam_sid);
+ sid_append_rid(&sid, rid);
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ (*type) = SID_NAME_DOM_GRP;
- if (!sid_equal(&global_sam_sid, &tmp))
+ if (map_group_sid_to_name(&sid, group_name, NULL))
{
- DEBUG(5,("not our SID\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ status = 0x0;
}
- grp = getgrouprid(rid, NULL, NULL);
-
- if (grp != NULL)
+ if (status == 0x0)
{
- fstrcpy(group_name, grp->name);
DEBUG(5,(" = %s\n", group_name));
- return 0x0;
+ }
+ else
+ {
+ DEBUG(5,(" none mapped\n"));
}
- DEBUG(5,(" none mapped\n"));
return status;
}
/*******************************************************************
- lookup_wk_alias_sid
+ lookup_wk_alias_name
********************************************************************/
-uint32 lookup_wk_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
+uint32 lookup_wk_alias_name(uint32 rid, char *alias_name, uint8 *type)
{
- uint32 rid;
- DOM_SID tmp;
- char *mapped;
-
+ int i = 0;
(*type) = SID_NAME_ALIAS;
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ DEBUG(5,("lookup_wk_alias_name: rid: %d", rid));
- if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+ while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
{
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ i++;
}
- DEBUG(5,("lookup_wk_alias_sid: rid: %d", rid));
-
- /* look up the well-known alias group rids first */
- mapped = lookup_wk_alias_rid(rid);
- if(mapped == NULL)
+ if (builtin_alias_rids[i].rid != 0)
{
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ fstrcpy(alias_name, builtin_alias_rids[i].name);
+ DEBUG(5,(" = %s\n", alias_name));
+ return 0x0;
}
- fstrcpy(alias_name, mapped);
- DEBUG(5,(" = %s\n", alias_name));
- return 0x0;
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup_alias_sid
+ lookup_alias_name
********************************************************************/
-uint32 lookup_alias_sid(DOM_SID *sid, char *alias_name, uint8 *type)
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint8 *type)
{
- pstring sid_str;
- uint32 rid;
- DOM_SID tmp;
- LOCAL_GRP *als = NULL;
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
(*type) = SID_NAME_ALIAS;
- sid_to_string(sid_str, sid);
- DEBUG(5,("lookup_alias_sid: sid: %s", sid_str));
+ DEBUG(2,("lookup_alias_name: rid: %d\n", rid));
+ DEBUG(2,(" NOT IMPLEMENTED\n"));
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
- if (!sid_equal(&global_sam_sid, &tmp))
+/*******************************************************************
+ lookup well-known user name
+ ********************************************************************/
+uint32 lookup_wk_user_name(uint32 rid, char *user_name, uint8 *type)
+{
+ int i = 0;
+ (*type) = SID_NAME_USER;
+
+ DEBUG(5,("lookup_wk_user_name: rid: %d", rid));
+
+ /* look up the well-known domain user rids first */
+ while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
{
- DEBUG(5,("not our SID\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ i++;
}
- als = getaliasrid(rid, NULL, NULL);
-
- if (als != NULL)
+ if (domain_user_rids[i].rid != 0)
{
- fstrcpy(alias_name, als->name);
- DEBUG(5,(" = %s\n", alias_name));
+ fstrcpy(user_name, domain_user_rids[i].name);
+ DEBUG(5,(" = %s\n", user_name));
return 0x0;
}
DEBUG(5,(" none mapped\n"));
- return status;
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup well-known user name
+ lookup user name
********************************************************************/
-uint32 lookup_wk_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
+uint32 lookup_user_name(uint32 rid, char *user_name, uint8 *type)
{
- uint32 rid;
- DOM_SID tmp;
- char *mapped;
-
+ struct sam_disp_info *disp_info;
(*type) = SID_NAME_USER;
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ DEBUG(5,("lookup_user_name: rid: %d", rid));
- if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+ /* find the user account */
+ become_root(True);
+ disp_info = getsamdisprid(rid);
+ unbecome_root(True);
+
+ if (disp_info != NULL)
{
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ fstrcpy(user_name, disp_info->smb_name);
+ DEBUG(5,(" = %s\n", user_name));
+ return 0x0;
}
- DEBUG(5,("lookup_wk_user_sid: rid: %d", rid));
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
- /* look up the well-known domain user rids first */
- mapped = lookup_wk_user_rid(rid);
- if(mapped == NULL)
+/*******************************************************************
+ lookup_group_rid
+ ********************************************************************/
+uint32 lookup_group_rid(char *group_name, uint32 *rid, uint8 *type)
+{
+ DOM_SID sid;
+
+ (*rid) = 0;
+ (*type) = SID_NAME_DOM_GRP;
+
+ DEBUG(5,("lookup_group_rid: name: %s", group_name));
+
+ if (map_group_name_to_sid(group_name, &sid) &&
+ sid_split_rid(&sid, rid) &&
+ sid_equal(&sid, &global_sam_sid))
{
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ DEBUG(5,(" = 0x%x\n", (*rid)));
+ return 0x0;
}
- fstrcpy(user_name, mapped);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup user name
+ lookup_wk_group_rid
********************************************************************/
-uint32 lookup_user_sid(DOM_SID *sid, char *user_name, uint8 *type)
+uint32 lookup_wk_group_rid(char *group_name, uint32 *rid, uint8 *type)
{
- struct sam_disp_info *disp_info;
- uint32 rid;
- DOM_SID tmp;
+ char *grp_name;
+ int i = -1; /* start do loop at -1 */
+ (*rid) = 0;
+ (*type) = SID_NAME_WKN_GRP;
- (*type) = SID_NAME_USER;
+ do /* find, if it exists, a group rid for the group name */
+ {
+ i++;
+ (*rid) = domain_group_rids[i].rid;
+ grp_name = domain_group_rids[i].name;
- sid_copy(&tmp, sid);
- sid_split_rid(&tmp, &rid);
+ } while (grp_name != NULL && !strequal(grp_name, group_name));
- if (sid_equal(&global_sam_sid, &tmp))
- {
- DEBUG(5,("lookup_user_sid in SAM %s: rid: %d",
- global_sam_name, rid));
+ return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
- /* find the user account */
- become_root(True);
- disp_info = getsamdisprid(rid);
- unbecome_root(True);
+/*******************************************************************
+ lookup_alias_sid
+ ********************************************************************/
+uint32 lookup_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
+{
+ (*type) = SID_NAME_ALIAS;
- if (disp_info != NULL)
- {
- fstrcpy(user_name, disp_info->nt_name);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
- }
+ DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
- DEBUG(5,(" none mapped\n"));
+ if (map_alias_name_to_sid(alias_name, sid))
+ {
+ fstring sid_str;
+ sid_to_string(sid_str, sid);
+ DEBUG(5,(" = %s\n", sid_str));
+ return 0x0;
}
+ DEBUG(5,(" none mapped\n"));
return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup_group_rid
+ lookup_alias_rid
********************************************************************/
-uint32 lookup_added_group_name(const char *grp_name, const char *domain,
- DOM_SID *sid, uint8 *type)
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
{
- DOMAIN_GRP *grp = NULL;
- (*type) = SID_NAME_DOM_GRP;
-
- DEBUG(5,("lookup_added_group_name: name: %s", grp_name));
+ DOM_SID sid;
- if (!strequal(domain, global_sam_name))
- {
- DEBUG(5,(" not our domain\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
+ (*rid) = 0;
+ (*type) = SID_NAME_ALIAS;
- grp = getgroupntnam(grp_name, NULL, NULL);
+ DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
- if (grp != NULL)
+ if (map_alias_name_to_sid(alias_name, &sid) &&
+ sid_split_rid(&sid, rid) &&
+ sid_equal(&sid, &global_sam_sid))
{
- sid_copy(sid, &global_sam_sid);
- sid_append_rid(sid, grp->rid);
-
- DEBUG(5,(" = 0x%x\n", grp->rid));
+ DEBUG(5,(" = 0x%x\n", (*rid)));
return 0x0;
}
@@ -428,41 +452,86 @@ uint32 lookup_added_group_name(const char *grp_name, const char *domain,
}
/*******************************************************************
- lookup_added_alias_name
+ lookup_wk_alias_sid
********************************************************************/
-uint32 lookup_added_alias_name(const char *als_name, const char *domain,
- DOM_SID *sid, uint8 *type)
+uint32 lookup_wk_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
{
- LOCAL_GRP *als = NULL;
+ char *als_name;
+ int i = 0;
+ uint32 rid;
(*type) = SID_NAME_ALIAS;
- DEBUG(5,("lookup_added_alias_name: name: %s\\%s", domain, als_name));
-
- if (!strequal(domain, global_sam_name))
+ do /* find, if it exists, a alias rid for the alias name*/
{
- DEBUG(5,(" not our domain\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
+ rid = builtin_alias_rids[i].rid;
+ als_name = builtin_alias_rids[i].name;
- als = getaliasntnam(als_name, NULL, NULL);
+ i++;
- if (als != NULL)
+ if (strequal(als_name, alias_name))
+ {
+ sid_copy(sid, &global_sid_S_1_5_20);
+ sid_append_rid(sid, rid);
+
+ return 0x0;
+ }
+
+ } while (als_name != NULL);
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_wk_alias_rid
+ ********************************************************************/
+uint32 lookup_wk_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
+{
+ char *als_name;
+ int i = -1; /* start do loop at -1 */
+ (*rid) = 0;
+ (*type) = SID_NAME_ALIAS;
+
+ do /* find, if it exists, a alias rid for the alias name*/
{
- sid_copy(sid, &global_sam_sid);
- sid_append_rid(sid, als->rid);
+ i++;
+ (*rid) = builtin_alias_rids[i].rid;
+ als_name = builtin_alias_rids[i].name;
- DEBUG(5,(" = 0x%x\n", als->rid));
- return 0x0;
+ } while (als_name != NULL && !strequal(als_name, alias_name));
+
+ return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_sid
+ ********************************************************************/
+uint32 lookup_sid(char *name, DOM_SID *sid, uint8 *type)
+{
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ fstring domain;
+ fstring user;
+
+ split_domain_name(name, domain, user);
+
+ if (!strequal(domain, global_sam_name))
+ {
+ DEBUG(0,("lookup_sid: remote domain %s not supported\n", domain));
+ return status;
}
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ status = (status != 0x0) ? lookup_wk_alias_sid(user, sid, type) : status;
+ status = (status != 0x0) ? lookup_alias_sid (user, sid, type) : status;
+#if 0
+ status = (status != 0x0) ? lookup_domain_sid (user, sid, type) : status;
+#endif
+
+ return status;
}
/*******************************************************************
lookup_added_user_rid
********************************************************************/
-uint32 lookup_added_user_rids(char *nt_name,
+uint32 lookup_added_user_rids(char *user_name,
uint32 *usr_rid, uint32 *grp_rid)
{
struct sam_passwd *sam_pass;
@@ -471,7 +540,7 @@ uint32 lookup_added_user_rids(char *nt_name,
/* find the user account */
become_root(True);
- sam_pass = getsam21pwntnam(nt_name);
+ sam_pass = getsam21pwnam(user_name);
unbecome_root(True);
if (sam_pass != NULL)
@@ -485,29 +554,22 @@ uint32 lookup_added_user_rids(char *nt_name,
}
/*******************************************************************
- lookup_added_user_name
+ lookup_added_user_rid
********************************************************************/
-static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
- DOM_SID *sid, uint8 *type)
+uint32 lookup_added_user_rid(char *user_name, uint32 *rid, uint8 *type)
{
struct sam_passwd *sam_pass;
+ (*rid) = 0;
(*type) = SID_NAME_USER;
- if (!strequal(domain, global_sam_name))
- {
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
-
/* find the user account */
become_root(True);
- sam_pass = getsam21pwntnam(nt_name);
+ sam_pass = getsam21pwnam(user_name);
unbecome_root(True);
if (sam_pass != NULL)
{
- sid_copy(sid, &global_sam_sid);
- sid_append_rid(sid, sam_pass->user_rid);
-
+ (*rid) = sam_pass->user_rid;
return 0x0;
}
@@ -515,52 +577,134 @@ static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
}
/*******************************************************************
- lookup_grp_name
+ lookup_wk_user_rid
********************************************************************/
-static uint32 lookup_grp_name(const char *name, const char *domain,
- DOM_SID *sid, uint8 *type)
+uint32 lookup_wk_user_rid(char *user_name, uint32 *rid, uint8 *type)
+{
+ char *usr_name;
+ int i = -1; /* start do loop at -1 */
+ (*rid) = 0;
+ (*type) = SID_NAME_USER;
+
+ do /* find, if it exists, a alias rid for the alias name*/
+ {
+ i++;
+ (*rid) = domain_user_rids[i].rid;
+ usr_name = domain_user_rids[i].name;
+
+ } while (usr_name != NULL && !strequal(usr_name, user_name));
+
+ return (usr_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_added_grp_rid
+ ********************************************************************/
+uint32 lookup_added_grp_rid(char *name, uint32 *rid, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_wk_group_name (name, domain, sid, type) : status;
- status = (status != 0x0) ? lookup_builtin_alias_name(name, domain, sid, type) : status;
- status = (status != 0x0) ? lookup_added_group_name (name, domain, sid, type) : status;
- status = (status != 0x0) ? lookup_added_alias_name (name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_group_rid(name, rid, type) : status;
+ status = (status != 0x0) ? lookup_alias_rid(name, rid, type) : status;
return status;
}
/*******************************************************************
- lookup_user_name
+ lookup_builtin_grp_rid
********************************************************************/
-static uint32 lookup_user_name(const char *name, const char *domain,
- DOM_SID *sid, uint8 *type)
+uint32 lookup_builtin_grp_rid(char *name, uint32 *rid, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_wk_user_name (name, domain, sid, type) : status;
- status = (status != 0x0) ? lookup_added_user_name(name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_wk_group_rid(name, rid, type) : status;
+ status = (status != 0x0) ? lookup_wk_alias_rid(name, rid, type) : status;
return status;
}
/*******************************************************************
- lookup_name
+ lookup_grp_rid
********************************************************************/
-uint32 lookup_name(char *name, DOM_SID *sid, uint8 *type)
+uint32 lookup_grp_rid(char *name, uint32 *rid, uint8 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- fstring domain;
- fstring user;
-
- split_domain_name(name, domain, user);
- status = (status != 0x0) ? lookup_user_name (user, domain, sid, type) : status;
- status = (status != 0x0) ? lookup_grp_name (user, domain, sid, type) : status;
-#if 0
- status = (status != 0x0) ? lookup_domain_name (domain, sid, type) : status;
-#endif
+ status = (status != 0x0) ? lookup_builtin_grp_rid(name, rid, type) : status;
+ status = (status != 0x0) ? lookup_added_grp_rid (name, rid, type) : status;
return status;
}
+/*******************************************************************
+ lookup_user_rid
+ ********************************************************************/
+uint32 lookup_user_rid(char *name, uint32 *rid, uint8 *type)
+{
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ status = (status != 0x0) ? lookup_wk_user_rid (name, rid, type) : status;
+ status = (status != 0x0) ? lookup_added_user_rid(name, rid, type) : status;
+
+ return status;
+}
+
+/*******************************************************************
+ lookup_rid
+ ********************************************************************/
+uint32 lookup_rid(char *name, uint32 *rid, uint8 *type)
+{
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ status = (status != 0x0) ? lookup_user_rid(name, rid, type) : status;
+ status = (status != 0x0) ? lookup_grp_rid (name, rid, type) : status;
+
+ return status;
+}
+
+/*******************************************************************
+ lookup_user_rids
+ ********************************************************************/
+uint32 lookup_user_rids(char *name, uint32 *usr_rid, uint32 *grp_rid)
+{
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ uint8 type;
+
+ /*
+ * try an ordinary user lookup
+ */
+
+ status = lookup_added_user_rids(name, usr_rid, grp_rid);
+ if (status == 0)
+ {
+ return status;
+ }
+
+ /*
+ * hm. must be a well-known user, in a well-known group.
+ */
+
+ status = lookup_wk_user_rid(name, usr_rid, &type);
+ if (status != 0 || type != SID_NAME_USER)
+ {
+ return status; /* ok, maybe not! */
+ }
+ if (type != SID_NAME_USER)
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED; /* users only... */
+ }
+
+ /*
+ * ok, got the user rid: now try the group rid
+ */
+
+ status = lookup_builtin_grp_rid(name, grp_rid, &type);
+ if (type == SID_NAME_DOM_GRP ||
+ type == SID_NAME_ALIAS ||
+ type == SID_NAME_WKN_GRP)
+ {
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+
+ return status;
+}
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index fbe83b02c8..7094d842b4 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -29,82 +29,87 @@
extern int DEBUGLEVEL;
extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
-extern DOM_SID global_member_sid;
extern fstring global_myworkgroup;
-extern DOM_SID global_sid_S_1_5_20;
+extern pstring global_myname;
/***************************************************************************
-lsa_reply_open_policy2
+ lsa_reply_open_policy2
***************************************************************************/
-static void lsa_reply_open_policy2(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy2(prs_struct *rdata)
{
+ int i;
LSA_R_OPEN_POL2 r_o;
ZERO_STRUCT(r_o);
/* set up the LSA QUERY INFO response */
+ for (i = 4; i < POL_HND_SIZE; i++)
+ r_o.pol.data[i] = i;
r_o.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (!open_policy_hnd(&r_o.pol))
- {
- r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
+ DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
+ return False;
}
- /* store the response in the SMB stream */
- lsa_io_r_open_pol2("", &r_o, rdata, 0);
+ return True;
}
/***************************************************************************
lsa_reply_open_policy
***************************************************************************/
-static void lsa_reply_open_policy(prs_struct *rdata)
+
+static BOOL lsa_reply_open_policy(prs_struct *rdata)
{
+ int i;
LSA_R_OPEN_POL r_o;
ZERO_STRUCT(r_o);
/* set up the LSA QUERY INFO response */
+ for (i = 4; i < POL_HND_SIZE; i++)
+ r_o.pol.data[i] = i;
r_o.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (!open_policy_hnd(&r_o.pol))
- {
- r_o.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
+ DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
+ return False;
}
- /* store the response in the SMB stream */
- lsa_io_r_open_pol("", &r_o, rdata, 0);
+ return True;
}
/***************************************************************************
-make_dom_query
+Init dom_query
***************************************************************************/
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+
+static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
{
fstring sid_str;
int domlen = strlen(dom_name);
- d_q->uni_dom_str_len = (domlen+1) * 2;
d_q->uni_dom_max_len = domlen * 2;
+ d_q->uni_dom_str_len = domlen * 2;
d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
/* this string is supposed to be character short */
- make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
- d_q->uni_domain_name.uni_max_len++;
+ init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
sid_to_string(sid_str, dom_sid);
- make_dom_sid2(&(d_q->dom_sid), dom_sid);
+ init_dom_sid2(&d_q->dom_sid, dom_sid);
}
/***************************************************************************
-lsa_reply_query_info
+ lsa_reply_enum_trust_dom
***************************************************************************/
+
static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
prs_struct *rdata,
uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
@@ -114,7 +119,7 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
ZERO_STRUCT(r_e);
/* set up the LSA QUERY INFO response */
- make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
+ init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
/* store the response in the SMB stream */
@@ -124,63 +129,53 @@ static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
/***************************************************************************
lsa_reply_query_info
***************************************************************************/
-static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
+
+static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
char *dom_name, DOM_SID *dom_sid)
{
LSA_R_QUERY_INFO r_q;
ZERO_STRUCT(r_q);
- /* get a (unique) handle. open a policy on it. */
- if (r_q.status == 0x0 && !open_policy_hnd(&q_q->pol))
- {
- r_q.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
- else
- {
- /* set up the LSA QUERY INFO response */
+ /* set up the LSA QUERY INFO response */
- r_q.undoc_buffer = 0x1;
- r_q.info_class = q_q->info_class;
+ r_q.undoc_buffer = 0x22000000; /* bizarre */
+ r_q.info_class = q_q->info_class;
- make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+ init_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+
+ r_q.status = 0x0;
- r_q.status = 0x0;
- }
/* store the response in the SMB stream */
- lsa_io_r_query("", &r_q, rdata, 0);
-}
+ if(!lsa_io_r_query("", &r_q, rdata, 0)) {
+ DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
+ return False;
+ }
+ return True;
+}
/***************************************************************************
-make_dom_ref - adds a domain if it's not already in, returns the index
- ***************************************************************************/
-static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
-
+ init_dom_ref - adds a domain if it's not already in, returns the index.
+***************************************************************************/
+
+static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
{
int num = 0;
int len;
- if (dom_name != NULL)
- {
- for (num = 0; num < ref->num_ref_doms_1; num++)
- {
+ if (dom_name != NULL) {
+ for (num = 0; num < ref->num_ref_doms_1; num++) {
fstring domname;
- unistr2_to_ascii(domname, &ref->ref_dom[num].uni_dom_name, sizeof(domname)-1);
+ fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
if (strequal(domname, dom_name))
- {
return num;
- }
}
-
- }
- else
- {
+ } else {
num = ref->num_ref_doms_1;
}
- if (num >= MAX_REF_DOMAINS)
- {
+ if (num >= MAX_REF_DOMAINS) {
/* index not found, already at maximum domain limit */
return -1;
}
@@ -190,95 +185,85 @@ static int make_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
ref->max_entries = MAX_REF_DOMAINS;
ref->num_ref_doms_2 = num+1;
- len = dom_name != NULL ? strlen(dom_name) : 0;
+ len = (dom_name != NULL) ? strlen(dom_name) : 0;
+ if(dom_name != NULL && len == 0)
+ len = 1;
- make_uni_hdr(&(ref->hdr_ref_dom[num].hdr_dom_name), len);
+ init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
- make_unistr2 (&(ref->ref_dom[num].uni_dom_name), dom_name, len);
- make_dom_sid2(&(ref->ref_dom[num].ref_dom ), dom_sid );
+ init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
+ init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
return num;
}
/***************************************************************************
-make_lsa_rid2s
+ init_lsa_rid2s
***************************************************************************/
-static void make_lsa_rid2s(DOM_R_REF *ref,
- DOM_RID2 *rid2,
+
+static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
uint32 *mapped_count)
{
int i;
int total = 0;
- (*mapped_count) = 0;
+ *mapped_count = 0;
SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
- for (i = 0; i < num_entries; i++)
- {
- uint32 status = 0x0;
- DOM_SID find_sid;
+ for (i = 0; i < num_entries; i++) {
+ BOOL status = False;
+ DOM_SID dom_sid;
DOM_SID sid;
uint32 rid = 0xffffffff;
int dom_idx = -1;
- fstring find_name;
- char *dom_name = NULL;
+ pstring full_name;
+ fstring dom_name;
+ fstring user;
uint8 sid_name_use = SID_NAME_UNKNOWN;
- unistr2_to_ascii(find_name, &name[i], sizeof(find_name)-1);
- dom_name = strdup(find_name);
+ pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
- if (map_domain_name_to_sid(&sid, &dom_name))
- {
- sid_name_use = SID_NAME_DOMAIN;
- dom_idx = make_dom_ref(ref, dom_name, &find_sid);
- }
+ /*
+ * Try and split the name into a DOMAIN and
+ * user component.
+ */
- if (lookup_name(find_name, &sid, &sid_name_use) == 0x0 &&
- sid_split_rid(&sid, &rid))
- {
- if (map_domain_sid_to_name(&sid, find_name))
- {
- dom_idx = make_dom_ref(ref, find_name, &sid);
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ split_domain_name(full_name, dom_name, user);
+
+ /*
+ * We only do anything with this name if we
+ * can map the Domain into a SID we know.
+ */
+
+ if (map_domain_name_to_sid(&dom_sid, dom_name)) {
+ dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
+
+ if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
+ status = True;
}
- if (status == 0x0)
- {
+ if (status)
(*mapped_count)++;
- }
- else
- {
+ else {
dom_idx = -1;
rid = 0xffffffff;
sid_name_use = SID_NAME_UNKNOWN;
}
- make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+ init_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
total++;
-
- if (dom_name != NULL)
- {
- free(dom_name);
- }
}
}
/***************************************************************************
-make_reply_lookup_names
+ init_reply_lookup_names
***************************************************************************/
-static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
- DOM_R_REF *ref, uint32 num_entries,
- DOM_RID2 *rid2, uint32 mapped_count)
+
+static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+ DOM_R_REF *ref, uint32 num_entries,
+ DOM_RID2 *rid2, uint32 mapped_count)
{
r_l->ptr_dom_ref = 1;
r_l->dom_ref = ref;
@@ -291,84 +276,74 @@ static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
r_l->mapped_count = mapped_count;
if (mapped_count == 0)
- {
r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
else
- {
r_l->status = 0x0;
- }
}
/***************************************************************************
-make_lsa_trans_names
+ Init lsa_trans_names.
***************************************************************************/
-static void make_lsa_trans_names(DOM_R_REF *ref,
- LSA_TRANS_NAME_ENUM *trn,
- int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
- uint32 *mapped_count)
+
+static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
+ int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS], uint32 *mapped_count)
{
+ extern DOM_SID global_sid_S_1_5_0x20; /* BUILTIN sid. */
int i;
int total = 0;
- (*mapped_count) = 0;
+ *mapped_count = 0;
SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
- for (i = 0; i < num_entries; i++)
- {
- uint32 status = 0x0;
+ for (i = 0; i < num_entries; i++) {
+ BOOL status = False;
DOM_SID find_sid = sid[i].sid;
- DOM_SID tmp_sid = sid[i].sid;
uint32 rid = 0xffffffff;
int dom_idx = -1;
fstring name;
fstring dom_name;
uint8 sid_name_use = 0;
-
- memset(dom_name, 0, sizeof(dom_name));
- memset(name , 0, sizeof(name ));
- if (map_domain_sid_to_name(&find_sid, dom_name))
- {
+ memset(dom_name, '\0', sizeof(dom_name));
+ memset(name, '\0', sizeof(name));
+
+ /*
+ * First, check to see if the SID is one of the well
+ * known ones (this includes our own domain SID).
+ * Next, check if the domain prefix is one of the
+ * well known ones. If so and the domain prefix was
+ * either BUILTIN or our own global sid, then lookup
+ * the RID as a user or group id and translate to
+ * a name.
+ */
+
+ if (map_domain_sid_to_name(&find_sid, dom_name)) {
sid_name_use = SID_NAME_DOMAIN;
- dom_idx = make_dom_ref(ref, dom_name, &find_sid);
- }
- else if (sid_split_rid (&find_sid, &rid) &&
- map_domain_sid_to_name(&find_sid, dom_name))
- {
+ } else if (sid_split_rid(&find_sid, &rid) && map_domain_sid_to_name(&find_sid, dom_name)) {
if (sid_equal(&find_sid, &global_sam_sid) ||
- sid_equal(&find_sid, &global_sid_S_1_5_20))
- {
- /* lkclXXXX REPLACE THIS FUNCTION WITH
- samr_xxxx() routines
- */
- status = lookup_sid(&tmp_sid, name, &sid_name_use);
+ sid_equal(&find_sid, &global_sid_S_1_5_0x20)) {
+ status = lookup_local_rid(rid, name, &sid_name_use);
+ } else {
+ status = lookup_known_rid(&find_sid, rid, name, &sid_name_use);
}
- else
- {
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+ DEBUG(10,("init_lsa_trans_names: adding domain '%s' sid %s to referenced list.\n",
+ dom_name, name ));
- if (status == 0x0)
- {
- (*mapped_count)++;
- }
- else
- {
- snprintf(name, sizeof(name), "%08x", rid);
- sid_name_use = SID_NAME_UNKNOWN;
+ dom_idx = init_dom_ref(ref, dom_name, &find_sid);
+ if(!status) {
+ slprintf(name, sizeof(name)-1, "unix.%08x", rid);
+ sid_name_use = SID_NAME_UNKNOWN;
}
- make_lsa_trans_name(&(trn->name [total]),
- &(trn->uni_name[total]),
- sid_name_use, name, dom_idx);
+
+ DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to referenced list.\n", dom_name, name ));
+
+ (*mapped_count)++;
+
+ init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
+ sid_name_use, name, dom_idx);
total++;
}
@@ -378,11 +353,12 @@ static void make_lsa_trans_names(DOM_R_REF *ref,
}
/***************************************************************************
-make_reply_lookup_sids
+ Init_reply_lookup_sids.
***************************************************************************/
-static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
- DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
- uint32 mapped_count)
+
+static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+ DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+ uint32 mapped_count)
{
r_l->ptr_dom_ref = 1;
r_l->dom_ref = ref;
@@ -390,20 +366,16 @@ static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
r_l->mapped_count = mapped_count;
if (mapped_count == 0)
- {
r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
else
- {
r_l->status = 0x0;
- }
}
/***************************************************************************
lsa_reply_lookup_sids
***************************************************************************/
-static void lsa_reply_lookup_sids(prs_struct *rdata,
- DOM_SID2 *sid, int num_entries)
+
+static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
{
LSA_R_LOOKUP_SIDS r_l;
DOM_R_REF ref;
@@ -415,18 +387,24 @@ static void lsa_reply_lookup_sids(prs_struct *rdata,
ZERO_STRUCT(names);
/* set up the LSA Lookup SIDs response */
- make_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
- make_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
+ init_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
+ init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
/* store the response in the SMB stream */
- lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+ if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
+ DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
+ return False;
+ }
+
+ return True;
}
/***************************************************************************
lsa_reply_lookup_names
***************************************************************************/
-static void lsa_reply_lookup_names(prs_struct *rdata,
- UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
+
+static BOOL lsa_reply_lookup_names(prs_struct *rdata,
+ UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
{
LSA_R_LOOKUP_NAMES r_l;
DOM_R_REF ref;
@@ -435,20 +413,26 @@ static void lsa_reply_lookup_names(prs_struct *rdata,
ZERO_STRUCT(r_l);
ZERO_STRUCT(ref);
- ZERO_STRUCT(rids);
+ ZERO_ARRAY(rids);
/* set up the LSA Lookup RIDs response */
- make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
- make_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
+ init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+ init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
/* store the response in the SMB stream */
- lsa_io_r_lookup_names("", &r_l, rdata, 0);
+ if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
+ DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
+ return False;
+ }
+
+ return True;
}
/***************************************************************************
-api_lsa_open_policy
+ api_lsa_open_policy2
***************************************************************************/
-static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
+
+static BOOL api_lsa_open_policy2( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
LSA_Q_OPEN_POL2 q_o;
@@ -456,18 +440,24 @@ static void api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
ZERO_STRUCT(q_o);
/* grab the server, object attributes and desired access flag...*/
- lsa_io_q_open_pol2("", &q_o, data, 0);
+ if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
+ DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
+ return False;
+ }
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* return a 20 byte policy handle */
- lsa_reply_open_policy2(rdata);
+ if(!lsa_reply_open_policy2(rdata))
+ return False;
+
+ return True;
}
/***************************************************************************
api_lsa_open_policy
***************************************************************************/
-static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_policy( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
LSA_Q_OPEN_POL q_o;
@@ -475,18 +465,24 @@ static void api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
ZERO_STRUCT(q_o);
/* grab the server, object attributes and desired access flag...*/
- lsa_io_q_open_pol("", &q_o, data, 0);
+ if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
+ DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
+ return False;
+ }
/* lkclXXXX having decoded it, ignore all fields in the open policy! */
/* return a 20 byte policy handle */
- lsa_reply_open_policy(rdata);
+ if(!lsa_reply_open_policy(rdata))
+ return False;
+
+ return True;
}
/***************************************************************************
api_lsa_enum_trust_dom
***************************************************************************/
-static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_enum_trust_dom( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
LSA_Q_ENUM_TRUST_DOM q_e;
@@ -498,12 +494,14 @@ static void api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
/* construct reply. return status is always 0x0 */
lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
+
+ return True;
}
/***************************************************************************
api_lsa_query_info
***************************************************************************/
-static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_query_info( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
LSA_Q_QUERY_INFO q_i;
@@ -514,119 +512,118 @@ static void api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
ZERO_STRUCT(q_i);
/* grab the info class and policy handle */
- lsa_io_q_query("", &q_i, data, 0);
-
- switch (q_i.info_class)
- {
- case 0x03:
- {
- fstrcpy(name, global_myworkgroup);
- sid = &global_member_sid;
- break;
- }
- case 0x05:
- {
- fstrcpy(name, global_sam_name);
- sid = &global_sam_sid;
- break;
- }
- default:
- {
- DEBUG(5,("unknown info level in Lsa Query: %d\n",
- q_i.info_class));
- break;
- }
+ if(!lsa_io_q_query("", &q_i, data, 0)) {
+ DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
+ return False;
+ }
+
+ switch (q_i.info_class) {
+ case 0x03:
+ fstrcpy(name, global_myworkgroup);
+ sid = &global_sam_sid;
+ break;
+ case 0x05:
+ fstrcpy(name, global_myname);
+ sid = &global_sam_sid;
+ break;
+ default:
+ DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
+ break;
}
/* construct reply. return status is always 0x0 */
- lsa_reply_query_info(&q_i, rdata, name, sid);
+ if(!lsa_reply_query_info(&q_i, rdata, name, sid))
+ return False;
+
+ return True;
}
/***************************************************************************
-api_lsa_lookup_sids
+ api_lsa_lookup_sids
***************************************************************************/
-static void api_lsa_lookup_sids( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+
+static BOOL api_lsa_lookup_sids( uint16 vuid, prs_struct *data, prs_struct *rdata )
{
LSA_Q_LOOKUP_SIDS q_l;
ZERO_STRUCT(q_l);
/* grab the info class and policy handle */
- lsa_io_q_lookup_sids("", &q_l, data, 0);
+ if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
+ DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
+ return False;
+ }
/* construct reply. return status is always 0x0 */
- lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries);
+ if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries))
+ return False;
+
+ return True;
}
/***************************************************************************
-api_lsa_lookup_names
+ api_lsa_lookup_names
***************************************************************************/
-static void api_lsa_lookup_names( rpcsrv_struct *p, prs_struct *data,
- prs_struct *rdata )
+
+static BOOL api_lsa_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata )
{
LSA_Q_LOOKUP_NAMES q_l;
ZERO_STRUCT(q_l);
/* grab the info class and policy handle */
- lsa_io_q_lookup_names("", &q_l, data, 0);
+ if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
+ DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
+ return False;
+ }
SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
- lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
+ return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
}
/***************************************************************************
api_lsa_close
***************************************************************************/
-static void api_lsa_close( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_close( uint16 vuid, prs_struct *data,
prs_struct *rdata)
{
LSA_R_CLOSE r_c;
- LSA_Q_CLOSE q_c;
-
- lsa_io_q_close("", &q_c, data, 0);
ZERO_STRUCT(r_c);
- r_c.status = 0x0;
-
- /* find the connection policy handle. */
- if (r_c.status == 0x0 && (find_policy_by_hnd(&(q_c.pol)) == -1))
- {
- r_c.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- if (r_c.status == 0x0)
- {
- close_policy_hnd(&(q_c.pol));
+ /* store the response in the SMB stream */
+ if (!lsa_io_r_close("", &r_c, rdata, 0)) {
+ DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
+ return False;
}
- /* store the response in the SMB stream */
- lsa_io_r_close("", &r_c, rdata, 0);
+ return True;
}
/***************************************************************************
api_lsa_open_secret
***************************************************************************/
-static void api_lsa_open_secret( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_lsa_open_secret( uint16 vuid, prs_struct *data,
prs_struct *rdata)
{
/* XXXX this is NOT good */
- char *q = mem_data(&(rdata->data), rdata->offset);
-
- SIVAL(q, 0, 0);
- q += 4;
- SIVAL(q, 0, 0);
- q += 4;
- SIVAL(q, 0, 0);
- q += 4;
- SIVAL(q, 0, 0);
- q += 4;
- SIVAL(q, 0, 0);
- q += 4;
- SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND);
- q += 4;
-
- rdata->offset += 24;
+ size_t i;
+ uint32 dummy = 0;
+
+ for(i =0; i < 4; i++) {
+ if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+ DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
+ (int)i ));
+ return False;
+ }
+ }
+
+ dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
+ DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
+ return False;
+ }
+
+ return True;
}
/***************************************************************************
@@ -648,7 +645,7 @@ static struct api_struct api_lsa_cmds[] =
/***************************************************************************
api_ntLsarpcTNP
***************************************************************************/
-BOOL api_ntlsa_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
}
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index b895fb31c0..24aec701f0 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -31,11 +31,6 @@ extern int DEBUGLEVEL;
#define MAX_OPEN_POLS 64
#endif
-#define POL_NO_INFO 0
-#define POL_REG_INFO 1
-#define POL_SAMR_INFO 2
-#define POL_CLI_INFO 3
-
struct reg_info
{
/* for use by \PIPE\winreg */
@@ -50,27 +45,17 @@ struct samr_info
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
};
-struct con_info
-{
- struct cli_connection *con;
- void (*free)(struct cli_connection*);
-};
-
static struct policy
{
struct policy *next, *prev;
int pnum;
BOOL open;
POLICY_HND pol_hnd;
- int type;
union {
- struct samr_info *samr;
- struct reg_info *reg;
- struct con_info *con;
-
+ struct samr_info samr;
+ struct reg_info reg;
} dev;
-
} *Policy;
static struct bitmap *bmap;
@@ -100,17 +85,18 @@ static void create_pol_hnd(POLICY_HND *hnd)
/****************************************************************************
initialise policy handle states...
****************************************************************************/
-BOOL init_policy_hnd(int num_pol_hnds)
+void init_lsa_policy_hnd(void)
{
- bmap = bitmap_allocate(num_pol_hnds);
-
- return bmap != NULL;
+ bmap = bitmap_allocate(MAX_OPEN_POLS);
+ if (!bmap) {
+ exit_server("out of memory in init_lsa_policy_hnd\n");
+ }
}
/****************************************************************************
find first available policy slot. creates a policy handle for you.
****************************************************************************/
-BOOL register_policy_hnd(POLICY_HND *hnd)
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd)
{
int i;
struct policy *p;
@@ -132,8 +118,8 @@ BOOL register_policy_hnd(POLICY_HND *hnd)
p->open = True;
p->pnum = i;
- p->type = POL_NO_INFO;
+ create_pol_hnd(hnd);
memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
bitmap_set(bmap, i);
@@ -147,32 +133,22 @@ BOOL register_policy_hnd(POLICY_HND *hnd)
}
/****************************************************************************
- find first available policy slot. creates a policy handle for you.
-****************************************************************************/
-BOOL open_policy_hnd(POLICY_HND *hnd)
-{
- create_pol_hnd(hnd);
- return register_policy_hnd(hnd);
-}
-
-/****************************************************************************
find policy by handle
****************************************************************************/
-static struct policy *find_policy(const POLICY_HND *hnd)
+static struct policy *find_lsa_policy(POLICY_HND *hnd)
{
struct policy *p;
for (p=Policy;p;p=p->next) {
if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
DEBUG(4,("Found policy hnd[%x] ", p->pnum));
- dump_data(4, (const char *)hnd->data,
- sizeof(hnd->data));
+ dump_data(4, (char *)hnd->data, sizeof(hnd->data));
return p;
}
}
DEBUG(4,("Policy not found: "));
- dump_data(4, (const char *)hnd->data, sizeof(hnd->data));
+ dump_data(4, (char *)hnd->data, sizeof(hnd->data));
return NULL;
}
@@ -180,9 +156,9 @@ static struct policy *find_policy(const POLICY_HND *hnd)
/****************************************************************************
find policy index by handle
****************************************************************************/
-int find_policy_by_hnd(const POLICY_HND *hnd)
+int find_lsa_policy_by_hnd(POLICY_HND *hnd)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
return p?p->pnum:-1;
}
@@ -190,24 +166,15 @@ int find_policy_by_hnd(const POLICY_HND *hnd)
/****************************************************************************
set samr rid
****************************************************************************/
-BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
- if (p && p->open)
- {
+ if (p && p->open) {
DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
rid, p->pnum));
- if (p->dev.samr == NULL)
- {
- p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
- }
- if (p->dev.samr == NULL)
- {
- return False;
- }
- p->dev.samr->rid = rid;
+ p->dev.samr.rid = rid;
return True;
}
@@ -219,25 +186,15 @@ BOOL set_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
/****************************************************************************
set samr pol status. absolutely no idea what this is.
****************************************************************************/
-BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
- if (p && p->open)
- {
+ if (p && p->open) {
DEBUG(3,("Setting policy status=%x pnum=%x\n",
pol_status, p->pnum));
- if (p->dev.samr == NULL)
- {
- p->type = POL_SAMR_INFO;
- p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
- }
- if (p->dev.samr == NULL)
- {
- return False;
- }
- p->dev.samr->status = pol_status;
+ p->dev.samr.status = pol_status;
return True;
}
@@ -249,25 +206,16 @@ BOOL set_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
/****************************************************************************
set samr sid
****************************************************************************/
-BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
{
- pstring sidstr;
- struct policy *p = find_policy(hnd);
+ fstring sidstr;
+ struct policy *p = find_lsa_policy(hnd);
if (p && p->open) {
DEBUG(3,("Setting policy sid=%s pnum=%x\n",
sid_to_string(sidstr, sid), p->pnum));
- if (p->dev.samr == NULL)
- {
- p->type = POL_SAMR_INFO;
- p->dev.samr = (struct samr_info*)malloc(sizeof(*p->dev.samr));
- }
- if (p->dev.samr == NULL)
- {
- return False;
- }
- memcpy(&p->dev.samr->sid, sid, sizeof(*sid));
+ memcpy(&p->dev.samr.sid, sid, sizeof(*sid));
return True;
}
@@ -279,14 +227,14 @@ BOOL set_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
/****************************************************************************
get samr sid
****************************************************************************/
-BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
if (p != NULL && p->open)
{
- pstring sidstr;
- memcpy(sid, &p->dev.samr->sid, sizeof(*sid));
+ fstring sidstr;
+ memcpy(sid, &p->dev.samr.sid, sizeof(*sid));
DEBUG(3,("Getting policy sid=%s pnum=%x\n",
sid_to_string(sidstr, sid), p->pnum));
@@ -300,12 +248,12 @@ BOOL get_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
/****************************************************************************
get samr rid
****************************************************************************/
-uint32 get_policy_samr_rid(POLICY_HND *hnd)
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
if (p && p->open) {
- uint32 rid = p->dev.samr->rid;
+ uint32 rid = p->dev.samr.rid;
DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
rid, p->pnum));
@@ -319,116 +267,30 @@ uint32 get_policy_samr_rid(POLICY_HND *hnd)
/****************************************************************************
set reg name
****************************************************************************/
-BOOL set_policy_reg_name(POLICY_HND *hnd, fstring name)
-{
- struct policy *p = find_policy(hnd);
-
- if (p && p->open)
- {
- DEBUG(3,("Getting policy pnum=%x\n",
- p->pnum));
-
- if (p->dev.reg == NULL)
- {
- p->type = POL_REG_INFO;
- p->dev.reg = (struct reg_info*)malloc(sizeof(*p->dev.reg));
- }
- if (p->dev.reg == NULL)
- {
- return False;
- }
- fstrcpy(p->dev.reg->name, name);
- return True;
- }
-
- DEBUG(3,("Error setting policy name=%s\n", name));
- return False;
-}
-
-/****************************************************************************
- set reg name
-****************************************************************************/
-BOOL get_policy_reg_name(POLICY_HND *hnd, fstring name)
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
- if (p && p->open)
- {
+ if (p && p->open) {
DEBUG(3,("Setting policy pnum=%x name=%s\n",
p->pnum, name));
- fstrcpy(name, p->dev.reg->name);
- DEBUG(5,("getting policy reg name=%s\n", name));
- return True;
- }
-
- DEBUG(3,("Error getting policy reg name\n"));
- return False;
-}
-
-/****************************************************************************
- set con state
-****************************************************************************/
-BOOL set_policy_con(POLICY_HND *hnd, struct cli_connection *con,
- void (*free_fn)(struct cli_connection *))
-{
- struct policy *p = find_policy(hnd);
-
- if (p && p->open)
- {
- DEBUG(3,("Setting policy con state pnum=%x\n", p->pnum));
-
- if (p->dev.con == NULL)
- {
- p->type = POL_CLI_INFO;
- p->dev.con = (struct con_info*)malloc(sizeof(*p->dev.con));
- }
- if (p->dev.con == NULL)
- {
- return False;
- }
- p->dev.con->con = con;
- p->dev.con->free = free_fn;
+ fstrcpy(p->dev.reg.name, name);
return True;
}
- DEBUG(3,("Error setting policy con state\n"));
-
- return False;
-}
-
-/****************************************************************************
- get con state
-****************************************************************************/
-BOOL get_policy_con(const POLICY_HND *hnd, struct cli_connection **con)
-{
- struct policy *p = find_policy(hnd);
-
- if (p != NULL && p->open)
- {
- DEBUG(3,("Getting con state pnum=%x\n", p->pnum));
-
- if (con != NULL)
- {
- (*con ) = p->dev.con->con;
- }
-
- return True;
- }
-
- DEBUG(3,("Error getting policy\n"));
+ DEBUG(3,("Error setting policy name=%s\n", name));
return False;
}
/****************************************************************************
close an lsa policy
****************************************************************************/
-BOOL close_policy_hnd(POLICY_HND *hnd)
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd)
{
- struct policy *p = find_policy(hnd);
+ struct policy *p = find_lsa_policy(hnd);
- if (!p)
- {
+ if (!p) {
DEBUG(3,("Error closing policy\n"));
return False;
}
@@ -440,33 +302,8 @@ BOOL close_policy_hnd(POLICY_HND *hnd)
bitmap_clear(bmap, p->pnum);
ZERO_STRUCTP(p);
- ZERO_STRUCTP(hnd);
-
- switch (p->type)
- {
- case POL_REG_INFO:
- {
- free(p->dev.reg);
- break;
- }
- case POL_SAMR_INFO:
- {
- free(p->dev.samr);
- break;
- }
- case POL_CLI_INFO:
- {
- if (p->dev.con->free != NULL)
- {
- p->dev.con->free(p->dev.con->con);
- }
- free(p->dev.con);
- break;
- }
- }
free(p);
return True;
}
-
diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c
index 9721b3bf00..c0233d80c6 100644
--- a/source3/rpc_server/srv_netlog.c
+++ b/source3/rpc_server/srv_netlog.c
@@ -1,3 +1,4 @@
+
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
@@ -28,17 +29,19 @@
extern int DEBUGLEVEL;
+extern BOOL sam_logon_in_ssb;
+extern pstring samlogon_user;
extern pstring global_myname;
extern DOM_SID global_sam_sid;
-extern fstring global_sam_name;
/*************************************************************************
- make_net_r_req_chal:
+ init_net_r_req_chal:
*************************************************************************/
-static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
+
+static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
DOM_CHAL *srv_chal, int status)
{
- DEBUG(6,("make_net_r_req_chal: %d\n", __LINE__));
+ DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
r_c->status = status;
}
@@ -46,7 +49,8 @@ static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
/*************************************************************************
net_reply_req_chal:
*************************************************************************/
-static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
+
+static BOOL net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
DOM_CHAL *srv_chal, uint32 srv_time)
{
NET_R_REQ_CHAL r_c;
@@ -54,19 +58,24 @@ static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
/* set up the LSA REQUEST CHALLENGE response */
- make_net_r_req_chal(&r_c, srv_chal, srv_time);
+ init_net_r_req_chal(&r_c, srv_chal, srv_time);
/* store the response in the SMB stream */
- net_io_r_req_chal("", &r_c, rdata, 0);
+ if(!net_io_r_req_chal("", &r_c, rdata, 0)) {
+ DEBUG(0,("net_reply_req_chal: Failed to marshall NET_R_REQ_CHAL.\n"));
+ return False;
+ }
DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
+ return True;
}
/*************************************************************************
net_reply_logon_ctrl2:
*************************************************************************/
-static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
+
+static BOOL net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
uint32 flags, uint32 pdc_status, uint32 logon_attempts,
uint32 tc_status, char *trust_domain_name)
{
@@ -75,80 +84,63 @@ static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
/* set up the Logon Control2 response */
- make_r_logon_ctrl2(&r_l, q_l->query_level,
+ init_r_logon_ctrl2(&r_l, q_l->query_level,
flags, pdc_status, logon_attempts,
tc_status, trust_domain_name);
/* store the response in the SMB stream */
- net_io_r_logon_ctrl2("", &r_l, rdata, 0);
+ if(!net_io_r_logon_ctrl2("", &r_l, rdata, 0)) {
+ DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
+ return False;
+ }
DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
+ return True;
}
/*************************************************************************
net_reply_trust_dom_list:
*************************************************************************/
-static void net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
- uint32 num_trust_domains, char **trust_domain_name)
+
+static BOOL net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
+ uint32 num_trust_domains, char *trust_domain_name)
{
NET_R_TRUST_DOM_LIST r_t;
DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
/* set up the Trusted Domain List response */
- make_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
+ init_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
/* store the response in the SMB stream */
- net_io_r_trust_dom("", &r_t, rdata, 0);
+ if(!net_io_r_trust_dom("", &r_t, rdata, 0)) {
+ DEBUG(0,("net_reply_trust_dom_list: Failed to marshall NET_R_TRUST_DOM_LIST.\n"));
+ return False;
+ }
- DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
+ DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
+ return True;
}
-
/*************************************************************************
- make_net_r_auth:
+ init_net_r_auth_2:
*************************************************************************/
-static void make_net_r_auth(NET_R_AUTH *r_a,
- DOM_CHAL *resp_cred, int status)
-{
- memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
- r_a->status = status;
-}
-/*************************************************************************
- net_reply_auth:
- *************************************************************************/
-static void net_reply_auth(NET_Q_AUTH *q_a, prs_struct *rdata,
- DOM_CHAL *resp_cred, int status)
-{
- NET_R_AUTH r_a;
-
- /* set up the LSA AUTH 2 response */
-
- make_net_r_auth(&r_a, resp_cred, status);
-
- /* store the response in the SMB stream */
- net_io_r_auth("", &r_a, rdata, 0);
-
-}
-
-/*************************************************************************
- make_net_r_auth_2:
- *************************************************************************/
-static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
+static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
{
- memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
- memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
+ memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
+ memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
r_a->status = status;
}
-/*************************************************************************
+/************************************************************************
net_reply_auth_2:
*************************************************************************/
-static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
+
+static BOOL net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
DOM_CHAL *resp_cred, int status)
{
NET_R_AUTH_2 r_a;
@@ -158,31 +150,37 @@ static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
/* set up the LSA AUTH 2 response */
- make_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
+ init_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
/* store the response in the SMB stream */
- net_io_r_auth_2("", &r_a, rdata, 0);
+ if(!net_io_r_auth_2("", &r_a, rdata, 0)) {
+ DEBUG(0,("net_reply_auth_2: Failed to marshall NET_R_AUTH_2.\n"));
+ return False;
+ }
+ return True;
}
/***********************************************************************************
- make_net_r_srv_pwset:
+ init_net_r_srv_pwset:
***********************************************************************************/
-static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
+
+static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
DOM_CRED *srv_cred, int status)
{
- DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+ DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
- memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
+ memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred));
r_s->status = status;
- DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+ DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
}
/*************************************************************************
net_reply_srv_pwset:
*************************************************************************/
-static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
+
+static BOOL net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
DOM_CRED *srv_cred, int status)
{
NET_R_SRV_PWSET r_s;
@@ -190,19 +188,24 @@ static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
/* set up the LSA Server Password Set response */
- make_net_r_srv_pwset(&r_s, srv_cred, status);
+ init_net_r_srv_pwset(&r_s, srv_cred, status);
/* store the response in the SMB stream */
- net_io_r_srv_pwset("", &r_s, rdata, 0);
+ if(!net_io_r_srv_pwset("", &r_s, rdata, 0)) {
+ DEBUG(0,("net_reply_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n"));
+ return False;
+ }
DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
+ return True;
}
/*************************************************************************
net_reply_sam_logon:
*************************************************************************/
-static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
+
+static BOOL net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
uint32 status)
{
@@ -210,32 +213,33 @@ static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
/* XXXX maybe we want to say 'no', reject the client's credentials */
r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+ memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
/* store the user information, if there is any. */
r_s.user = user_info;
if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
- {
r_s.switch_value = 3; /* indicates type of validation user info */
- }
else
- {
r_s.switch_value = 0; /* indicates no info */
- }
r_s.status = status;
r_s.auth_resp = 1; /* authoritative response */
/* store the response in the SMB stream */
- net_io_r_sam_logon("", &r_s, rdata, 0);
+ if(!net_io_r_sam_logon("", &r_s, rdata, 0)) {
+ DEBUG(0,("net_reply_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n"));
+ return False;
+ }
+ return True;
}
/*************************************************************************
net_reply_sam_logoff:
*************************************************************************/
-static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
+
+static BOOL net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
DOM_CRED *srv_cred,
uint32 status)
{
@@ -243,63 +247,23 @@ static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
/* XXXX maybe we want to say 'no', reject the client's credentials */
r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+ memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
r_s.status = status;
/* store the response in the SMB stream */
- net_io_r_sam_logoff("", &r_s, rdata, 0);
-
-}
-
-/*************************************************************************
- net_reply_sam_sync:
- *************************************************************************/
-static void net_reply_sam_sync(NET_Q_SAM_SYNC *q_s, prs_struct *rdata,
- uint8 sess_key[16],
- DOM_CRED *srv_creds, uint32 status)
-{
- NET_R_SAM_SYNC r_s;
- int i = 0;
- struct sam_passwd *pwd;
- void *vp;
-
- memcpy(&(r_s.srv_creds), srv_creds, sizeof(r_s.srv_creds));
- r_s.sync_context = 1;
- r_s.ptr_deltas = 0;
-
- if ((status == 0x0) && ((vp = startsmbpwent(False)) != NULL))
- {
- /* Give the poor BDC some accounts */
-
- while (((pwd = getsam21pwent(vp)) != NULL) && (i < MAX_SAM_DELTAS))
- {
- make_sam_delta_hdr(&r_s.hdr_deltas[i], 5, pwd->user_rid);
- make_sam_account_info(&r_s.deltas[i].account_info,
- pwd->nt_name, pwd->full_name, pwd->user_rid,
- pwd->group_rid, pwd->home_dir, pwd->dir_drive,
- pwd->logon_script, pwd->acct_desc,
- pwd->acct_ctrl, pwd->profile_path);
-
- i++;
- }
-
- endsmbpwent(vp);
-
- r_s.ptr_deltas = r_s.ptr_deltas2 = 1;
- r_s.num_deltas = r_s.num_deltas2 = i;
+ if(!net_io_r_sam_logoff("", &r_s, rdata, 0)) {
+ DEBUG(0,("net_reply_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n"));
+ return False;
}
- r_s.status = status;
-
- /* store the response in the SMB stream */
- net_io_r_sam_sync("", sess_key, &r_s, rdata, 0);
-
+ return True;
}
/******************************************************************
gets a machine password entry. checks access rights of the host.
******************************************************************/
+
static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
{
struct smb_passwd *smb_pass;
@@ -334,13 +298,6 @@ static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
return True;
}
- if (strequal(mach_name, global_myname))
- {
- DEBUG(0,("get_md4pw: *** LOOPBACK DETECTED - USING NULL KEY ***\n"));
- memset(md4pw, 0, 16);
- return True;
- }
-
DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
return False;
}
@@ -348,9 +305,8 @@ static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
/*************************************************************************
api_net_req_chal:
*************************************************************************/
-static void api_net_req_chal( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
+
+static BOOL api_net_req_chal( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
NET_Q_REQ_CHAL q_r;
uint32 status = 0x0;
@@ -358,93 +314,60 @@ static void api_net_req_chal( rpcsrv_struct *p,
fstring mach_acct;
fstring mach_name;
- DEBUG(5,("api_net_req_chal(%d)\n", __LINE__));
+ user_struct *vuser;
+
+ DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return False;
/* grab the challenge... */
- net_io_q_req_chal("", &q_r, data, 0);
+ if(!net_io_q_req_chal("", &q_r, data, 0)) {
+ DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n"));
+ return False;
+ }
- unistr2_to_ascii(mach_acct, &q_r.uni_logon_clnt, sizeof(mach_acct)-1);
+ fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
+ q_r.uni_logon_clnt.uni_str_len));
fstrcpy(mach_name, mach_acct);
strlower(mach_name);
fstrcat(mach_acct, "$");
- if (get_md4pw((char *)p->dc.md4pw, mach_name, mach_acct))
- {
+ if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct)) {
/* copy the client credentials */
- memcpy(p->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
- memcpy(p->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+ memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+ memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
/* create a server challenge for the client */
/* Set these to random values. */
- generate_random_buffer(p->dc.srv_chal.data, 8, False);
+ generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
- memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
+ memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
- bzero(p->dc.sess_key, sizeof(p->dc.sess_key));
+ memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
/* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&(p->dc.clnt_chal), &(p->dc.srv_chal),
- (char *)p->dc.md4pw, p->dc.sess_key);
- }
- else
- {
+ cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
+ (char *)vuser->dc.md4pw, vuser->dc.sess_key);
+ } else {
/* lkclXXXX take a guess at a good error message to return :-) */
status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
}
/* construct reply. */
- net_reply_req_chal(&q_r, rdata,
- &(p->dc.srv_chal), status);
-
-}
-
-/*************************************************************************
- api_net_auth:
- *************************************************************************/
-static void api_net_auth( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
-{
- NET_Q_AUTH q_a;
- uint32 status = 0x0;
-
- DOM_CHAL srv_cred;
- UTIME srv_time;
-
- srv_time.time = 0;
-
- /* grab the challenge... */
- net_io_q_auth("", &q_a, data, 0);
-
- /* check that the client credentials are valid */
- if (cred_assert(&(q_a.clnt_chal), p->dc.sess_key,
- &(p->dc.clnt_cred.challenge), srv_time))
- {
-
- /* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &(p->dc.srv_cred.challenge), srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- }
- else
- {
- status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
- }
+ if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
+ return False;
- /* construct reply. */
- net_reply_auth(&q_a, rdata, &srv_cred, status);
+ return True;
}
/*************************************************************************
api_net_auth_2:
*************************************************************************/
-static void api_net_auth_2( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
+
+static BOOL api_net_auth_2( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
NET_Q_AUTH_2 q_a;
uint32 status = 0x0;
@@ -452,38 +375,46 @@ static void api_net_auth_2( rpcsrv_struct *p,
DOM_CHAL srv_cred;
UTIME srv_time;
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return False;
+
srv_time.time = 0;
/* grab the challenge... */
- net_io_q_auth_2("", &q_a, data, 0);
+ if(!net_io_q_auth_2("", &q_a, data, 0)) {
+ DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n"));
+ return False;
+ }
/* check that the client credentials are valid */
- if (cred_assert(&(q_a.clnt_chal), p->dc.sess_key,
- &(p->dc.clnt_cred.challenge), srv_time))
- {
+ if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
+ &(vuser->dc.clnt_cred.challenge), srv_time)) {
/* create server challenge for inclusion in the reply */
- cred_create(p->dc.sess_key, &(p->dc.srv_cred.challenge), srv_time, &srv_cred);
+ cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
/* copy the received client credentials for use next time */
- memcpy(p->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- memcpy(p->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- }
- else
- {
+ memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
+ memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
+ } else {
status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
}
/* construct reply. */
- net_reply_auth_2(&q_a, rdata, &srv_cred, status);
+ if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
+ return False;
+
+ return True;
}
+
/*************************************************************************
api_net_srv_pwset:
*************************************************************************/
-static void api_net_srv_pwset( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
+
+static BOOL api_net_srv_pwset( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
NET_Q_SRV_PWSET q_a;
uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
@@ -491,20 +422,27 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
pstring mach_acct;
struct smb_passwd *smb_pass;
BOOL ret;
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return False;
/* grab the challenge and encrypted password ... */
- net_io_q_srv_pwset("", &q_a, data, 0);
+ if(!net_io_q_srv_pwset("", &q_a, data, 0)) {
+ DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n"));
+ return False;
+ }
/* checks and updates credentials. creates reply credentials */
- if (deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred),
+ if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
&(q_a.clnt_id.cred), &srv_cred))
{
- memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred), sizeof(p->dc.clnt_cred));
+ memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
- unistr2_to_ascii(mach_acct, &q_a.clnt_id.login.uni_acct_name,
- sizeof(mach_acct)-1);
+ pstrcpy(mach_acct, dos_unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
+ q_a.clnt_id.login.uni_acct_name.uni_str_len));
DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
@@ -512,19 +450,16 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
smb_pass = getsmbpwnam(mach_acct);
unbecome_root(True);
- if (smb_pass != NULL)
- {
+ if (smb_pass != NULL) {
unsigned char pwd[16];
int i;
DEBUG(100,("Server password set : new given value was :\n"));
for(i = 0; i < 16; i++)
- {
DEBUG(100,("%02X ", q_a.pwd[i]));
- }
DEBUG(100,("\n"));
- cred_hash3( pwd, q_a.pwd, p->dc.sess_key, 0);
+ cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
/* lies! nt and lm passwords are _not_ the same: don't care */
smb_pass->smb_passwd = pwd;
@@ -535,8 +470,7 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
ret = mod_smbpwd_entry(smb_pass,False);
unbecome_root(True);
- if (ret)
- {
+ if (ret) {
/* hooray! */
status = 0x0;
}
@@ -544,83 +478,63 @@ static void api_net_srv_pwset( rpcsrv_struct *p,
DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
- }
- else
- {
+ } else {
/* lkclXXXX take a guess at a sensible error code to return... */
status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
}
/* Construct reply. */
- net_reply_srv_pwset(&q_a, rdata, &srv_cred, status);
+ if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
+ return False;
+
+ return True;
}
/*************************************************************************
api_net_sam_logoff:
*************************************************************************/
-static void api_net_sam_logoff( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
+
+static BOOL api_net_sam_logoff( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
NET_Q_SAM_LOGOFF q_l;
NET_ID_INFO_CTR ctr;
DOM_CRED srv_cred;
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return False;
+
/* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
dynamically allocate it inside net_io_q_sam_logon, at some point */
q_l.sam_id.ctr = &ctr;
/* grab the challenge... */
- net_io_q_sam_logoff("", &q_l, data, 0);
+ if(!net_io_q_sam_logoff("", &q_l, data, 0)) {
+ DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n"));
+ return False;
+ }
/* checks and updates credentials. creates reply credentials */
- deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred),
- &(q_l.sam_id.client.cred), &srv_cred);
- memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred), sizeof(p->dc.clnt_cred));
+ deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred,
+ &q_l.sam_id.client.cred, &srv_cred);
+ memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
/* construct reply. always indicate success */
- net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0);
-}
-
-/*************************************************************************
- api_net_sam_sync:
- *************************************************************************/
-static void api_net_sam_sync( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
-{
- NET_Q_SAM_SYNC q_s;
- DOM_CRED srv_creds;
- uint32 status = 0x0;
-
- /* grab the challenge... */
- net_io_q_sam_sync("", &q_s, data, 0);
-
- /* checks and updates credentials. creates reply credentials */
- if (deal_with_creds(p->dc.sess_key, &(p->dc.clnt_cred),
- &(q_s.cli_creds), &srv_creds))
- {
- memcpy(&(p->dc.srv_cred), &(p->dc.clnt_cred),
- sizeof(p->dc.clnt_cred));
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
- }
+ if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
+ return False;
- /* construct reply. */
- net_reply_sam_sync(&q_s, rdata, p->dc.sess_key, &srv_creds, status);
+ return True;
}
-
/*************************************************************************
net_login_interactive:
*************************************************************************/
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
- struct sam_passwd *smb_pass,
- struct dcinfo *dc)
+
+static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass,
+ user_struct *vuser)
{
uint32 status = 0x0;
@@ -629,14 +543,14 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
unsigned char key[16];
memset(key, 0, 16);
- memcpy(key, dc->sess_key, 8);
+ memcpy(key, vuser->dc.sess_key, 8);
memcpy(lm_pwd, id1->lm_owf.data, 16);
memcpy(nt_pwd, id1->nt_owf.data, 16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("key:"));
- dump_data(100, key, 16);
+ dump_data(100, (char *)key, 16);
DEBUG(100,("lm owf password:"));
dump_data(100, lm_pwd, 16);
@@ -645,8 +559,8 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
dump_data(100, nt_pwd, 16);
#endif
- SamOEMhash((uchar *)lm_pwd, key, 0);
- SamOEMhash((uchar *)nt_pwd, key, 0);
+ SamOEMhash((uchar *)lm_pwd, key, False);
+ SamOEMhash((uchar *)nt_pwd, key, False);
#ifdef DEBUG_PASSWORD
DEBUG(100,("decrypt of lm owf password:"));
@@ -656,14 +570,7 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
dump_data(100, nt_pwd, 16);
#endif
- if (smb_pass->smb_nt_passwd == NULL)
- {
- DEBUG(5,("warning: NETLOGON user %s only has an LM password\n",
- smb_pass->unix_name));
- }
-
if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
- smb_pass->smb_nt_passwd == NULL ||
memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
{
status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
@@ -675,52 +582,45 @@ static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
/*************************************************************************
net_login_network:
*************************************************************************/
-static uint32 net_login_network(NET_ID_INFO_2 *id2,
- struct sam_passwd *sam_pass,
- struct dcinfo *dc,
- char sess_key[16])
-{
- fstring user;
- fstring domain;
-
- int nt_pw_len = id2->hdr_nt_chal_resp.str_str_len;
- int lm_pw_len = id2->hdr_lm_chal_resp.str_str_len;
- unistr2_to_ascii(user , &id2->uni_user_name, sizeof(user)-1);
- unistr2_to_ascii(domain, &id2->uni_domain_name, sizeof(domain)-1);
+static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
+{
+ DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
+ id2->hdr_lm_chal_resp.str_str_len,
+ id2->hdr_nt_chal_resp.str_str_len));
- DEBUG(5,("net_login_network: lm_len:%d nt_len:%d user:%s domain:%s\n",
- lm_pw_len, nt_pw_len, user, domain));
+ /* JRA. Check the NT password first if it exists - this is a higher quality
+ password, if it exists and it doesn't match - fail. */
- if (pass_check_smb(pwdb_sam_to_smb(sam_pass),
- domain,
- id2->lm_chal,
- (uchar *)id2->lm_chal_resp.buffer, lm_pw_len,
- (uchar *)id2->nt_chal_resp.buffer, nt_pw_len,
- NULL, sess_key))
+ if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
+ smb_pass->smb_nt_passwd != NULL)
{
- unsigned char key[16];
-
- memset(key, 0, 16);
- memcpy(key, dc->sess_key, 8);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("key:"));
- dump_data(100, key, 16);
-
- DEBUG(100,("user sess key:"));
- dump_data(100, sess_key, 16);
-#endif
+ if(smb_password_check((char *)id2->nt_chal_resp.buffer,
+ smb_pass->smb_nt_passwd,
+ id2->lm_chal))
+ return 0x0;
+ else
+ return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ }
- SamOEMhash((uchar *)sess_key, key, 0);
+ /* lkclXXXX this is not a good place to put disabling of LM hashes in.
+ if that is to be done, first move this entire function into a
+ library routine that calls the two smb_password_check() functions.
+ if disabling LM hashes (which nt can do for security reasons) then
+ an attempt should be made to disable them everywhere (which nt does
+ not do, for various security-hole reasons).
+ */
+
+ if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
+ smb_password_check((char *)id2->lm_chal_resp.buffer,
+ smb_pass->smb_passwd,
+ id2->lm_chal))
+ {
+ return 0x0;
+ }
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("encrypt of user session key:"));
- dump_data(100, sess_key, 16);
-#endif
- return 0x0;
- }
+ /* oops! neither password check succeeded */
return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
}
@@ -728,242 +628,242 @@ static uint32 net_login_network(NET_ID_INFO_2 *id2,
/*************************************************************************
api_net_sam_logon:
*************************************************************************/
-static uint32 reply_net_sam_logon(NET_Q_SAM_LOGON *q_l,
- struct dcinfo *dc,
- DOM_CRED *srv_cred, NET_USER_INFO_3 *usr_info)
-{
- struct sam_passwd *sam_pass = NULL;
- UNISTR2 *uni_samusr = NULL;
- UNISTR2 *uni_domain = NULL;
- fstring nt_username;
- char *enc_user_sess_key = NULL;
- char sess_key[16];
-
- NTTIME logon_time ;
- NTTIME logoff_time ;
- NTTIME kickoff_time ;
- NTTIME pass_last_set_time ;
- NTTIME pass_can_change_time ;
- NTTIME pass_must_change_time;
-
- fstring nt_name ;
- fstring full_name ;
- fstring logon_script;
- fstring profile_path;
- fstring home_dir ;
- fstring dir_drive ;
-
- uint32 user_rid ;
- uint32 group_rid;
-
- int num_gids = 0;
- DOMAIN_GRP *grp_mem = NULL;
- DOM_GID *gids = NULL;
-
- /* checks and updates credentials. creates reply credentials */
- if (!deal_with_creds(dc->sess_key, &(dc->clnt_cred),
- &(q_l->sam_id.client.cred), srv_cred))
- {
- return 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- memcpy(&(dc->srv_cred), &(dc->clnt_cred), sizeof(dc->clnt_cred));
-
- /* find the username */
-
- switch (q_l->sam_id.logon_level)
- {
- case INTERACTIVE_LOGON_TYPE:
- {
- uni_samusr = &(q_l->sam_id.ctr->auth.id1.uni_user_name);
- uni_domain = &(q_l->sam_id.ctr->auth.id1.uni_domain_name);
-
- DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", global_sam_name));
- break;
- }
- case NET_LOGON_TYPE:
- {
- uni_samusr = &(q_l->sam_id.ctr->auth.id2.uni_user_name);
- uni_domain = &(q_l->sam_id.ctr->auth.id2.uni_domain_name);
-
- DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", global_sam_name));
- break;
- }
- default:
- {
- DEBUG(2,("SAM Logon: unsupported switch value\n"));
- return 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- }
-
- /* check username exists */
-
- unistr2_to_ascii(nt_username, uni_samusr,
- sizeof(nt_username)-1);
- DEBUG(3,("User:[%s]\n", nt_username));
-
- become_root(True);
- sam_pass = getsam21pwntnam(nt_username);
- unbecome_root(True);
-
- if (sam_pass == NULL)
- {
- return 0xC0000000 | NT_STATUS_NO_SUCH_USER;
- }
- else if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED) &&
- IS_BITS_CLR_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ))
- {
- return 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
- }
+static BOOL api_net_sam_logon( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ NET_Q_SAM_LOGON q_l;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 usr_info;
+ uint32 status = 0x0;
+ DOM_CRED srv_cred;
+ struct smb_passwd *smb_pass = NULL;
+ UNISTR2 *uni_samlogon_user = NULL;
+ fstring nt_username;
+
+ user_struct *vuser = NULL;
+
+ if ((vuser = get_valid_user_struct(vuid)) == NULL)
+ return False;
+
+ memset(&q_l, '\0', sizeof(q_l));
+ memset(&ctr, '\0', sizeof(ctr));
+ memset(&usr_info, '\0', sizeof(usr_info));
+
+ q_l.sam_id.ctr = &ctr;
+
+ if(!net_io_q_sam_logon("", &q_l, data, 0)) {
+ DEBUG(0,("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
+ return False;
+ }
+
+ /* checks and updates credentials. creates reply credentials */
+ if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
+ &(q_l.sam_id.client.cred), &srv_cred))
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ else
+ memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
+
+ /* find the username */
+
+ if (status == 0) {
+ switch (q_l.sam_id.logon_level) {
+ case INTERACTIVE_LOGON_TYPE:
+ uni_samlogon_user = &q_l.sam_id.ctr->auth.id1.uni_user_name;
+
+ DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
+ break;
+ case NET_LOGON_TYPE:
+ uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
+
+ DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
+ break;
+ default:
+ DEBUG(2,("SAM Logon: unsupported switch value\n"));
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ } /* end switch */
+ } /* end if status == 0 */
+
+ /* check username exists */
+
+ if (status == 0) {
+ pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
+ uni_samlogon_user->uni_str_len));
+
+ DEBUG(3,("User:[%s]\n", nt_username));
- logon_time = sam_pass->logon_time;
- logoff_time = sam_pass->logoff_time;
- kickoff_time = sam_pass->kickoff_time;
- pass_last_set_time = sam_pass->pass_last_set_time;
- pass_can_change_time = sam_pass->pass_can_change_time;
- pass_must_change_time = sam_pass->pass_must_change_time;
+ /*
+ * Convert to a UNIX username.
+ */
+ map_username(nt_username);
- fstrcpy(nt_name , sam_pass->nt_name);
- fstrcpy(full_name , sam_pass->full_name);
- fstrcpy(logon_script, sam_pass->logon_script);
- fstrcpy(profile_path, sam_pass->profile_path);
- fstrcpy(home_dir , sam_pass->home_dir);
- fstrcpy(dir_drive , sam_pass->dir_drive);
+ /*
+ * Do any case conversions.
+ */
+ (void)Get_Pwnam(nt_username, True);
+
+ become_root(True);
+ smb_pass = getsmbpwnam(nt_username);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ else if (smb_pass->acct_ctrl & ACB_PWNOTREQ)
+ status = 0;
+ else if (smb_pass->acct_ctrl & ACB_DISABLED)
+ status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
+ }
+
+ /* Validate password - if required. */
+
+ if ((status == 0) && !(smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
+ switch (q_l.sam_id.logon_level) {
+ case INTERACTIVE_LOGON_TYPE:
+ /* interactive login. */
+ status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, smb_pass, vuser);
+ break;
+ case NET_LOGON_TYPE:
+ /* network login. lm challenge and 24 byte responses */
+ status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass);
+ break;
+ }
+ }
+
+ /* lkclXXXX this is the point at which, if the login was
+ successful, that the SAM Local Security Authority should
+ record that the user is logged in to the domain.
+ */
- user_rid = sam_pass->user_rid;
- group_rid = sam_pass->group_rid;
+ /* return the profile plus other bits :-) */
- /* validate password - if required */
+ if (status == 0) {
+ DOM_GID *gids = NULL;
+ int num_gids = 0;
+ NTTIME dummy_time;
+ pstring logon_script;
+ pstring profile_path;
+ pstring home_dir;
+ pstring home_drive;
+ pstring my_name;
+ pstring my_workgroup;
+ pstring domain_groups;
+ uint32 r_uid;
+ uint32 r_gid;
- if (!(IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_PWNOTREQ)))
- {
- uint32 status = 0x0;
- switch (q_l->sam_id.logon_level)
- {
- case INTERACTIVE_LOGON_TYPE:
- {
- /* interactive login. */
- status = net_login_interactive(&q_l->sam_id.ctr->auth.id1, sam_pass, dc);
- break;
- }
- case NET_LOGON_TYPE:
- {
- /* network login. lm challenge and 24 byte responses */
- status = net_login_network(&q_l->sam_id.ctr->auth.id2, sam_pass, dc, sess_key);
- enc_user_sess_key = sess_key;
- break;
- }
- }
- if (status != 0x0)
- {
- return status;
- }
- }
+ /* set up pointer indicating user/password failed to be found */
+ usr_info.ptr_user_info = 0;
- /* lkclXXXX this is the point at which, if the login was
- successful, that the SAM Local Security Authority should
- record that the user is logged in to the domain.
- */
+ dummy_time.low = 0xffffffff;
+ dummy_time.high = 0x7fffffff;
- /* return the profile plus other bits :-) */
+ /* XXXX hack to get standard_sub_basic() to use sam logon username */
+ /* possibly a better way would be to do a become_user() call */
+ sam_logon_in_ssb = True;
+ pstrcpy(samlogon_user, nt_username);
- /* set up pointer indicating user/password failed to be found */
- usr_info->ptr_user_info = 0;
+ pstrcpy(logon_script, lp_logon_script());
+ pstrcpy(profile_path, lp_logon_path());
- if (!getusergroupsntnam(nt_username, &grp_mem, &num_gids))
- {
- return 0xC0000000 | NT_STATUS_INVALID_PRIMARY_GROUP;
- }
+ pstrcpy(my_workgroup, lp_workgroup());
- num_gids = make_dom_gids(grp_mem, num_gids, &gids);
-
- make_net_user_info3(usr_info,
- &logon_time,
- &logoff_time,
- &kickoff_time,
- &pass_last_set_time,
- &pass_can_change_time,
- &pass_must_change_time,
-
- nt_name , /* user_name */
- full_name , /* full_name */
- logon_script , /* logon_script */
- profile_path , /* profile_path */
- home_dir , /* home_dir */
- dir_drive , /* dir_drive */
-
- 0, /* logon_count */
- 0, /* bad_pw_count */
-
- user_rid , /* RID user_id */
- group_rid , /* RID group_id */
- num_gids, /* uint32 num_groups */
- gids , /* DOM_GID *gids */
- 0x20 , /* uint32 user_flgs (?) */
-
- enc_user_sess_key, /* char sess_key[16] */
-
- global_myname , /* char *logon_srv */
- global_sam_name, /* char *logon_dom */
- &global_sam_sid, /* DOM_SID *dom_sid */
- NULL); /* char *other_sids */
-
- /* Free any allocated groups array. */
- if (gids)
- {
- free((char *)gids);
- }
+ pstrcpy(home_drive, lp_logon_drive());
+ pstrcpy(home_dir, lp_logon_home());
- return 0x0;
-}
+ pstrcpy(my_name, global_myname);
+ strupper(my_name);
-/*************************************************************************
- api_net_sam_logon:
- *************************************************************************/
-static void api_net_sam_logon( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
-{
- NET_Q_SAM_LOGON q_l;
- NET_ID_INFO_CTR ctr;
- NET_USER_INFO_3 usr_info;
- uint32 status = 0x0;
- DOM_CRED srv_cred;
+ /*
+ * This is the point at which we get the group
+ * database - we should be getting the gid_t list
+ * from /etc/group and then turning the uids into
+ * rids and then into machine sids for this user.
+ * JRA.
+ */
- q_l.sam_id.ctr = &ctr;
- net_io_q_sam_logon("", &q_l, data, 0);
+ get_domain_user_groups(domain_groups, nt_username);
- status = reply_net_sam_logon(&q_l, &p->dc, &srv_cred, &usr_info);
- net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
+ /*
+ * make_dom_gids allocates the gids array. JRA.
+ */
+ gids = NULL;
+ num_gids = make_dom_gids(domain_groups, &gids);
+
+ sam_logon_in_ssb = False;
+
+ if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
+ init_net_user_info3(&usr_info,
+ &dummy_time, /* logon_time */
+ &dummy_time, /* logoff_time */
+ &dummy_time, /* kickoff_time */
+ &dummy_time, /* pass_last_set_time */
+ &dummy_time, /* pass_can_change_time */
+ &dummy_time, /* pass_must_change_time */
+
+ nt_username , /* user_name */
+ vuser->real_name, /* full_name */
+ logon_script , /* logon_script */
+ profile_path , /* profile_path */
+ home_dir , /* home_dir */
+ home_drive , /* dir_drive */
+
+ 0, /* logon_count */
+ 0, /* bad_pw_count */
+
+ r_uid , /* RID user_id */
+ r_gid , /* RID group_id */
+ num_gids, /* uint32 num_groups */
+ gids , /* DOM_GID *gids */
+ 0x20 , /* uint32 user_flgs (?) */
+
+ NULL, /* char sess_key[16] */
+
+ my_name , /* char *logon_srv */
+ my_workgroup, /* char *logon_dom */
+
+ &global_sam_sid, /* DOM_SID *dom_sid */
+ NULL); /* char *other_sids */
+ else
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+
+ /* Free any allocated groups array. */
+ if(gids)
+ free((char *)gids);
+ }
+
+ if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
+ return False;
+
+ return True;
}
/*************************************************************************
api_net_trust_dom_list:
*************************************************************************/
-static void api_net_trust_dom_list( rpcsrv_struct *p,
- prs_struct *data,
- prs_struct *rdata)
+
+static BOOL api_net_trust_dom_list( uint16 vuid,
+ prs_struct *data,
+ prs_struct *rdata)
{
NET_Q_TRUST_DOM_LIST q_t;
- char **doms = NULL;
- uint32 num_doms = 0;
- enumtrustdoms(&doms, &num_doms);
+ char *trusted_domain = "test_domain";
DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
/* grab the lsa trusted domain list query... */
- net_io_q_trust_dom("", &q_t, data, 0);
+ if(!net_io_q_trust_dom("", &q_t, data, 0)) {
+ DEBUG(0,("api_net_trust_dom_list: Failed to unmarshall NET_Q_TRUST_DOM_LIST.\n"));
+ return False;
+ }
/* construct reply. */
- net_reply_trust_dom_list(&q_t, rdata,
- num_doms, doms);
-
- free_char_array(num_doms, doms);
+ if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
+ return False;
DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
+
+ return True;
}
@@ -976,7 +876,8 @@ static void api_net_trust_dom_list( rpcsrv_struct *p,
/*************************************************************************
api_net_logon_ctrl2:
*************************************************************************/
-static void api_net_logon_ctrl2( rpcsrv_struct *p,
+
+static BOOL api_net_logon_ctrl2( uint16 vuid,
prs_struct *data,
prs_struct *rdata)
{
@@ -992,14 +893,20 @@ static void api_net_logon_ctrl2( rpcsrv_struct *p,
DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
/* grab the lsa netlogon ctrl2 query... */
- net_io_q_logon_ctrl2("", &q_l, data, 0);
+ if(!net_io_q_logon_ctrl2("", &q_l, data, 0)) {
+ DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n"));
+ return False;
+ }
/* construct reply. */
- net_reply_logon_ctrl2(&q_l, rdata,
+ if(!net_reply_logon_ctrl2(&q_l, rdata,
flags, pdc_connection_status, logon_attempts,
- tc_status, trusted_domain);
+ tc_status, trusted_domain))
+ return False;
DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+
+ return True;
}
/*******************************************************************
@@ -1008,21 +915,20 @@ static void api_net_logon_ctrl2( rpcsrv_struct *p,
static struct api_struct api_net_cmds [] =
{
{ "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
- { "NET_AUTH" , NET_AUTH , api_net_auth },
{ "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
{ "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
{ "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
{ "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
{ "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
{ "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
- { "NET_SAM_SYNC" , NET_SAM_SYNC , api_net_sam_sync },
- { NULL , 0 , NULL }
+ { NULL , 0 , NULL }
};
/*******************************************************************
receives a netlogon pipe and responds.
********************************************************************/
-BOOL api_netlog_rpc(rpcsrv_struct *p, prs_struct *data)
+
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);
}
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index d15cc1248c..236558ba70 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -1,4 +1,3 @@
-
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
@@ -6,6 +5,7 @@
* Copyright (C) Andrew Tridgell 1992-1998
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998.
+ * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -43,15 +43,14 @@
extern int DEBUGLEVEL;
-static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
+static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
unsigned char *hash = p->ntlmssp_hash;
unsigned char index_i = hash[256];
unsigned char index_j = hash[257];
int ind;
- for( ind = 0; ind < len; ind++)
- {
+ for( ind = 0; ind < len; ind++) {
unsigned char tc;
unsigned char t;
@@ -71,250 +70,332 @@ static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
}
/*******************************************************************
- frees all temporary data used in construction of pdu
+ Generate the next PDU to be returned from the data in p->rdata.
+ We cheat here as this function doesn't handle the special auth
+ footers of the authenticated bind response reply.
********************************************************************/
-void rpcsrv_free_temp(rpcsrv_struct *l)
+
+BOOL create_next_pdu(pipes_struct *p)
{
- mem_free_data(l->rhdr .data);
- mem_free_data(l->rfault .data);
- mem_free_data(l->rdata_i.data);
- mem_free_data(l->rauth .data);
- mem_free_data(l->rverf .data);
- mem_free_data(l->rntlm .data);
-}
+ RPC_HDR_RESP hdr_resp;
+ BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
+ uint32 data_len;
+ uint32 data_space_available;
+ uint32 data_len_left;
+ prs_struct outgoing_pdu;
+ char *data;
+ char *data_from;
+ uint32 data_pos;
-/*******************************************************************
- turns a DCE/RPC request into a DCE/RPC reply
+ memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
- this is where the data really should be split up into an array of
- headers and data sections.
+ /* Change the incoming request header to a response. */
+ p->hdr.pkt_type = RPC_RESPONSE;
- ********************************************************************/
-BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start)
-{
- char *data;
- BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
- uint32 data_len;
- uint32 auth_len;
- uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0);
+ /* Set up rpc header flags. */
+ if (p->data_sent_length == 0)
+ p->hdr.flags = RPC_FLG_FIRST;
+ else
+ p->hdr.flags = 0;
- DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
- data_start, data_end, l->hdr_ba.bba.max_tsize));
+ /*
+ * Work out how much we can fit in a sigle PDU.
+ */
- auth_len = l->hdr.auth_len;
+ data_space_available = sizeof(p->current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+ if(p->ntlmssp_auth_validated)
+ data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
- if (l->ntlmssp_auth)
- {
- DEBUG(10,("create_rpc_reply: auth\n"));
- if (auth_len != 16)
- {
- return False;
- }
- }
+ /*
+ * The amount we send is the minimum of the available
+ * space and the amount left to send.
+ */
- prs_init(&l->rhdr , 0x18, 4, 0, False);
- prs_init(&l->rauth, 1024, 4, 0, False);
- prs_init(&l->rverf, 0x10, 4, 0, False);
+ data_len_left = prs_offset(&p->rdata) - p->data_sent_length;
- l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+ /*
+ * Ensure there really is data left to send.
+ */
- /* set up rpc header (fragmentation issues) */
- if (data_start == 0)
- {
- l->hdr.flags = RPC_FLG_FIRST;
- }
- else
- {
- l->hdr.flags = 0;
+ if(!data_len_left) {
+ DEBUG(0,("create_next_pdu: no data left to send !\n"));
+ return False;
}
- l->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ data_len = MIN(data_len_left, data_space_available);
- if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
- {
- l->hdr.flags |= RPC_FLG_LAST;
- l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18;
- }
- else
- {
- l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
- }
+ /*
+ * Set up the alloc hint. This should be the data left to
+ * send.
+ */
- if (l->ntlmssp_auth)
- {
- l->hdr_resp.alloc_hint -= auth_len + 8;
+ hdr_resp.alloc_hint = data_len_left;
+
+ /*
+ * Set up the header lengths.
+ */
+
+ if (p->ntlmssp_auth_validated) {
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
+ RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
+ p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
+ } else {
+ p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
+ p->hdr.auth_len = 0;
}
- if (l->ntlmssp_auth)
- {
- data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+ /*
+ * Work out if this PDU will be the last.
+ */
+
+ if(p->data_sent_length + data_len >= prs_offset(&p->rdata))
+ p->hdr.flags |= RPC_FLG_LAST;
+
+ /*
+ * Init the parse struct to point at the outgoing
+ * data.
+ */
+
+ prs_init( &outgoing_pdu, 0, 4, MARSHALL);
+ prs_give_memory( &outgoing_pdu, (char *)p->current_pdu, sizeof(p->current_pdu), False);
+
+ /* Store the header in the data stream. */
+ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
+ return False;
}
- else
- {
- data_len = l->hdr.frag_len - 0x18;
+
+ if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
+ return False;
}
- l->rhdr.data->offset.start = 0;
- l->rhdr.data->offset.end = 0x18;
+ /* Store the current offset. */
+ data_pos = prs_offset(&outgoing_pdu);
- /* store the header in the data stream */
- smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0);
- smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0);
+ /* Copy the data into the PDU. */
+ data_from = prs_data_p(&p->rdata) + p->data_sent_length;
+
+ if(!prs_append_data(&outgoing_pdu, data_from, data_len)) {
+ DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
+ return False;
+ }
- /* don't use rdata: use rdata_i instead, which moves... */
- /* make a pointer to the rdata data, NOT A COPY */
+ /*
+ * Set data to point to where we copied the data into.
+ */
- l->rdata_i.data = NULL;
- prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io);
- data = mem_data(&(l->rdata.data), data_start);
- mem_create(l->rdata_i.data, data, 0, data_len, 0, False);
- l->rdata_i.offset = data_len;
+ data = prs_data_p(&outgoing_pdu) + data_pos;
- if (auth_len > 0)
- {
+ if (p->hdr.auth_len > 0) {
uint32 crc32 = 0;
- DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+ DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len));
- if (auth_seal)
- {
- crc32 = crc32_calc_buffer(data_len, data);
- NTLMSSPcalc_p(l, (uchar*)data, data_len);
+ if (auth_seal) {
+ crc32 = crc32_calc_buffer(data, data_len);
+ NTLMSSPcalc_p(p, (uchar*)data, data_len);
}
- if (auth_seal || auth_verify)
- {
- make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
- smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0);
+ if (auth_seal || auth_verify) {
+ RPC_HDR_AUTH auth_info;
+
+ init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL,
+ (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
+ return False;
+ }
}
- if (auth_verify)
- {
- char *auth_data;
- l->ntlmssp_seq_num++;
- make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++);
- smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0);
- auth_data = mem_data(&l->rverf.data, 4);
- NTLMSSPcalc_p(l, (uchar*)auth_data, 12);
+ if (auth_verify) {
+ RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+ char *auth_data = prs_data_p(&outgoing_pdu);
+
+ p->ntlmssp_seq_num++;
+ init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
+ crc32, p->ntlmssp_seq_num++);
+ auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
+ if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
+ DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
+ return False;
+ }
+ NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
}
}
- /* set up the data chain */
- if (l->ntlmssp_auth)
- {
- prs_link(NULL , &l->rhdr , &l->rdata_i);
- prs_link(&l->rhdr , &l->rdata_i, &l->rauth );
- prs_link(&l->rdata_i, &l->rauth , &l->rverf );
- prs_link(&l->rauth , &l->rverf , NULL );
- }
- else
- {
- prs_link(NULL , &l->rhdr , &l->rdata_i);
- prs_link(&l->rhdr, &l->rdata_i, NULL );
- }
+ /*
+ * Setup the counts for this PDU.
+ */
- return l->rhdr.data != NULL && l->rhdr.offset == 0x18;
+ p->data_sent_length += data_len;
+ p->current_pdu_len = p->hdr.frag_len;
+ p->current_pdu_sent = 0;
+
+ return True;
}
-static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
+/*******************************************************************
+ Process an NTLMSSP authentication response.
+ If this function succeeds, the user has been authenticated
+ and their domain, name and calling workstation stored in
+ the pipe struct.
+ The initial challenge is stored in p->challenge.
+ *******************************************************************/
+
+static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
{
- uchar *pwd = NULL;
- uchar null_pwd[16];
uchar lm_owf[24];
- uchar nt_owf[128];
- size_t lm_owf_len;
- size_t nt_owf_len;
- size_t usr_len;
- size_t dom_len;
- size_t wks_len;
- BOOL anonymous = False;
+ uchar nt_owf[24];
+ fstring user_name;
+ fstring unix_user_name;
+ fstring domain;
+ fstring wks;
+ BOOL guest_user = False;
+ struct smb_passwd *smb_pass = NULL;
+ struct passwd *pass = NULL;
+ uchar null_smb_passwd[16];
+ uchar *smb_passwd_ptr = NULL;
+
+ DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
- memset(null_pwd, 0, sizeof(null_pwd));
+ memset(p->user_name, '\0', sizeof(p->user_name));
+ memset(p->unix_user_name, '\0', sizeof(p->unix_user_name));
+ memset(p->domain, '\0', sizeof(p->domain));
+ memset(p->wks, '\0', sizeof(p->wks));
- DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
+ /*
+ * Setup an empty password for a guest user.
+ */
- lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
- nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
- usr_len = l->ntlmssp_resp.hdr_usr .str_str_len;
- dom_len = l->ntlmssp_resp.hdr_domain .str_str_len;
- wks_len = l->ntlmssp_resp.hdr_wks .str_str_len;
+ memset(null_smb_passwd,0,16);
- if (lm_owf_len == 0 && nt_owf_len == 0 &&
- usr_len == 0 && dom_len == 0 && wks_len == 0)
- {
- anonymous = True;
- }
- else
- {
- if (lm_owf_len == 0) return False;
- if (nt_owf_len == 0) return False;
- if (l->ntlmssp_resp.hdr_usr .str_str_len == 0) return False;
- if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
- if (l->ntlmssp_resp.hdr_wks .str_str_len == 0) return False;
+ /*
+ * We always negotiate UNICODE.
+ */
+
+ if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
+ fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2));
+ fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2));
+ fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2));
+ } else {
+ fstrcpy(user_name, ntlmssp_resp->user);
+ fstrcpy(domain, ntlmssp_resp->domain);
+ fstrcpy(wks, ntlmssp_resp->wks);
}
- if (lm_owf_len > sizeof(lm_owf)) return False;
- if (nt_owf_len > sizeof(nt_owf)) return False;
+ DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
- memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
- memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
+ memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
+ memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
#ifdef DEBUG_PASSWORD
DEBUG(100,("lm, nt owfs, chal\n"));
- dump_data(100, lm_owf, sizeof(lm_owf));
- dump_data(100, nt_owf, sizeof(nt_owf));
- dump_data(100, l->ntlmssp_chal.challenge, 8);
+ dump_data(100, (char *)lm_owf, sizeof(lm_owf));
+ dump_data(100, (char *)nt_owf, sizeof(nt_owf));
+ dump_data(100, (char *)p->challenge, 8);
#endif
- memset(l->user_name, 0, sizeof(l->user_name));
- memset(l->domain , 0, sizeof(l->domain ));
- memset(l->wks , 0, sizeof(l->wks ));
+ /*
+ * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
+ */
+
+ if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) &&
+ (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) {
+
+ guest_user = True;
+
+ fstrcpy(unix_user_name, lp_guestaccount(-1));
+ DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name));
+
+ smb_passwd_ptr = null_smb_passwd;
+
+ } else {
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ fstrcpy(unix_user_name, user_name);
+ (void)map_username(unix_user_name);
+
+ /*
+ * Do the length checking only if user is not NULL.
+ */
+
+ if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_usr.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_domain.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_wks.str_str_len == 0)
+ return False;
- if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
- {
- unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
- MIN(l->ntlmssp_resp.hdr_usr .str_str_len/2,
- sizeof(l->user_name)-1));
- unibuf_to_ascii(l->domain , l->ntlmssp_resp.domain,
- MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
- sizeof(l->domain )-1));
- unibuf_to_ascii(l->wks , l->ntlmssp_resp.wks,
- MIN(l->ntlmssp_resp.hdr_wks .str_str_len/2,
- sizeof(l->wks )-1));
- }
- else
- {
- fstrcpy(l->user_name, l->ntlmssp_resp.user );
- fstrcpy(l->domain , l->ntlmssp_resp.domain);
- fstrcpy(l->wks , l->ntlmssp_resp.wks );
}
+ /*
+ * Find the user in the unix password db.
+ */
- if (anonymous)
- {
- DEBUG(5,("anonymous user session\n"));
- mdfour(l->user_sess_key, null_pwd, 16);
- pwd = null_pwd;
- l->ntlmssp_validated = True;
+ if(!(pass = Get_Pwnam(unix_user_name,True))) {
+ DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name));
+ return(False);
}
- else
- {
- DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
- become_root(False);
- l->ntlmssp_validated = check_domain_security(l->user_name, l->domain,
- (uchar*)l->ntlmssp_chal.challenge,
- lm_owf, lm_owf_len,
- nt_owf, nt_owf_len,
- l->user_sess_key);
- unbecome_root(False);
+
+ if(!guest_user) {
+
+ become_root(True);
+
+ if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain,
+ (uchar*)p->challenge, lm_owf, nt_owf, NULL))) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
+failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name ));
+ unbecome_root(True);
+ return False;
+ }
+
+ if(!(smb_pass = getsmbpwnam(unix_user_name))) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
+ unix_user_name));
+ unbecome_root(True);
+ return False;
+ }
+
+ unbecome_root(True);
+
+ if (smb_pass == NULL) {
+ DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n",
+ unix_user_name));
+ return(False);
+ }
+
+ /* Quit if the account was disabled. */
+ if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) {
+ DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name));
+ return(False);
+ }
+
+ if(!smb_pass->smb_nt_passwd) {
+ DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name));
+ return(False);
+ }
+
+ smb_passwd_ptr = smb_pass->smb_passwd;
}
- if (l->ntlmssp_validated && pwd != NULL)
+ /*
+ * Set up the sign/seal data.
+ */
+
{
uchar p24[24];
- NTLMSSPOWFencrypt(pwd, lm_owf, p24);
+ NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
{
unsigned char j = 0;
int ind;
@@ -327,761 +408,670 @@ static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
k2[7] = 0xb0;
for (ind = 0; ind < 256; ind++)
- {
- l->ntlmssp_hash[ind] = (unsigned char)ind;
- }
+ p->ntlmssp_hash[ind] = (unsigned char)ind;
- for( ind = 0; ind < 256; ind++)
- {
+ for( ind = 0; ind < 256; ind++) {
unsigned char tc;
- j += (l->ntlmssp_hash[ind] + k2[ind%8]);
+ j += (p->ntlmssp_hash[ind] + k2[ind%8]);
- tc = l->ntlmssp_hash[ind];
- l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
- l->ntlmssp_hash[j] = tc;
+ tc = p->ntlmssp_hash[ind];
+ p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
+ p->ntlmssp_hash[j] = tc;
}
- l->ntlmssp_hash[256] = 0;
- l->ntlmssp_hash[257] = 0;
+ p->ntlmssp_hash[256] = 0;
+ p->ntlmssp_hash[257] = 0;
}
- l->ntlmssp_seq_num = 0;
- }
- else
- {
- l->ntlmssp_validated = False;
+/* NTLMSSPhash(p->ntlmssp_hash, p24); */
+ p->ntlmssp_seq_num = 0;
+
}
- return l->ntlmssp_validated;
-}
+ fstrcpy(p->user_name, user_name);
+ fstrcpy(p->unix_user_name, unix_user_name);
+ fstrcpy(p->domain, domain);
+ fstrcpy(p->wks, wks);
-static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
-{
- /* receive a negotiate; send a challenge; receive a response */
- switch (l->auth_verifier.msg_type)
- {
- case NTLMSSP_NEGOTIATE:
- {
- smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
- break;
- }
- case NTLMSSP_AUTH:
- {
- smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
- if (!api_pipe_ntlmssp_verify(l))
- {
- pd->offset = 0;
- }
- break;
- }
- default:
- {
- /* NTLMSSP expected: unexpected message type */
- DEBUG(3,("unexpected message type in NTLMSSP %d\n",
- l->auth_verifier.msg_type));
- return False;
- }
- }
+ /*
+ * Store the UNIX credential data (uid/gid pair) in the pipe structure.
+ */
+
+ p->uid = pass->pw_uid;
+ p->gid = pass->pw_gid;
- return (pd->offset != 0);
+ p->ntlmssp_auth_validated = True;
+ return True;
}
+/*******************************************************************
+ The switch table for the pipe names and the functions to handle them.
+ *******************************************************************/
+
struct api_cmd
{
char * pipe_clnt_name;
char * pipe_srv_name;
- BOOL (*fn) (rpcsrv_struct *, prs_struct *);
+ BOOL (*fn) (pipes_struct *, prs_struct *);
};
-static struct api_cmd **api_fd_commands = NULL;
-uint32 num_cmds = 0;
-
-static void api_cmd_free(struct api_cmd *item)
-{
- if (item != NULL)
- {
- if (item->pipe_clnt_name != NULL)
- {
- free(item->pipe_clnt_name);
- }
- if (item->pipe_srv_name != NULL)
- {
- free(item->pipe_srv_name);
- }
- free(item);
- }
-}
-
-static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
+static struct api_cmd api_fd_commands[] =
{
- struct api_cmd *copy = NULL;
- if (from == NULL)
- {
- return NULL;
- }
- copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
- if (copy != NULL)
- {
- ZERO_STRUCTP(copy);
- if (from->pipe_clnt_name != NULL)
- {
- copy->pipe_clnt_name = strdup(from->pipe_clnt_name );
- }
- if (from->pipe_srv_name != NULL)
- {
- copy->pipe_srv_name = strdup(from->pipe_srv_name);
- }
- if (from->fn != NULL)
- {
- copy->fn = from->fn;
- }
- }
- return copy;
-}
+ { "lsarpc", "lsass", api_ntlsa_rpc },
+ { "samr", "lsass", api_samr_rpc },
+ { "srvsvc", "ntsvcs", api_srvsvc_rpc },
+ { "wkssvc", "ntsvcs", api_wkssvc_rpc },
+ { "NETLOGON", "lsass", api_netlog_rpc },
+#if DISABLED_IN_2_0
+ { "winreg", "winreg", api_reg_rpc },
+#endif
+ { NULL, NULL, NULL }
+};
-static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
-{
- void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
- free_void_array(num_entries, (void**)entries, *fn);
-}
+/*******************************************************************
+ This is the client reply to our challenge for an authenticated
+ bind request. The challenge we sent is in p->challenge.
+*******************************************************************/
-static struct api_cmd* add_api_cmd_to_array(uint32 *len,
- struct api_cmd ***array,
- const struct api_cmd *name)
+static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
{
- void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
- return (struct api_cmd*)add_copy_to_array(len,
- (void***)array, (const void*)name, *fn, False);
-
-}
+ RPC_HDR_AUTHA autha_info;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
-void close_msrpc_command_processor(void)
-{
- free_api_cmd_array(num_cmds, api_fd_commands);
-}
+ if (p->hdr.auth_len == 0) {
+ DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
+ return False;
+ }
-void add_msrpc_command_processor(char* pipe_name,
- char* process_name,
- BOOL (*fn) (rpcsrv_struct *, prs_struct *))
-{
- struct api_cmd cmd;
- cmd.pipe_clnt_name = pipe_name;
- cmd.pipe_srv_name = process_name;
- cmd.fn = fn;
+ /*
+ * Decode the authentication verifier response.
+ */
- add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
-}
+ if(!smb_io_rpc_hdr_autha("", &autha_info, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n"));
+ return False;
+ }
-static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
-{
- DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+ if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) {
+ DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
+ (int)autha_info.auth_type, (int)autha_info.auth_level ));
+ return False;
+ }
- if (l->hdr.auth_len == 0) return False;
+ if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n"));
+ return False;
+ }
- /* decode the authentication verifier response */
- smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
- if (pd->offset == 0) return False;
+ /*
+ * Ensure this is a NTLMSSP_AUTH packet type.
+ */
- if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
+ if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
+ DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
+ return False;
+ }
- smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
- if (pd->offset == 0) return False;
+ if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n"));
+ return False;
+ }
- if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
+ /*
+ * The following call actually checks the challenge/response data.
+ * for correctness against the given DOMAIN\user name.
+ */
- return api_pipe_ntlmssp(l, pd);
+ if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp))
+ return False;
+
+ return True;
}
-static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
+/*******************************************************************
+ Marshall a bind_nak pdu.
+*******************************************************************/
+
+static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd)
{
- DEBUG(5,("api_pipe_fault_resp: make response\n"));
+ prs_struct outgoing_rpc;
+ RPC_HDR nak_hdr;
+ uint16 zero = 0;
+
+ /*
+ * Marshall directly into the outgoing PDU space. We
+ * must do this as we need to set to the bind response
+ * header and are never sending more than one PDU here.
+ */
- prs_init(&(l->rhdr ), 0x18, 4, 0, False);
- prs_init(&(l->rfault ), 0x8 , 4, 0, False);
+ prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+ prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False);
- /***/
- /*** set up the header, response header and fault status ***/
- /***/
- l->hdr_fault.status = status;
- l->hdr_fault.reserved = 0x0;
+ /*
+ * Initialize a bind_nak header.
+ */
- l->hdr_resp.alloc_hint = 0x0;
- l->hdr_resp.cancel_count = 0x0;
- l->hdr_resp.reserved = 0x0;
+ init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
- make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
- l->hdr.call_id,
- 0x20,
- 0);
+ /*
+ * Marshall the header into the outgoing PDU.
+ */
- smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0);
- smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
- smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
- mem_realloc_data(l->rhdr.data, l->rhdr.offset);
- mem_realloc_data(l->rfault.data, l->rfault.offset);
+ if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
+ DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
+ return False;
+ }
- /***/
- /*** link rpc header and fault together ***/
- /***/
+ /*
+ * Now add the reject reason.
+ */
- prs_link(NULL , &l->rhdr , &l->rfault);
- prs_link(&l->rhdr, &l->rfault, NULL );
+ if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero))
+ return False;
+
+ p->data_sent_length = 0;
+ p->current_pdu_len = prs_offset(&outgoing_rpc);
+ p->current_pdu_sent = 0;
return True;
}
-static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
- const char* ack_pipe_name,
- enum RPC_PKT_TYPE pkt_type)
+/*******************************************************************
+ Respond to a pipe bind request.
+*******************************************************************/
+
+static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
{
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_AUTH auth_info;
uint16 assoc_gid;
+ fstring ack_pipe_name;
+ prs_struct out_hdr_ba;
+ prs_struct out_auth;
+ prs_struct outgoing_rpc;
+ int i = 0;
+ int auth_len = 0;
+
+ p->ntlmssp_auth_requested = False;
+
+ DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+
+ /*
+ * Try and find the correct pipe name to ensure
+ * that this is a pipe name we support.
+ */
- l->ntlmssp_auth = False;
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL) {
+ DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ api_fd_commands[i].pipe_clnt_name,
+ api_fd_commands[i].pipe_srv_name));
+ fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
+ break;
+ }
+ }
+
+ if (api_fd_commands[i].fn == NULL) {
+ DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
+ p->name ));
+ if(!setup_bind_nak(p, pd))
+ return False;
+ return True;
+ }
/* decode the bind request */
- smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
+ if(!smb_io_rpc_hdr_rb("", &hdr_rb, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
+ return False;
+ }
- if (pd->offset == 0) return False;
+ /*
+ * Check if this is an authenticated request.
+ */
- if (l->hdr.auth_len != 0)
- {
- /* decode the authentication verifier */
- smb_io_rpc_hdr_auth ("", &l->auth_info , pd, 0);
- if (pd->offset == 0) return False;
+ if (p->hdr.auth_len != 0) {
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
- l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
+ /*
+ * Decode the authentication verifier.
+ */
- if (l->ntlmssp_auth)
- {
- smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
- if (pd->offset == 0) return False;
+ if(!smb_io_rpc_hdr_auth("", &auth_info, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+ return False;
+ }
- l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
+ /*
+ * We only support NTLMSSP_AUTH_TYPE requests.
+ */
+
+ if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) {
+ DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
+ auth_info.auth_type ));
+ return False;
}
- if (l->ntlmssp_auth)
- {
- if (!api_pipe_ntlmssp(l, pd)) return False;
+ if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
+ return False;
+ }
+
+ if(!strequal(auth_verifier.signature, "NTLMSSP")) {
+ DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n"));
+ return False;
+ }
+
+ if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
+ DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
+ auth_verifier.msg_type));
+ return False;
}
+
+ if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, pd, 0)) {
+ DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
+ return False;
+ }
+
+ p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
+ p->ntlmssp_auth_requested = True;
}
+ /* name has to be \PIPE\xxxxx */
+ fstrcpy(ack_pipe_name, "\\PIPE\\");
+ fstrcat(ack_pipe_name, p->pipe_srv_name);
+
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
- prs_init(&(l->rdata), 1024, 4, 0, False);
- prs_init(&(l->rhdr ), 0x18, 4, 0, False);
- prs_init(&(l->rauth), 1024, 4, 0, False);
- prs_init(&(l->rverf), 0x08, 4, 0, False);
- prs_init(&(l->rntlm), 1024, 4, 0, False);
+ /*
+ * Marshall directly into the outgoing PDU space. We
+ * must do this as we need to set to the bind response
+ * header and are never sending more than one PDU here.
+ */
- /***/
- /*** do the bind ack first ***/
- /***/
+ prs_init( &outgoing_rpc, 0, 4, MARSHALL);
+ prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False);
- if (l->ntlmssp_auth)
- {
- assoc_gid = 0x7a77;
+ /*
+ * Setup the memory to marshall the ba header, and the
+ * auth footers.
+ */
+
+ if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) {
+ DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
+ return False;
}
- else
- {
- assoc_gid = l->hdr_rb.bba.assoc_gid;
+
+ if(!prs_init(&out_auth, 1024, 4, MARSHALL)) {
+ DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
+ prs_mem_free(&out_hdr_ba);
+ return False;
}
- make_rpc_hdr_ba(&l->hdr_ba,
- l->hdr_rb.bba.max_tsize,
- l->hdr_rb.bba.max_rsize,
+ if (p->ntlmssp_auth_requested)
+ assoc_gid = 0x7a77;
+ else
+ assoc_gid = hdr_rb.bba.assoc_gid;
+
+ /*
+ * Create the bind response struct.
+ */
+
+ init_rpc_hdr_ba(&hdr_ba,
+ hdr_rb.bba.max_tsize,
+ hdr_rb.bba.max_rsize,
assoc_gid,
ack_pipe_name,
0x1, 0x0, 0x0,
- &(l->hdr_rb.transfer));
+ &hdr_rb.transfer);
+
+ /*
+ * and marshall it.
+ */
- smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
- mem_realloc_data(l->rdata.data, l->rdata.offset);
+ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
+ goto err_exit;
+ }
- /***/
- /*** now the authentication ***/
- /***/
+ /*
+ * Now the authentication.
+ */
- if (l->ntlmssp_auth)
- {
- uint8 challenge[8];
- generate_random_buffer(challenge, 8, False);
+ if (p->ntlmssp_auth_requested) {
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
- /*** authentication info ***/
+ generate_random_buffer(p->challenge, 8, False);
- make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
- smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
- mem_realloc_data(l->rverf.data, l->rverf.offset);
+ /*** Authentication info ***/
+
+ init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1);
+ if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
+ goto err_exit;
+ }
/*** NTLMSSP verifier ***/
- make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
- "NTLMSSP", NTLMSSP_CHALLENGE);
- smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
- mem_realloc_data(l->rauth.data, l->rauth.offset);
+ init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
+ if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
+ goto err_exit;
+ }
/* NTLMSSP challenge ***/
- make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
- 0x000082b1, challenge);
- smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
- mem_realloc_data(l->rntlm.data, l->rntlm.offset);
- }
+ init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge);
+ if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) {
+ DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n"));
+ goto err_exit;
+ }
- /***/
- /*** then do the header, now we know the length ***/
- /***/
+ /* Auth len in the rpc header doesn't include auth_header. */
+ auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
+ }
- make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
- l->hdr.call_id,
- l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
- l->rauth.offset + l->rntlm.offset);
+ /*
+ * Create the header, now we know the length.
+ */
- smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
- mem_realloc_data(l->rhdr.data, l->rdata.offset);
+ init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id,
+ RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
+ auth_len);
- /***/
- /*** link rpc header, bind acknowledgment and authentication responses ***/
- /***/
+ /*
+ * Marshall the header into the outgoing PDU.
+ */
- if (l->ntlmssp_auth)
- {
- prs_link(NULL , &l->rhdr , &l->rdata);
- prs_link(&l->rhdr , &l->rdata, &l->rverf);
- prs_link(&l->rdata, &l->rverf, &l->rauth);
- prs_link(&l->rverf, &l->rauth, &l->rntlm);
- prs_link(&l->rauth, &l->rntlm, NULL );
+ if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
+ DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
+ goto err_exit;
}
- else
- {
- prs_link(NULL , &l->rhdr , &l->rdata);
- prs_link(&l->rhdr, &l->rdata, NULL );
+
+ /*
+ * Now add the RPC_HDR_BA and any auth needed.
+ */
+
+ if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
+ DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
+ goto err_exit;
}
- return True;
-}
+ if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
+ DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
+ goto err_exit;
+ }
-static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
- const char* name,
- enum RPC_PKT_TYPE pkt_type)
-{
- fstring ack_pipe_name;
- fstring pipe_srv_name;
- int i = 0;
+ /*
+ * Setup the lengths for the initial reply.
+ */
- DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+ p->data_sent_length = 0;
+ p->current_pdu_len = prs_offset(&outgoing_rpc);
+ p->current_pdu_sent = 0;
- for (i = 0; i < num_cmds; i++)
- {
- if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
- api_fd_commands[i]->fn != NULL)
- {
- DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- api_fd_commands[i]->pipe_clnt_name,
- api_fd_commands[i]->pipe_srv_name));
- fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
- break;
- }
- }
+ prs_mem_free(&out_hdr_ba);
+ prs_mem_free(&out_auth);
- if (api_fd_commands[i]->fn == NULL) return False;
+ return True;
- switch (pkt_type)
- {
- case RPC_BINDACK:
- {
- /* name has to be \PIPE\xxxxx */
- fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, pipe_srv_name);
- break;
- }
- case RPC_ALTCONTRESP:
- {
- /* secondary address CAN be NULL
- * as the specs says it's ignored.
- * It MUST NULL to have the spoolss working.
- */
- fstrcpy(ack_pipe_name, "");
- break;
- }
- default:
- {
- return False;
- }
- }
- return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
-}
+ err_exit:
-/*
- * The RPC Alter-Context call is used only by the spoolss pipe
- * simply because there is a bug (?) in the MS unmarshalling code
- * or in the marshalling code. If it's in the later, then Samba
- * have the same bug.
- */
-static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
- const char* name)
-{
- return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
+ prs_mem_free(&out_hdr_ba);
+ prs_mem_free(&out_auth);
+ return False;
}
-static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
- const char* name)
-{
- return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
-}
+/****************************************************************************
+ Deal with sign & seal processing on an RPC request.
+****************************************************************************/
-static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
+static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
{
- BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
+ /*
+ * We always negotiate the following two bits....
+ */
+ BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
int data_len;
int auth_len;
uint32 old_offset;
uint32 crc32 = 0;
- auth_len = l->hdr.auth_len;
+ auth_len = p->hdr.auth_len;
- if (auth_len != 16 && auth_verify)
- {
+ if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) {
+ DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len ));
return False;
}
- data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+ /*
+ * The following is that length of the data we must verify or unseal.
+ * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
+ * preceeding the auth_data.
+ */
+
+ data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
+ (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
- if (auth_seal)
- {
- char *data = mem_data(&pd->data, pd->offset);
- DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
- NTLMSSPcalc_p(l, (uchar*)data, data_len);
- crc32 = crc32_calc_buffer(data_len, data);
+ if (auth_seal) {
+ char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
+ NTLMSSPcalc_p(p, (uchar*)data, data_len);
+ crc32 = crc32_calc_buffer(data, data_len);
}
- /*** skip the data, record the offset so we can restore it again */
- old_offset = pd->offset;
+ old_offset = prs_offset(rpc_in);
- if (auth_seal || auth_verify)
- {
- pd->offset += data_len;
- smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
- }
+ if (auth_seal || auth_verify) {
+ RPC_HDR_AUTH auth_info;
- if (auth_verify)
- {
- char *req_data = mem_data(&pd->data, pd->offset + 4);
- DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
- NTLMSSPcalc_p(l, (uchar*)req_data, 12);
- smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
+ if(!prs_set_offset(rpc_in, old_offset + data_len)) {
+ DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n",
+ (unsigned int)old_offset + data_len ));
+ return False;
+ }
- if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
- l->ntlmssp_seq_num))
- {
+ if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
+ DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
return False;
}
}
- pd->offset = old_offset;
-
- return True;
-}
-
-static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
-{
- int i = 0;
-
- if (l->ntlmssp_auth && l->ntlmssp_validated)
- {
- if (!api_pipe_auth_process(l, pd)) return False;
+ if (auth_verify) {
+ RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+ char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4;
- DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
-#if 0
- become_user();
-#endif
- }
+ DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4));
- for (i = 0; i < num_cmds; i++)
- {
- if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
- api_fd_commands[i]->fn != NULL)
- {
- DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
- return api_fd_commands[i]->fn(l, pd);
+ /*
+ * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the
+ * incoming buffer.
+ */
+ if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) {
+ DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n",
+ RPC_AUTH_NTLMSSP_CHK_LEN - 4 ));
+ return False;
}
- }
- return False;
-}
-
-BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
-{
- int prev_size;
- int new_size;
- char *to = NULL;
-
- ps->offset = 0;
- if (ps->data == NULL)
- {
- DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
- prs_init(ps, len, 4, 0, True);
- prev_size = 0;
- new_size = len;
- if (ps->data == NULL)
- {
+ NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+ if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) {
+ DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n"));
return False;
}
- }
- else
- {
- prev_size = ps->data->data_used;
- new_size = prev_size + len;
- DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
- prev_size, new_size));
- if (!mem_realloc_data(ps->data, new_size))
- {
+
+ if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) {
+ DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n"));
return False;
}
}
- DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
- ps->data->offset.start = 0x0;
+ /*
+ * Return the current pointer to the data offset.
+ */
- to = mem_data(&ps->data, prev_size);
- if (to == NULL)
- {
- DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
- return False;
- }
- if (ps->data->data_used != new_size)
- {
- DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
- ps->data->data_used, new_size));
+ if(!prs_set_offset(rpc_in, old_offset)) {
+ DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
+ (unsigned int)old_offset ));
return False;
}
- memcpy(to, data, len);
+
return True;
}
-static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
+/****************************************************************************
+ Find the correct RPC function to call for this request.
+ If the pipe is authenticated then become the correct UNIX user
+ before doing the call.
+****************************************************************************/
+
+static BOOL api_pipe_request(pipes_struct *p, prs_struct *rpc_in)
{
- DEBUG(10,("rpc_redirect\n"));
+ int i = 0;
+ BOOL ret = False;
+ BOOL changed_user_id = False;
- if (!msrpc_send_prs(p->m, req))
- {
- DEBUG(2,("msrpc redirect send failed\n"));
- return False;
+ if (p->ntlmssp_auth_validated) {
+ if (!api_pipe_auth_process(p, rpc_in))
+ return False;
+
+ if(!become_authenticated_pipe_user(p))
+ return False;
+
+ changed_user_id = True;
}
- if (!msrpc_receive_prs(p->m, resp))
- {
- DEBUG(2,("msrpc redirect receive failed\n"));
- return False;
+
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL) {
+ DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+ ret = api_fd_commands[i].fn(p, rpc_in);
+ }
}
- prs_link(NULL, resp, NULL);
- prs_debug_out(resp, "redirect", 100);
- return True;
+
+ if(changed_user_id)
+ unbecome_authenticated_pipe_user(p);
+
+ return ret;
}
-static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
- const char* name)
+/****************************************************************************
+ This function is the entry point to processing a DCE/RPC request.
+ All the data for the request (including RPC headers and authentication
+ verifiers) must be linearized in the input_data buffer, with a length
+ of data_len.
+
+ The output is placed into the pipes_struct, and handed back to the
+ client on demand.
+****************************************************************************/
+
+BOOL rpc_command(pipes_struct *p, char *input_data, int data_len)
{
+ prs_struct rpc_in;
BOOL reply = False;
- if (req->data == NULL) return False;
+ if (input_data == NULL)
+ return False;
+
+ prs_init(&rpc_in, 0, 4, UNMARSHALL);
- /* lkclXXXX still assume that the first complete PDU is always
- in a single request!!!
+ /*
+ * Hand the data to the prs_struct, but don't let
+ * it own it.
*/
- /* process the rpc header */
- req->offset = 0x0;
- smb_io_rpc_hdr("", &l->hdr, req, 0);
+ prs_give_memory( &rpc_in, input_data, (uint32)data_len, False);
- if (req->offset == 0) return False;
+ /* Unmarshall the rpc header */
+ if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
+ DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+ return False;
+ }
- switch (l->hdr.pkt_type)
- {
- case RPC_BIND :
- {
- reply = api_pipe_bind_req(l, req, name);
- break;
- }
- case RPC_ALTCONT:
- {
- reply = api_pipe_alt_req(l, req, name);
- break;
- }
- case RPC_REQUEST:
- {
- if (l->ntlmssp_auth && !l->ntlmssp_validated)
- {
- /* authentication _was_ requested
- and it failed. sorry, no deal!
- */
- reply = False;
- }
- else
- {
- /* read the rpc header */
- smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
- reply = api_pipe_request(l, req, name);
+ /*
+ * Create the response data buffer.
+ */
+
+ if(!pipe_init_outgoing_data(p)) {
+ DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+ return False;
+ }
+
+ switch (p->hdr.pkt_type) {
+ case RPC_BIND:
+ reply = api_pipe_bind_req(p, &rpc_in);
+ break;
+ case RPC_REQUEST:
+ if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
+ /* authentication _was_ requested
+ and it failed. sorry, no deal!
+ */
+ DEBUG(0,("rpc_command: RPC request received on pipe %s where \
+authentication failed. Denying the request.\n", p->name));
+ reply = False;
+ } else {
+ /* read the RPC request header */
+ if(!smb_io_rpc_hdr_req("req", &p->hdr_req, &rpc_in, 0)) {
+ DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR_REQ.\n"));
+ return False;
}
- break;
- }
- case RPC_BINDRESP: /* not the real name! */
- {
- reply = api_pipe_bind_auth_resp(l, req);
- l->ntlmssp_auth = reply;
- break;
+ reply = api_pipe_request(p, &rpc_in);
}
+ break;
+ case RPC_BINDRESP: /* not the real name! */
+ reply = api_pipe_bind_auth_resp(p, &rpc_in);
+ break;
}
if (!reply)
- {
- reply = api_pipe_fault_resp(l, req, 0x1c010002);
- }
-
- if (reply)
- {
- /* flatten the data into a single pdu */
- reply = prs_copy(resp, &l->rhdr);
- }
-
- /* delete intermediate data used to set up the pdu. leave
- rdata alone because that's got the rest of the data in it */
- rpcsrv_free_temp(l);
+ DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
return reply;
}
-BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
-{
- DEBUG(10,("rpc_send_and_rcv_pdu\n"));
-
- if (p->m != NULL)
- {
- return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
- }
- else if (p->l != NULL)
- {
- return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
- p->name);
- }
- return False;
-}
/*******************************************************************
- entry point from msrpc to smb. adds data received to pdu; checks
- pdu; hands pdu off to msrpc, which gets a pdu back (except in the
- case of the RPC_BINDCONT pdu).
+ Calls the underlying RPC function for a named pipe.
********************************************************************/
-BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
-{
- BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
- if (reply && is_complete_pdu(&p->smb_pdu))
- {
- p->smb_pdu.offset = p->smb_pdu.data->data_size;
- prs_link(NULL, &p->smb_pdu, NULL);
- reply = rpc_send_and_rcv_pdu(p);
- mem_free_data(p->smb_pdu.data);
- prs_init(&p->smb_pdu, 0, 4, 0, True);
-
- }
- return reply;
-}
-
-/*******************************************************************
- receives a netlogon pipe and responds.
- ********************************************************************/
-static BOOL api_rpc_command(rpcsrv_struct *l,
- char *rpc_name, struct api_struct *api_rpc_cmds,
- prs_struct *data)
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+ prs_struct *rpc_in)
{
int fn_num;
- DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
- for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
- {
- if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
- {
+ /* interpret the command */
+ DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
+
+ for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
+ if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
break;
}
}
- if (api_rpc_cmds[fn_num].name == NULL)
- {
+ if (api_rpc_cmds[fn_num].name == NULL) {
DEBUG(4, ("unknown\n"));
return False;
}
- /* start off with 1024 bytes, and a large safety margin too */
- prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
-
/* do the actual command */
- api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
-
- if (l->rdata.data == NULL || l->rdata.offset == 0)
- {
- mem_free_data(l->rdata.data);
+ if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->rdata)) {
+ DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
+ prs_mem_free(&p->rdata);
return False;
}
- mem_realloc_data(l->rdata.data, l->rdata.offset);
-
- DEBUG(10,("called %s\n", rpc_name));
+ DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
return True;
}
-
-
-/*******************************************************************
- receives a netlogon pipe and responds.
- ********************************************************************/
-BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
- prs_struct *data)
-{
- if (data == NULL || data->data == NULL)
- {
- DEBUG(2,("%s: NULL data received\n", rpc_name));
- return False;
- }
-
- /* interpret the command */
- if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
- {
- return False;
- }
-
- /* create the rpc header */
- if (!create_rpc_reply(l, 0))
- {
- return False;
- }
-
- return True;
-}
-
-BOOL is_complete_pdu(prs_struct *ps)
-{
- RPC_HDR hdr;
- int len = ps->data->data_size;
-
- DEBUG(10,("is_complete_pdu - len %d\n", len));
- ps->offset = 0x0;
-
- if (!ps->io)
- {
- /* writing. oops!! */
- DEBUG(4,("is_complete_pdu: write set, not read!\n"));
- return False;
- }
-
- if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
- {
- return False;
- }
- /* check that the fragment length is equal to the data length so far */
- return hdr.frag_len == len;
-}
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index f8bde1bf9b..b21b768a6e 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -5,6 +5,7 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -55,7 +56,7 @@ void set_pipe_handle_offset(int max_open_files)
}
/****************************************************************************
- reset pipe chain handle number
+ Reset pipe chain handle number.
****************************************************************************/
void reset_chain_p(void)
{
@@ -63,63 +64,64 @@ void reset_chain_p(void)
}
/****************************************************************************
- initialise pipe handle states...
+ Initialise pipe handle states.
****************************************************************************/
+
void init_rpc_pipe_hnd(void)
{
bmap = bitmap_allocate(MAX_OPEN_PIPES);
- if (!bmap) {
+ if (!bmap)
exit_server("out of memory in init_rpc_pipe_hnd\n");
- }
}
+/****************************************************************************
+ Initialise an outgoing packet.
+****************************************************************************/
+
+BOOL pipe_init_outgoing_data( pipes_struct *p)
+{
+
+ memset(p->current_pdu, '\0', sizeof(p->current_pdu));
+
+ /* Free any memory in the current return data buffer. */
+ prs_mem_free(&p->rdata);
+
+ /*
+ * Initialize the outgoing RPC data buffer.
+ * we will use this as the raw data area for replying to rpc requests.
+ */
+ if(!prs_init(&p->rdata, 1024, 4, MARSHALL)) {
+ DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
+ return False;
+ }
+
+ /* Reset the offset counters. */
+ p->data_sent_length = 0;
+ p->current_pdu_len = 0;
+ p->current_pdu_sent = 0;
+
+ return True;
+}
/****************************************************************************
- find first available file slot
+ Find first available pipe slot.
****************************************************************************/
+
pipes_struct *open_rpc_pipe_p(char *pipe_name,
connection_struct *conn, uint16 vuid)
{
int i;
pipes_struct *p;
static int next_pipe;
- struct msrpc_state *m = NULL;
- struct rpcsrv_struct *l = NULL;
- user_struct *vuser = get_valid_user_struct(vuid);
- struct user_creds usr;
-
- ZERO_STRUCT(usr);
DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
pipe_name, pipes_open));
- if (vuser == NULL)
- {
- DEBUG(4,("invalid vuid %d\n", vuid));
- return NULL;
- }
-
- /* set up unix credentials from the smb side, to feed over the pipe */
- make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
- vuser->real_name, vuser->guest);
- usr.ptr_uxc = 1;
- make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
- vuser->n_groups, vuser->groups);
- usr.ptr_uxs = 1;
-
- /* set up nt credentials from the smb side, to feed over the pipe */
- /* lkclXXXX todo!
- make_creds_nt(&usr.ntc);
- make_creds_nt_sec(&usr.nts);
- */
-
/* not repeating pipe numbers makes it easier to track things in
log files and prevents client bugs where pipe numbers are reused
over connection restarts */
if (next_pipe == 0)
- {
next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
- }
i = bitmap_find(bmap, next_pipe);
@@ -131,44 +133,19 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
next_pipe = (i+1) % MAX_OPEN_PIPES;
for (p = Pipes; p; p = p->next)
- {
DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
- }
-
- m = msrpc_use_add(pipe_name, &usr, False);
- if (m == NULL)
- {
- DEBUG(5,("open pipes: msrpc redirect failed\n"));
- return NULL;
- }
-#if 0
- }
- else
- {
- l = malloc(sizeof(*l));
- if (l == NULL)
- {
- DEBUG(5,("open pipes: local msrpc malloc failed\n"));
- return NULL;
- }
- ZERO_STRUCTP(l);
- l->rhdr.data = NULL;
- l->rdata.data = NULL;
- l->rhdr.offset = 0;
- l->rdata.offset = 0;
-
- l->ntlmssp_validated = False;
- l->ntlmssp_auth = False;
-
- memcpy(l->user_sess_key, vuser->user_sess_key,
- sizeof(l->user_sess_key));
- }
-#endif
p = (pipes_struct *)malloc(sizeof(*p));
- if (!p) return NULL;
+ if (!p)
+ return NULL;
ZERO_STRUCTP(p);
+
+ /*
+ * Initialize the RPC and PDU data buffers with no memory.
+ */
+ prs_init(&p->rdata, 0, 4, MARSHALL);
+
DLIST_ADD(Pipes, p);
bitmap_set(bmap, i);
@@ -177,24 +154,28 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
pipes_open++;
p->pnum = i;
- p->m = m;
- p->l = l;
p->open = True;
p->device_state = 0;
p->priority = 0;
p->conn = conn;
p->vuid = vuid;
+
+ p->max_trans_reply = 0;
- p->file_offset = 0;
- p->prev_pdu_file_offset = 0;
- p->hdr_offsets = 0;
-
- fstrcpy(p->name, pipe_name);
+ p->ntlmssp_chal_flags = 0;
+ p->ntlmssp_auth_validated = False;
+ p->ntlmssp_auth_requested = False;
- prs_init(&p->smb_pdu, 0, 4, 0, True);
- prs_init(&p->rsmb_pdu, 0, 4, 0, False);
+ p->current_pdu_len = 0;
+ p->current_pdu_sent = 0;
+ p->data_sent_length = 0;
+ p->uid = (uid_t)-1;
+ p->gid = (gid_t)-1;
+
+ fstrcpy(p->name, pipe_name);
+
DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
pipe_name, i, pipes_open));
@@ -202,182 +183,179 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
/* OVERWRITE p as a temp variable, to display all open pipes */
for (p = Pipes; p; p = p->next)
- {
DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
- }
return chain_p;
}
/****************************************************************************
- writes data to a pipe.
+ Accepts incoming data on an rpc pipe.
- SERIOUSLY ALPHA CODE!
+ This code is probably incorrect at the moment. The problem is
+ that the rpc request shouldn't really be executed until all the
+ data needed for it is received. This currently assumes that each
+ SMBwrite or SMBwriteX contains all the data needed for an rpc
+ request. JRA.
****************************************************************************/
-ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
+
+ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
{
DEBUG(6,("write_pipe: %x", p->pnum));
+
DEBUG(6,("name: %s open: %s len: %d",
- p->name, BOOLSTR(p->open), n));
+ p->name, BOOLSTR(p->open), (int)n));
dump_data(50, data, n);
- return rpc_to_smb(p, data, n) ? ((ssize_t)n) : -1;
+ return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
}
/****************************************************************************
- reads data from a pipe.
+ Replyies to a request to read data from a pipe.
- headers are interspersed with the data at regular intervals. by the time
+ Headers are interspersed with the data at PDU intervals. By the time
this function is called, the start of the data could possibly have been
read by an SMBtrans (file_offset != 0).
- calling create_rpc_reply() here is a fudge. the data should already
+ Calling create_rpc_reply() here is a hack. The data should already
have been prepared into arrays of headers + data stream sections.
****************************************************************************/
-int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
+
+int read_from_pipe(pipes_struct *p, char *data, int n)
{
- int num = 0;
- int pdu_len = 0;
- uint32 hdr_num = 0;
- int pdu_data_sent; /* amount of current pdu already sent */
- int data_pos; /* entire rpc data sent - no headers, no auth verifiers */
- int this_pdu_data_pos;
-
- DEBUG(6,("read_pipe: %x name: %s open: %s pos: %d len: %d",
- p->pnum, p->name, BOOLSTR(p->open),
- pos, n));
-
- if (!p || !p->open)
- {
- DEBUG(6,("pipe not open\n"));
+ uint32 pdu_remaining = 0;
+ int data_returned = 0;
+
+ if (!p || !p->open) {
+ DEBUG(0,("read_from_pipe: pipe not open\n"));
return -1;
}
+ DEBUG(6,("read_from_pipe: %x", p->pnum));
- if (p->rsmb_pdu.data == NULL || p->rsmb_pdu.data->data == NULL ||
- p->rsmb_pdu.data->data_used == 0)
- {
- return 0;
+ DEBUG(6,("name: %s len: %d\n", p->name, n));
+
+ /*
+ * We cannot return more than one PDU length per
+ * read request.
+ */
+
+ if(n > MAX_PDU_FRAG_LEN) {
+ DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
+only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
+ return -1;
}
- DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
- p, p->file_offset, n));
+ /*
+ * Determine if there is still data to send in the
+ * pipe PDU buffer. Always send this first. Never
+ * send more than is left in the current PDU. The
+ * client should send a new read request for a new
+ * PDU.
+ */
- /* the read request starts from where the SMBtrans2 left off. */
- data_pos = p->file_offset - p->hdr_offsets;
- pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
- this_pdu_data_pos = (pdu_data_sent == 0) ? 0 : (pdu_data_sent - 0x18);
+ if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) {
+ data_returned = MIN(n, pdu_remaining);
- if (!IS_BITS_SET_ALL(p->l->hdr.flags, RPC_FLG_LAST))
- {
- /* intermediate fragment - possibility of another header */
-
- DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
- p->l->hdr.frag_len, data_pos, pdu_data_sent));
-
- if (pdu_data_sent == 0)
- {
- DEBUG(6,("read_pipe: next fragment header\n"));
-
- /* this is subtracted from the total data bytes, later */
- hdr_num = 0x18;
- p->hdr_offsets += 0x18;
- data_pos -= 0x18;
-
- /* create and copy in a new header. */
- create_rpc_reply(p->l, data_pos);
- }
- }
-
- pdu_len = mem_buf_len(p->rsmb_pdu.data);
- num = pdu_len - this_pdu_data_pos;
-
- DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
-
- if (num > n) num = n;
- if (num <= 0)
- {
- DEBUG(5,("read_pipe: 0 or -ve data length\n"));
- return 0;
- }
+ DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
+returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len,
+ (unsigned int)p->current_pdu_sent, (int)data_returned));
- if (num < hdr_num)
- {
- DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
+ memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned);
+ p->current_pdu_sent += (uint32)data_returned;
+ return data_returned;
}
- mem_buf_copy(data, p->rsmb_pdu.data, pdu_data_sent, num);
-
- p->file_offset += num;
- pdu_data_sent += num;
-
- if (hdr_num == 0x18 && num == 0x18)
- {
- DEBUG(6,("read_pipe: just header read\n"));
+ /*
+ * At this point p->current_pdu_len == p->current_pdu_sent (which
+ * may of course be zero if this is the first return fragment.
+ */
+
+ DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n",
+ p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) ));
+
+ if(p->data_sent_length >= prs_offset(&p->rdata)) {
+ /*
+ * We have sent all possible data. Return 0.
+ */
+ return 0;
}
- if (pdu_data_sent == p->l->hdr.frag_len)
- {
- DEBUG(6,("read_pipe: next fragment expected\n"));
- p->prev_pdu_file_offset = p->file_offset;
+ /*
+ * We need to create a new PDU from the data left in p->rdata.
+ * Create the header/data/footers. This also sets up the fields
+ * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
+ * and stores the outgoing PDU in p->current_pdu.
+ */
+
+ if(!create_next_pdu(p)) {
+ DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
+ p->name));
+ return -1;
}
- return num;
-}
+ data_returned = MIN(n, p->current_pdu_len);
+ memcpy( data, p->current_pdu, (size_t)data_returned);
+ p->current_pdu_sent += (uint32)data_returned;
+ return data_returned;
+}
/****************************************************************************
- wait device state on a pipe. exactly what this is for is unknown...
+ Wait device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
+
BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
{
- if (p == NULL) return False;
+ if (p == NULL)
+ return False;
- if (p->open)
- {
- DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
- timestring(), priority, p->name));
+ if (p->open) {
+ DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
+ priority, p->name));
p->priority = priority;
return True;
}
- DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
- timestring(), priority, p->name));
+ DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
+ priority, p->name));
return False;
}
/****************************************************************************
- set device state on a pipe. exactly what this is for is unknown...
+ Set device state on a pipe. Exactly what this is for is unknown...
****************************************************************************/
+
BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
{
- if (p == NULL) return False;
+ if (p == NULL)
+ return False;
if (p->open) {
- DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
- timestring(), device_state, p->name));
+ DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
+ device_state, p->name));
p->device_state = device_state;
return True;
}
- DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
- timestring(), device_state, p->name));
+ DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
+ device_state, p->name));
return False;
}
/****************************************************************************
- close an rpc pipe
+ Close an rpc pipe.
****************************************************************************/
+
BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
{
if (!p) {
@@ -385,8 +363,7 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
return False;
}
- mem_buf_free(&(p->smb_pdu .data));
- mem_buf_free(&(p->rsmb_pdu.data));
+ prs_mem_free(&p->rdata);
bitmap_clear(bmap, p->pnum - pipe_handle_offset);
@@ -397,50 +374,31 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
DLIST_REMOVE(Pipes, p);
- if (p->m != NULL)
- {
- DEBUG(4,("closed msrpc redirect: "));
- if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
- {
- DEBUG(4,("OK\n"));
- }
- else
- {
- DEBUG(4,("FAILED\n"));
- }
- }
-
- if (p->l != NULL)
- {
- DEBUG(4,("closed msrpc local: OK\n"));
-
- mem_free_data(p->l->rdata .data);
- rpcsrv_free_temp(p->l);
-
- free(p->l);
- }
-
ZERO_STRUCTP(p);
+
free(p);
return True;
}
/****************************************************************************
- close an rpc pipe
+ Find an rpc pipe given a pipe handle in a buffer and an offset.
****************************************************************************/
+
pipes_struct *get_rpc_pipe_p(char *buf, int where)
{
int pnum = SVAL(buf,where);
- if (chain_p) return chain_p;
+ if (chain_p)
+ return chain_p;
return get_rpc_pipe(pnum);
}
/****************************************************************************
- close an rpc pipe
+ Find an rpc pipe given a pipe handle.
****************************************************************************/
+
pipes_struct *get_rpc_pipe(int pnum)
{
pipes_struct *p;
@@ -448,15 +406,11 @@ pipes_struct *get_rpc_pipe(int pnum)
DEBUG(4,("search for pipe pnum=%x\n", pnum));
for (p=Pipes;p;p=p->next)
- {
DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
p->name, p->pnum, pipes_open));
- }
- for (p=Pipes;p;p=p->next)
- {
- if (p->pnum == pnum)
- {
+ for (p=Pipes;p;p=p->next) {
+ if (p->pnum == pnum) {
chain_p = p;
return p;
}
@@ -464,4 +418,3 @@ pipes_struct *get_rpc_pipe(int pnum)
return NULL;
}
-
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
index ea3150fd3c..fc3ce9c0d2 100644
--- a/source3/rpc_server/srv_reg.c
+++ b/source3/rpc_server/srv_reg.c
@@ -1,4 +1,3 @@
-
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
@@ -38,10 +37,10 @@ static void reg_reply_close(REG_Q_CLOSE *q_r,
REG_R_CLOSE r_u;
/* set up the REG unknown_1 response */
- bzero(r_u.pol.data, POL_HND_SIZE);
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
/* close the policy handle */
- if (close_policy_hnd(&(q_r->pol)))
+ if (close_lsa_policy_hnd(&(q_r->pol)))
{
r_u.status = 0;
}
@@ -61,7 +60,7 @@ static void reg_reply_close(REG_Q_CLOSE *q_r,
/*******************************************************************
api_reg_close
********************************************************************/
-static void api_reg_close( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_close( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
REG_Q_CLOSE q_r;
@@ -71,6 +70,8 @@ static void api_reg_close( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
reg_reply_close(&q_r, rdata);
+
+ return True;
}
@@ -84,7 +85,7 @@ static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
r_u.status = 0x0;
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !open_policy_hnd(&(r_u.pol)))
+ if (r_u.status == 0x0 && !open_lsa_policy_hnd(&(r_u.pol)))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -100,7 +101,7 @@ static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
/*******************************************************************
api_reg_open
********************************************************************/
-static void api_reg_open( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_open( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
REG_Q_OPEN_HKLM q_u;
@@ -110,6 +111,8 @@ static void api_reg_open( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
reg_reply_open(&q_u, rdata);
+
+ return True;
}
@@ -126,35 +129,30 @@ static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
DEBUG(5,("reg_open_entry: %d\n", __LINE__));
- if (status == 0 && find_policy_by_hnd(&(q_u->pol)) == -1)
+ if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
{
status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
}
- if (status == 0x0 && !open_policy_hnd(&pol))
+ if (status == 0x0 && !open_lsa_policy_hnd(&pol))
{
status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
}
- unistr2_to_ascii(name, &q_u->uni_name, sizeof(name)-1);
+ fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));
if (status == 0x0)
{
DEBUG(5,("reg_open_entry: %s\n", name));
/* lkcl XXXX do a check on the name, here */
- if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions") &&
- !strequal(name, "SYSTEM\\CurrentControlSet\\Services\\NETLOGON\\Parameters\\"))
- {
- status = 0xC000000 | NT_STATUS_ACCESS_DENIED;
- }
}
- if (status == 0x0 && !set_policy_reg_name(&pol, name))
+ if (status == 0x0 && !set_lsa_policy_reg_name(&pol, name))
{
status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
}
- make_reg_r_open_entry(&r_u, &pol, status);
+ init_reg_r_open_entry(&r_u, &pol, status);
/* store the response in the SMB stream */
reg_io_r_open_entry("", &r_u, rdata, 0);
@@ -165,7 +163,7 @@ static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
/*******************************************************************
api_reg_open_entry
********************************************************************/
-static void api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_open_entry( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
REG_Q_OPEN_ENTRY q_u;
@@ -175,6 +173,8 @@ static void api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
/* construct reply. */
reg_reply_open_entry(&q_u, rdata);
+
+ return True;
}
@@ -187,32 +187,19 @@ static void reg_reply_info(REG_Q_INFO *q_u,
uint32 status = 0;
REG_R_INFO r_u;
- uint32 type = 0xcafeface;
- BUFFER2 buf;
- fstring name;
-
- ZERO_STRUCT(buf);
DEBUG(5,("reg_info: %d\n", __LINE__));
- if (status == 0x0 && !get_policy_reg_name(&q_u->pol, name))
+ if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
{
status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
}
- if (status == 0 &&
- strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions"))
+ if (status == 0)
{
- char *key = "LanmanNT";
- make_buffer2(&buf, key, strlen(key));
- type = 0x1;
- }
- else
- {
- status = 0x2; /* Win32 status code. ick */
}
- make_reg_r_info(&r_u, &type, &buf, status);
+ init_reg_r_info(&r_u, 1, "LanmanNT", 0x12, 0x12, status);
/* store the response in the SMB stream */
reg_io_r_info("", &r_u, rdata, 0);
@@ -223,7 +210,7 @@ static void reg_reply_info(REG_Q_INFO *q_u,
/*******************************************************************
api_reg_info
********************************************************************/
-static void api_reg_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_reg_info( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
REG_Q_INFO q_u;
@@ -233,6 +220,8 @@ static void api_reg_info( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
reg_reply_info(&q_u, rdata);
+
+ return True;
}
@@ -251,7 +240,7 @@ static struct api_struct api_reg_cmds[] =
/*******************************************************************
receives a reg pipe and responds.
********************************************************************/
-BOOL api_reg_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds, data);
}
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 738623ec4d..169dc2169e 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -28,11 +28,13 @@
extern int DEBUGLEVEL;
-extern fstring global_sam_name;
+extern fstring global_myworkgroup;
extern pstring global_myname;
extern DOM_SID global_sam_sid;
-extern DOM_SID global_sid_S_1_1;
-extern DOM_SID global_sid_S_1_5_20;
+
+extern rid_name domain_group_rids[];
+extern rid_name domain_alias_rids[];
+extern rid_name builtin_alias_rids[];
/*******************************************************************
This next function should be replaced with something that
@@ -69,18 +71,15 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
/* skip the requested number of entries.
not very efficient, but hey...
*/
- if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
- {
- start_idx--;
- }
+ start_idx--;
continue;
}
- user_name_len = strlen(pwd->nt_name);
- make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->nt_name, user_name_len);
- make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
+ user_name_len = strlen(pwd->smb_name);
+ init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
+ init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
pw_buf[(*num_entries)].user_rid = pwd->user_rid;
- bzero( pw_buf[(*num_entries)].nt_pwd , 16);
+ memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
/* Now check if the NT compatible password is available. */
if (pwd->smb_nt_passwd != NULL)
@@ -91,7 +90,7 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
- (*num_entries), pwd->nt_name,
+ (*num_entries), pwd->smb_name,
pwd->user_rid, pwd->acct_ctrl));
if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
@@ -121,10 +120,10 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
SAMR_R_CLOSE_HND r_u;
/* set up the SAMR unknown_1 response */
- bzero(r_u.pol.data, POL_HND_SIZE);
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
/* close the policy handle */
- if (close_policy_hnd(&(q_u->pol)))
+ if (close_lsa_policy_hnd(&(q_u->pol)))
{
r_u.status = 0;
}
@@ -145,11 +144,17 @@ static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
/*******************************************************************
api_samr_close_hnd
********************************************************************/
-static void api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CLOSE_HND q_u;
+
+ /* grab the samr unknown 1 */
samr_io_q_close_hnd("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_close_hnd(&q_u, rdata);
+
+ return True;
}
@@ -165,19 +170,19 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
r_u.status = 0x0;
/* find the connection policy handle. */
- if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->connect_pol)) == -1))
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
{
r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.domain_pol))))
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
{
/* oh, whoops. don't know what error message to return, here */
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -185,7 +190,7 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
if (r_u.status != 0 && pol_open)
{
- close_policy_hnd(&(r_u.domain_pol));
+ close_lsa_policy_hnd(&(r_u.domain_pol));
}
DEBUG(5,("samr_open_domain: %d\n", __LINE__));
@@ -200,11 +205,17 @@ static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
/*******************************************************************
api_samr_open_domain
********************************************************************/
-static void api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_OPEN_DOMAIN q_u;
+
+ /* grab the samr open */
samr_io_q_open_domain("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_open_domain(&q_u, rdata);
+
+ return True;
}
@@ -218,18 +229,18 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
uint32 status = 0x0;
/* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* find the user's rid */
- if ((status == 0x0) && (get_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
+ if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
{
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
}
- make_samr_r_unknown_2c(&r_u, status);
+ init_samr_r_unknown_2c(&r_u, status);
DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
@@ -243,11 +254,17 @@ static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
/*******************************************************************
api_samr_unknown_2c
********************************************************************/
-static void api_samr_unknown_2c( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_UNKNOWN_2C q_u;
+
+ /* grab the samr open */
samr_io_q_unknown_2c("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_unknown_2c(&q_u, rdata);
+
+ return True;
}
@@ -265,37 +282,40 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
status = 0x0;
/* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->user_pol)) == -1))
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* find the user's rid */
- if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
{
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
}
if (status == 0x0)
{
- DOM_SID usr_sid;
+ DOM_SID user_sid;
+ DOM_SID everyone_sid;
- usr_sid = global_sam_sid;
+ user_sid = global_sam_sid;
- SMB_ASSERT_ARRAY(usr_sid.sub_auths, usr_sid.num_auths+1);
+ SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
/*
* Add the user RID.
*/
- sid_append_rid(&usr_sid, rid);
+ user_sid.sub_auths[user_sid.num_auths++] = rid;
- /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
- /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
- make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &global_sid_S_1_1);
- make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &usr_sid);
+ string_to_sid(&everyone_sid, "S-1-1");
+
+ /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
+ /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
+ init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
+ init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
}
- make_samr_r_unknown_3(&r_u,
+ init_samr_r_unknown_3(&r_u,
0x0001, 0x8004,
0x00000014, 0x0002, 0x0070,
2, sid, status);
@@ -312,11 +332,17 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
/*******************************************************************
api_samr_unknown_3
********************************************************************/
-static void api_samr_unknown_3( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_UNKNOWN_3 q_u;
+
+ /* grab the samr open */
samr_io_q_unknown_3("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_unknown_3(&q_u, rdata);
+
+ return True;
}
@@ -332,9 +358,10 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
int total_entries;
r_e.status = 0x0;
+ r_e.total_num_entries = 0;
/* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
@@ -342,27 +369,16 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
become_root(True);
- get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
- MAX_SAM_ENTRIES, q_u->acb_mask);
+ get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
unbecome_root(True);
- make_samr_r_enum_dom_users(&r_e,
- q_u->start_idx + num_entries, num_entries,
+ init_samr_r_enum_dom_users(&r_e, total_entries,
+ q_u->unknown_0, num_entries,
pass, r_e.status);
/* store the response in the SMB stream */
samr_io_r_enum_dom_users("", &r_e, rdata, 0);
- if (r_e.sam != NULL)
- {
- free(r_e.sam);
- }
-
- if (r_e.uni_acct_name != NULL)
- {
- free(r_e.uni_acct_name);
- }
-
DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
}
@@ -370,331 +386,20 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
/*******************************************************************
api_samr_enum_dom_users
********************************************************************/
-static void api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_USERS q_e;
- samr_io_q_enum_dom_users("", &q_e, data, 0);
- samr_reply_enum_dom_users(&q_e, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_add_groupmem
- ********************************************************************/
-static void samr_reply_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_u,
- prs_struct *rdata)
-{
- SAMR_R_ADD_GROUPMEM r_e;
- DOM_SID group_sid;
- uint32 group_rid;
- fstring group_sid_str;
-
- r_e.status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(group_sid_str, &group_sid);
- sid_split_rid(&group_sid, &group_rid);
- }
-
- if (r_e.status == 0x0)
- {
- DEBUG(10,("sid is %s\n", group_sid_str));
-
- if (sid_equal(&group_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- r_e.status = add_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
- }
- }
-
- /* store the response in the SMB stream */
- samr_io_r_add_groupmem("", &r_e, rdata, 0);
-
- DEBUG(5,("samr_add_groupmem: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_add_groupmem
- ********************************************************************/
-static void api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_ADD_GROUPMEM q_e;
- samr_io_q_add_groupmem("", &q_e, data, 0);
- samr_reply_add_groupmem(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_del_groupmem
- ********************************************************************/
-static void samr_reply_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_u,
- prs_struct *rdata)
-{
- SAMR_R_DEL_GROUPMEM r_e;
- DOM_SID group_sid;
- uint32 group_rid;
- fstring group_sid_str;
-
- r_e.status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &group_sid))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(group_sid_str, &group_sid);
- sid_split_rid(&group_sid, &group_rid);
- }
-
- if (r_e.status == 0x0)
- {
- DEBUG(10,("sid is %s\n", group_sid_str));
-
- if (sid_equal(&group_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- r_e.status = del_group_member(group_rid, q_u->rid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
- }
- }
-
- /* store the response in the SMB stream */
- samr_io_r_del_groupmem("", &r_e, rdata, 0);
-
- DEBUG(5,("samr_del_groupmem: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_del_groupmem
- ********************************************************************/
-static void api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_DEL_GROUPMEM q_e;
- samr_io_q_del_groupmem("", &q_e, data, 0);
- samr_reply_del_groupmem(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_add_aliasmem
- ********************************************************************/
-static void samr_reply_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u,
- prs_struct *rdata)
-{
- SAMR_R_ADD_ALIASMEM r_e;
- DOM_SID alias_sid;
- uint32 alias_rid;
- fstring alias_sid_str;
-
- r_e.status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(alias_sid_str, &alias_sid);
- sid_split_rid(&alias_sid, &alias_rid);
- }
-
- if (r_e.status == 0x0)
- {
- DEBUG(10,("sid is %s\n", alias_sid_str));
-
- if (sid_equal(&alias_sid, &global_sam_sid))
- {
- DEBUG(10,("add member on Domain SID\n"));
-
- become_root(True);
- r_e.status = add_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
- {
- DEBUG(10,("add member on BUILTIN SID\n"));
-
- become_root(True);
- r_e.status = add_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- }
- }
-
- /* store the response in the SMB stream */
- samr_io_r_add_aliasmem("", &r_e, rdata, 0);
-
- DEBUG(5,("samr_add_aliasmem: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_add_aliasmem
- ********************************************************************/
-static void api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_ADD_ALIASMEM q_e;
- samr_io_q_add_aliasmem("", &q_e, data, 0);
- samr_reply_add_aliasmem(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_del_aliasmem
- ********************************************************************/
-static void samr_reply_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u,
- prs_struct *rdata)
-{
- SAMR_R_DEL_ALIASMEM r_e;
- DOM_SID alias_sid;
- uint32 alias_rid;
- fstring alias_sid_str;
-
- r_e.status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(alias_sid_str, &alias_sid);
- sid_split_rid(&alias_sid, &alias_rid);
- }
-
- if (r_e.status == 0x0)
- {
- DEBUG(10,("sid is %s\n", alias_sid_str));
-
- if (sid_equal(&alias_sid, &global_sam_sid))
- {
- DEBUG(10,("del member on Domain SID\n"));
-
- become_root(True);
- r_e.status = del_alias_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
- {
- DEBUG(10,("del member on BUILTIN SID\n"));
-
- become_root(True);
- r_e.status = del_builtin_member(alias_rid, &q_u->sid.sid) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
- else
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- }
- }
-
- /* store the response in the SMB stream */
- samr_io_r_del_aliasmem("", &r_e, rdata, 0);
-
- DEBUG(5,("samr_del_aliasmem: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_del_aliasmem
- ********************************************************************/
-static void api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_DEL_ALIASMEM q_e;
- samr_io_q_del_aliasmem("", &q_e, data, 0);
- samr_reply_del_aliasmem(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_enum_domains
- ********************************************************************/
-static void samr_reply_enum_domains(SAMR_Q_ENUM_DOMAINS *q_u,
- prs_struct *rdata)
-{
- SAMR_R_ENUM_DOMAINS r_e;
- char **doms = NULL;
- uint32 num_entries = 0;
-
- r_e.status = 0x0;
- r_e.num_entries2 = 0;
-
- ZERO_STRUCT(r_e);
-
- r_e.status = 0x0;
-
- /* find the connection policy handle. */
- if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- DEBUG(5,("samr_reply_enum_domains:\n"));
-
- if (!enumdomains(&doms, &num_entries))
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
- }
-
- if (r_e.status == 0x0)
- {
- make_samr_r_enum_domains(&r_e,
- q_u->start_idx + num_entries,
- num_entries, doms, r_e.status);
- }
-
- /* store the response in the SMB stream */
- samr_io_r_enum_domains("", &r_e, rdata, 0);
-
- free_char_array(num_entries, doms);
-
- if (r_e.sam != NULL)
- {
- free(r_e.sam);
- }
-
- if (r_e.uni_dom_name != NULL)
- {
- free(r_e.uni_dom_name);
- }
-
- DEBUG(5,("samr_enum_domains: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_samr_enum_domains
- ********************************************************************/
-static void api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_ENUM_DOMAINS q_e;
/* grab the samr open */
- samr_io_q_enum_domains("", &q_e, data, 0);
+ samr_io_q_enum_dom_users("", &q_e, data, 0);
/* construct reply. */
- samr_reply_enum_domains(&q_e, rdata);
+ samr_reply_enum_dom_users(&q_e, rdata);
+
+ return True;
}
+
/*******************************************************************
samr_reply_enum_dom_groups
********************************************************************/
@@ -702,69 +407,43 @@ static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
prs_struct *rdata)
{
SAMR_R_ENUM_DOM_GROUPS r_e;
- DOMAIN_GRP *grps = NULL;
- int num_entries = 0;
- DOM_SID sid;
- fstring sid_str;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries;
+ BOOL got_grps;
+ char *dummy_group = "Domain Admins";
r_e.status = 0x0;
- r_e.num_entries2 = 0;
+ r_e.num_entries = 0;
/* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
- sid_to_string(sid_str, &sid);
+ DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
- DEBUG(5,("samr_reply_enum_dom_groups: sid %s\n", sid_str));
+ got_grps = True;
+ num_entries = 1;
+ init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
+ pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
- if (sid_equal(&sid, &global_sam_sid))
+ if (r_e.status == 0 && got_grps)
{
- BOOL ret;
-
- become_root(True);
- ret = enumdomgroups(&grps, &num_entries);
- unbecome_root(True);
- if (!ret)
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
- }
- }
-
- if (r_e.status == 0x0)
- {
- make_samr_r_enum_dom_groups(&r_e,
- q_u->start_idx + num_entries,
- num_entries, grps, r_e.status);
+ init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
}
/* store the response in the SMB stream */
samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
- if (grps != NULL)
- {
- free(grps);
- }
-
- if (r_e.sam != NULL)
- {
- free(r_e.sam);
- }
-
- if (r_e.uni_grp_name != NULL)
- {
- free(r_e.uni_grp_name);
- }
-
DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
+
}
/*******************************************************************
api_samr_enum_dom_groups
********************************************************************/
-static void api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_GROUPS q_e;
@@ -773,6 +452,8 @@ static void api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_st
/* construct reply. */
samr_reply_enum_dom_groups(&q_e, rdata);
+
+ return True;
}
@@ -783,77 +464,50 @@ static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
prs_struct *rdata)
{
SAMR_R_ENUM_DOM_ALIASES r_e;
- LOCAL_GRP *alss = NULL;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
int num_entries = 0;
DOM_SID sid;
fstring sid_str;
+ fstring sam_sid_str;
r_e.status = 0x0;
- r_e.num_entries2 = 0;
+ r_e.num_entries = 0;
/* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_policy_samr_sid(&q_u->pol, &sid))
+ if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
{
r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
sid_to_string(sid_str, &sid);
+ sid_to_string(sam_sid_str, &global_sam_sid);
DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
/* well-known aliases */
- if (sid_equal(&sid, &global_sid_S_1_5_20))
+ if (strequal(sid_str, "S-1-5-32"))
{
- BOOL ret;
- /* builtin aliases */
-
- become_root(True);
- ret = enumdombuiltins(&alss, &num_entries);
- unbecome_root(True);
- if (!ret)
+ char *name;
+ while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
{
- r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
+ init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
+ pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
+ num_entries++;
}
}
- else if (sid_equal(&sid, &global_sam_sid))
+ else if (strequal(sid_str, sam_sid_str))
{
- BOOL ret;
/* local aliases */
-
- become_root(True);
- ret = enumdomaliases(&alss, &num_entries);
- unbecome_root(True);
- if (!ret)
- {
- r_e.status = 0xC0000000 | NT_STATUS_NO_MEMORY;
- }
+ /* oops! there's no code to deal with this */
+ DEBUG(3,("samr_reply_enum_dom_aliases: enum of aliases in our domain not supported yet\n"));
+ num_entries = 0;
}
- if (r_e.status == 0x0)
- {
- make_samr_r_enum_dom_aliases(&r_e,
- q_u->start_idx + num_entries,
- num_entries, alss, r_e.status);
- }
+ init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
/* store the response in the SMB stream */
samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
- if (alss != NULL)
- {
- free(alss);
- }
-
- if (r_e.sam != NULL)
- {
- free(r_e.sam);
- }
-
- if (r_e.uni_grp_name != NULL)
- {
- free(r_e.uni_grp_name);
- }
-
DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
}
@@ -861,7 +515,7 @@ static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
/*******************************************************************
api_samr_enum_dom_aliases
********************************************************************/
-static void api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_ALIASES q_e;
@@ -870,6 +524,8 @@ static void api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_s
/* construct reply. */
samr_reply_enum_dom_aliases(&q_e, rdata);
+
+ return True;
}
@@ -880,384 +536,88 @@ static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
prs_struct *rdata)
{
SAMR_R_QUERY_DISPINFO r_e;
- SAM_DISPINFO_CTR ctr;
+ SAM_INFO_CTR ctr;
+ SAM_INFO_1 info1;
+ SAM_INFO_2 info2;
SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- DOMAIN_GRP *grps = NULL;
- DOMAIN_GRP *sam_grps = NULL;
- uint32 data_size = 0;
- uint32 status = 0x0;
- uint16 acb_mask = ACB_NORMAL;
- int num_sam_entries = 0;
int num_entries = 0;
- int total_entries;
+ int total_entries = 0;
+ BOOL got_pwds;
+ uint16 switch_level = 0x0;
+
+ ZERO_STRUCT(r_e);
+
+ r_e.status = 0x0;
DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (find_policy_by_hnd(&(q_u->domain_pol)) == -1)
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
}
- if (status == 0x0)
+ if (r_e.status == 0x0)
{
become_root(True);
+ got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
+ unbecome_root(True);
- /* Get what we need from the password database */
switch (q_u->switch_level)
{
- case 0x2:
- {
- acb_mask = ACB_WSTRUST;
- /* Fall through */
- }
case 0x1:
- case 0x4:
- {
- get_sampwd_entries(pass, q_u->start_idx,
- &total_entries, &num_sam_entries,
- MAX_SAM_ENTRIES, acb_mask);
- break;
- }
- case 0x3:
- case 0x5:
{
- enumdomgroups(&sam_grps, &num_sam_entries);
-
- if (q_u->start_idx < num_sam_entries) {
- grps = sam_grps + q_u->start_idx;
- num_sam_entries -= q_u->start_idx;
- } else {
- num_sam_entries = 0;
- }
- break;
- }
- }
+
+ /* query disp info is for users */
+ switch_level = 0x1;
+ init_sam_info_1(&info1, ACB_NORMAL,
+ q_u->start_idx, num_entries, pass);
- unbecome_root(True);
+ ctr.sam.info1 = &info1;
- num_entries = num_sam_entries;
-
- if (num_entries > q_u->max_entries)
- {
- num_entries = q_u->max_entries;
- }
-
- if (num_entries > MAX_SAM_ENTRIES)
- {
- num_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_entries));
- }
-
- data_size = q_u->max_size;
-
- /* Now create reply structure */
- switch (q_u->switch_level)
- {
- case 0x1:
- {
- ctr.sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
- make_sam_dispinfo_1(ctr.sam.info1,
- &num_entries, &data_size,
- q_u->start_idx, pass);
break;
}
case 0x2:
{
- ctr.sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
- make_sam_dispinfo_2(ctr.sam.info2,
- &num_entries, &data_size,
- q_u->start_idx, pass);
- break;
- }
- case 0x3:
- {
- ctr.sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
- make_sam_dispinfo_3(ctr.sam.info3,
- &num_entries, &data_size,
- q_u->start_idx, grps);
- break;
- }
- case 0x4:
- {
- ctr.sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
- make_sam_dispinfo_4(ctr.sam.info4,
- &num_entries, &data_size,
- q_u->start_idx, pass);
- break;
- }
- case 0x5:
- {
- ctr.sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
- make_sam_dispinfo_5(ctr.sam.info5,
- &num_entries, &data_size,
- q_u->start_idx, grps);
- break;
- }
- default:
- {
- ctr.sam.info = NULL;
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ /* query disp info is for servers */
+ switch_level = 0x2;
+ init_sam_info_2(&info2, ACB_WSTRUST,
+ q_u->start_idx, num_entries, pass);
+
+ ctr.sam.info2 = &info2;
+
break;
}
}
}
- if ((status == 0) && (num_entries < num_sam_entries))
+ if (r_e.status == 0 && got_pwds)
{
- status = STATUS_MORE_ENTRIES;
+ init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
}
- make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
- q_u->switch_level, &ctr, status);
-
/* store the response in the SMB stream */
samr_io_r_query_dispinfo("", &r_e, rdata, 0);
- /* free malloc'd areas */
- if (sam_grps != NULL)
- {
- free(sam_grps);
- }
+ DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
- if (ctr.sam.info != NULL)
- {
- free(ctr.sam.info);
- }
-
- DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
}
/*******************************************************************
api_samr_query_dispinfo
********************************************************************/
-static void api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_DISPINFO q_e;
+ /* grab the samr open */
samr_io_q_query_dispinfo("", &q_e, data, 0);
- samr_reply_query_dispinfo(&q_e, rdata);
-}
-
-/*******************************************************************
- samr_reply_delete_dom_group
- ********************************************************************/
-static void samr_reply_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_u,
- prs_struct *rdata)
-{
- uint32 status = 0;
-
- DOM_SID group_sid;
- uint32 group_rid;
- fstring group_sid_str;
-
- SAMR_R_DELETE_DOM_GROUP r_u;
-
- DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(group_sid_str, &group_sid );
- sid_split_rid(&group_sid, &group_rid);
- }
-
- if (status == 0x0)
- {
- DEBUG(10,("sid is %s\n", group_sid_str));
-
- if (sid_equal(&group_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- status = del_group_entry(group_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
- unbecome_root(True);
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
- }
- }
-
- make_samr_r_delete_dom_group(&r_u, status);
-
- /* store the response in the SMB stream */
- samr_io_r_delete_dom_group("", &r_u, rdata, 0);
-}
-
-/*******************************************************************
- api_samr_delete_dom_group
- ********************************************************************/
-static void api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_DELETE_DOM_GROUP q_u;
- samr_io_q_delete_dom_group("", &q_u, data, 0);
- samr_reply_delete_dom_group(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_groupmem
- ********************************************************************/
-static void samr_reply_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_u,
- prs_struct *rdata)
-{
- uint32 status = 0;
-
- DOMAIN_GRP_MEMBER *mem_grp = NULL;
- uint32 *rid = NULL;
- uint32 *attr = NULL;
- int num_rids = 0;
- DOM_SID group_sid;
- uint32 group_rid;
- fstring group_sid_str;
-
- SAMR_R_QUERY_GROUPMEM r_u;
-
- DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->group_pol, &group_sid))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(group_sid_str, &group_sid );
- sid_split_rid(&group_sid, &group_rid);
- }
-
- if (status == 0x0)
- {
- DEBUG(10,("sid is %s\n", group_sid_str));
-
- if (sid_equal(&group_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- status = getgrouprid(group_rid, &mem_grp, &num_rids) != NULL ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_GROUP);
- unbecome_root(True);
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_GROUP;
- }
- }
-
- if (status == 0x0 && num_rids > 0)
- {
- rid = malloc(num_rids * sizeof(uint32));
- attr = malloc(num_rids * sizeof(uint32));
- if (mem_grp != NULL && rid != NULL && attr != NULL)
- {
- int i;
- for (i = 0; i < num_rids; i++)
- {
- rid [i] = mem_grp[i].rid;
- attr[i] = mem_grp[i].attr;
- }
- free(mem_grp);
- }
- }
-
- make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_groupmem("", &r_u, rdata, 0);
-
- if (rid != NULL)
- {
- free(rid);
- }
-
- if (attr != NULL)
- {
- free(attr);
- }
-
- DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_groupmem
- ********************************************************************/
-static void api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_QUERY_GROUPMEM q_u;
- samr_io_q_query_groupmem("", &q_u, data, 0);
- samr_reply_query_groupmem(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_query_groupinfo
- ********************************************************************/
-static void samr_reply_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_u,
- prs_struct *rdata)
-{
- SAMR_R_QUERY_GROUPINFO r_e;
- GROUP_INFO_CTR ctr;
- uint32 status = 0x0;
-
- r_e.ptr = 0;
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
- {
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- DEBUG(5,("samr_reply_query_groupinfo: %d\n", __LINE__));
-
- if (status == 0x0)
- {
- if (q_u->switch_level == 1)
- {
- r_e.ptr = 1;
- ctr.switch_value1 = 1;
- make_samr_group_info1(&ctr.group.info1,
- "fake account name",
- "fake account description", 2);
- }
- else if (q_u->switch_level == 4)
- {
- r_e.ptr = 1;
- ctr.switch_value1 = 4;
- make_samr_group_info4(&ctr.group.info4,
- "fake account description");
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- }
-
- make_samr_r_query_groupinfo(&r_e, status == 0 ? &ctr : NULL, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_groupinfo("", &r_e, rdata, 0);
- DEBUG(5,("samr_query_groupinfo: %d\n", __LINE__));
-
-}
+ /* construct reply. */
+ samr_reply_query_dispinfo(&q_e, rdata);
-/*******************************************************************
- api_samr_query_groupinfo
- ********************************************************************/
-static void api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_QUERY_GROUPINFO q_e;
- samr_io_q_query_groupinfo("", &q_e, data, 0);
- samr_reply_query_groupinfo(&q_e, rdata);
+ return True;
}
@@ -1268,34 +628,29 @@ static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
prs_struct *rdata)
{
SAMR_R_QUERY_ALIASINFO r_e;
- ALIAS_INFO_CTR ctr;
- uint32 status = 0x0;
+ r_e.status = 0x0;
r_e.ptr = 0;
/* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
- if (status == 0x0)
+ if (r_e.status == 0x0)
{
- if (q_u->switch_level == 3)
+ if (q_u->switch_level != 3)
{
- r_e.ptr = 1;
- ctr.switch_value1 = 3;
- make_samr_alias_info3(&ctr.alias.info3, "<fake account description>");
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ r_e.status = NT_STATUS_INVALID_INFO_CLASS;
}
}
- make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status);
+ init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
+ "<account description>",
+ r_e.status);
/* store the response in the SMB stream */
samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
@@ -1307,302 +662,108 @@ static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
/*******************************************************************
api_samr_query_aliasinfo
********************************************************************/
-static void api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_ALIASINFO q_e;
+
+ /* grab the samr open */
samr_io_q_query_aliasinfo("", &q_e, data, 0);
+
+ /* construct reply. */
samr_reply_query_aliasinfo(&q_e, rdata);
+
+ return True;
}
/*******************************************************************
- samr_reply_query_useraliases
+ samr_reply_lookup_ids
********************************************************************/
-static void samr_reply_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
+static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
prs_struct *rdata)
{
- uint32 status = 0;
-
- LOCAL_GRP *mem_grp = NULL;
- uint32 *rid = NULL;
- int num_rids = 0;
- struct sam_passwd *sam_pass;
- DOM_SID usr_sid;
- DOM_SID dom_sid;
- uint32 user_rid;
- fstring sam_sid_str;
- fstring dom_sid_str;
- fstring usr_sid_str;
+ uint32 rid[MAX_SAM_ENTRIES];
+ uint32 status = 0;
+ int num_rids = q_u->num_sids1;
- SAMR_R_QUERY_USERALIASES r_u;
- ZERO_STRUCT(r_u);
+ SAMR_R_LOOKUP_IDS r_u;
- DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
+ DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
+ if (num_rids > MAX_SAM_ENTRIES)
{
- sid_to_string(dom_sid_str, &dom_sid );
- sid_to_string(sam_sid_str, &global_sam_sid);
+ num_rids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
}
- if (status == 0x0)
+#if 0
+ int i;
+ SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
+
+ for (i = 0; i < num_rids && status == 0; i++)
{
- usr_sid = q_u->sid[0].sid;
- sid_split_rid(&usr_sid, &user_rid);
- sid_to_string(usr_sid_str, &usr_sid);
+ struct sam_passwd *sam_pass;
+ fstring user_name;
- }
- if (status == 0x0)
- {
+ fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
+ q_u->uni_user_name[i].uni_str_len));
+
/* find the user account */
become_root(True);
- sam_pass = getsam21pwrid(user_rid);
+ sam_pass = get_smb21pwd_entry(user_name, 0);
unbecome_root(True);
if (sam_pass == NULL)
{
status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
- num_rids = 0;
- }
- }
-
- if (status == 0x0)
- {
- DEBUG(10,("sid is %s\n", dom_sid_str));
-
- if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
- {
- DEBUG(10,("lookup on S-1-5-20\n"));
-
- become_root(True);
- getuserbuiltinntnam(sam_pass->nt_name, &mem_grp, &num_rids);
- unbecome_root(True);
- }
- else if (sid_equal(&dom_sid, &usr_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- getuseraliasntnam(sam_pass->nt_name, &mem_grp, &num_rids);
- unbecome_root(True);
+ rid[i] = 0;
}
else
{
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ rid[i] = sam_pass->user_rid;
}
}
+#endif
- if (status == 0x0 && num_rids > 0)
- {
- rid = malloc(num_rids * sizeof(uint32));
- if (mem_grp != NULL && rid != NULL)
- {
- int i;
- for (i = 0; i < num_rids; i++)
- {
- rid[i] = mem_grp[i].rid;
- }
- free(mem_grp);
- }
- }
+ num_rids = 1;
+ rid[0] = BUILTIN_ALIAS_RID_USERS;
- make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
+ init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
/* store the response in the SMB stream */
- samr_io_r_query_useraliases("", &r_u, rdata, 0);
+ samr_io_r_lookup_ids("", &r_u, rdata, 0);
- if (rid != NULL)
- {
- free(rid);
- }
+ DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
- DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_useraliases
- ********************************************************************/
-static void api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_QUERY_USERALIASES q_u;
- ZERO_STRUCT(q_u);
- samr_io_q_query_useraliases("", &q_u, data, 0);
- samr_reply_query_useraliases(&q_u, rdata);
- samr_free_q_query_useraliases(&q_u);
}
/*******************************************************************
- samr_reply_delete_dom_alias
+ api_samr_lookup_ids
********************************************************************/
-static void samr_reply_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
- uint32 status = 0;
-
- DOM_SID alias_sid;
- uint32 alias_rid;
- fstring alias_sid_str;
-
- SAMR_R_DELETE_DOM_ALIAS r_u;
+ SAMR_Q_LOOKUP_IDS q_u;
- DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
+ /* grab the samr 0x10 */
+ samr_io_q_lookup_ids("", &q_u, data, 0);
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(alias_sid_str, &alias_sid );
- sid_split_rid(&alias_sid, &alias_rid);
- }
-
- if (status == 0x0)
- {
- DEBUG(10,("sid is %s\n", alias_sid_str));
-
- if (sid_equal(&alias_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- status = del_alias_entry(alias_rid) ? 0x0 : (0xC0000000 | NT_STATUS_NO_SUCH_ALIAS);
- unbecome_root(True);
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- }
- }
-
- make_samr_r_delete_dom_alias(&r_u, status);
-
- /* store the response in the SMB stream */
- samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
-}
-
-/*******************************************************************
- api_samr_delete_dom_alias
- ********************************************************************/
-static void api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_DELETE_DOM_ALIAS q_u;
- samr_io_q_delete_dom_alias("", &q_u, data, 0);
- samr_reply_delete_dom_alias(&q_u, rdata);
-}
+ /* construct reply. always indicate success */
+ samr_reply_lookup_ids(&q_u, rdata);
-
-/*******************************************************************
- samr_reply_query_aliasmem
- ********************************************************************/
-static void samr_reply_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_u,
- prs_struct *rdata)
-{
- uint32 status = 0;
-
- LOCAL_GRP_MEMBER *mem_grp = NULL;
- DOM_SID2 *sid = NULL;
- int num_sids = 0;
- DOM_SID alias_sid;
- uint32 alias_rid;
- fstring alias_sid_str;
-
- SAMR_R_QUERY_ALIASMEM r_u;
-
- DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->alias_pol, &alias_sid))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- else
- {
- sid_to_string(alias_sid_str, &alias_sid );
- sid_split_rid(&alias_sid, &alias_rid);
- }
-
- if (status == 0x0)
- {
- DEBUG(10,("sid is %s\n", alias_sid_str));
-
- if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
- {
- DEBUG(10,("lookup on S-1-5-20\n"));
-
- become_root(True);
- status = getbuiltinrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- unbecome_root(True);
- }
- else if (sid_equal(&alias_sid, &global_sam_sid))
- {
- DEBUG(10,("lookup on Domain SID\n"));
-
- become_root(True);
- status = getaliasrid(alias_rid, &mem_grp, &num_sids) != NULL ? 0x0 : 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- unbecome_root(True);
- }
- else
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- }
- }
-
- if (status == 0x0 && num_sids > 0)
- {
- sid = malloc(num_sids * sizeof(DOM_SID));
- if (mem_grp != NULL && sid != NULL)
- {
- int i;
- for (i = 0; i < num_sids; i++)
- {
- make_dom_sid2(&sid[i], &mem_grp[i].sid);
- }
- free(mem_grp);
- }
- }
-
- make_samr_r_query_aliasmem(&r_u, num_sids, sid, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_aliasmem("", &r_u, rdata, 0);
-
- if (sid != NULL)
- {
- free(sid);
- }
-
- DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_query_aliasmem
- ********************************************************************/
-static void api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_QUERY_ALIASMEM q_u;
- samr_io_q_query_aliasmem("", &q_u, data, 0);
- samr_reply_query_aliasmem(&q_u, rdata);
+ return True;
}
/*******************************************************************
samr_reply_lookup_names
********************************************************************/
-static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+
+static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
prs_struct *rdata)
{
- uint32 rid [MAX_SAM_ENTRIES];
+ uint32 rid[MAX_SAM_ENTRIES];
uint8 type[MAX_SAM_ENTRIES];
- uint32 status = 0;
+ uint32 status = 0;
int i;
int num_rids = q_u->num_names1;
DOM_SID pol_sid;
@@ -1611,65 +772,88 @@ static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
- if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ ZERO_ARRAY(rid);
+ ZERO_ARRAY(type);
- if (num_rids > MAX_SAM_ENTRIES)
- {
+ if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
+ status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ init_samr_r_lookup_names(&r_u, 0, rid, type, status);
+ if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+ DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+ return False;
+ }
+ return True;
+ }
+
+ if (num_rids > MAX_SAM_ENTRIES) {
num_rids = MAX_SAM_ENTRIES;
DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
}
SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
- for (i = 0; i < num_rids && status == 0; i++)
- {
- DOM_SID sid;
+ for (i = 0; i < num_rids; i++) {
fstring name;
- unistr2_to_ascii(name, &q_u->uni_name[i], sizeof(name)-1);
- status = lookup_name(name, &sid, &(type[i]));
- if (status == 0x0)
- {
- sid_split_rid(&sid, &rid[i]);
- }
- else
- {
- type[i] = SID_NAME_UNKNOWN;
- rid [i] = 0xffffffff;
- }
- if (!sid_equal(&pol_sid, &sid))
- {
- rid [i] = 0xffffffff;
- type[i] = SID_NAME_UNKNOWN;
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ rid [i] = 0xffffffff;
+ type[i] = SID_NAME_UNKNOWN;
+
+ fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
+ q_u->uni_name[i].uni_str_len));
+
+ if(sid_equal(&pol_sid, &global_sam_sid)) {
+ DOM_SID sid;
+
+ if(lookup_local_name(global_myname, name, &sid, &type[i])) {
+ sid_split_rid( &sid, &rid[i]);
+ status = 0;
+ }
}
}
- make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
+ init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
/* store the response in the SMB stream */
- samr_io_r_lookup_names("", &r_u, rdata, 0);
+ if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
+ DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+ return False;
+ }
DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+ return True;
}
/*******************************************************************
api_samr_lookup_names
********************************************************************/
-static void api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+
+static BOOL api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_LOOKUP_NAMES q_u;
- samr_io_q_lookup_names("", &q_u, data, 0);
- samr_reply_lookup_names(&q_u, rdata);
+
+ memset(&q_u, '\0', sizeof(q_u));
+
+ /* grab the samr lookup names */
+ if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
+ DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
+ return False;
+ }
+
+ /* construct reply. always indicate success */
+ if(!samr_reply_lookup_names(&q_u, rdata))
+ return False;
+
+ return True;
}
/*******************************************************************
samr_reply_chgpasswd_user
********************************************************************/
-static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+
+static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
prs_struct *rdata)
{
SAMR_R_CHGPASSWD_USER r_u;
@@ -1677,8 +861,8 @@ static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
fstring user_name;
fstring wks;
- unistr2_to_ascii(user_name, &q_u->uni_user_name, sizeof(user_name)-1);
- unistr2_to_ascii(wks, &q_u->uni_dest_host, sizeof(wks)-1);
+ fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
+ fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
@@ -1689,22 +873,39 @@ static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
}
- make_samr_r_chgpasswd_user(&r_u, status);
+ init_samr_r_chgpasswd_user(&r_u, status);
/* store the response in the SMB stream */
- samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
+ if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
+ DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
+ return False;
+ }
DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
+ return True;
}
/*******************************************************************
api_samr_chgpasswd_user
********************************************************************/
-static void api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+
+static BOOL api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CHGPASSWD_USER q_u;
- samr_io_q_chgpasswd_user("", &q_u, data, 0);
- samr_reply_chgpasswd_user(&q_u, rdata);
+
+ /* unknown 38 command */
+ if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
+ DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
+ return False;
+ }
+
+ /* construct reply. */
+ if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
+ DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
+ return False;
+ }
+
+ return True;
}
@@ -1718,7 +919,7 @@ static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
- make_samr_r_unknown_38(&r_u);
+ init_samr_r_unknown_38(&r_u);
/* store the response in the SMB stream */
samr_io_r_unknown_38("", &r_u, rdata, 0);
@@ -1729,79 +930,80 @@ static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
/*******************************************************************
api_samr_unknown_38
********************************************************************/
-static void api_samr_unknown_38( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_UNKNOWN_38 q_u;
+
+ /* unknown 38 command */
samr_io_q_unknown_38("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_unknown_38(&q_u, rdata);
+
+ return True;
}
/*******************************************************************
- samr_reply_lookup_rids
+ samr_reply_unknown_12
********************************************************************/
-static void samr_reply_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
+static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
prs_struct *rdata)
{
fstring group_names[MAX_SAM_ENTRIES];
- uint8 group_attrs[MAX_SAM_ENTRIES];
+ uint32 group_attrs[MAX_SAM_ENTRIES];
uint32 status = 0;
- int num_rids = q_u->num_rids1;
- DOM_SID pol_sid;
+ int num_gids = q_u->num_gids1;
- SAMR_R_LOOKUP_RIDS r_u;
- ZERO_STRUCT(r_u);
+ SAMR_R_UNKNOWN_12 r_u;
- DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
+ DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
- if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &pol_sid))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
if (status == 0x0)
{
int i;
- if (num_rids > MAX_SAM_ENTRIES)
+ if (num_gids > MAX_SAM_ENTRIES)
{
- num_rids = MAX_SAM_ENTRIES;
- DEBUG(5,("samr_lookup_rids: truncating entries to %d\n", num_rids));
+ num_gids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
}
- for (i = 0; i < num_rids && status == 0; i++)
+ for (i = 0; i < num_gids && status == 0; i++)
{
- DOM_SID sid;
- sid_copy(&sid, &pol_sid);
- sid_append_rid(&sid, q_u->rid[i]);
- lookup_sid(&sid, group_names[i], &group_attrs[i]);
+ fstrcpy(group_names[i], "dummy group");
+ group_attrs[i] = 0x2;
}
}
- make_samr_r_lookup_rids(&r_u, num_rids, group_names, group_attrs, status);
+ init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
/* store the response in the SMB stream */
- samr_io_r_lookup_rids("", &r_u, rdata, 0);
+ samr_io_r_unknown_12("", &r_u, rdata, 0);
- DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
+ DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
}
/*******************************************************************
- api_samr_lookup_rids
+ api_samr_unknown_12
********************************************************************/
-static void api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_LOOKUP_RIDS q_u;
- ZERO_STRUCT(q_u);
- samr_io_q_lookup_rids("", &q_u, data, 0);
- samr_reply_lookup_rids(&q_u, rdata);
- samr_free_q_lookup_rids(&q_u);
+ SAMR_Q_UNKNOWN_12 q_u;
+
+ /* grab the samr lookup names */
+ samr_io_q_unknown_12("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_12(&q_u, rdata);
+
+ return True;
}
@@ -1817,18 +1019,18 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
BOOL pol_open = False;
/* set up the SAMR open_user response */
- bzero(r_u.user_pol.data, POL_HND_SIZE);
+ memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
r_u.status = 0x0;
/* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
{
r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.user_pol))))
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -1844,7 +1046,7 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
}
/* associate the RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
{
/* oh, whoops. don't know what error message to return, here */
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -1852,7 +1054,7 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
if (r_u.status != 0 && pol_open)
{
- close_policy_hnd(&(r_u.user_pol));
+ close_lsa_policy_hnd(&(r_u.user_pol));
}
DEBUG(5,("samr_open_user: %d\n", __LINE__));
@@ -1867,11 +1069,17 @@ static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
/*******************************************************************
api_samr_open_user
********************************************************************/
-static void api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_OPEN_USER q_u;
+
+ /* grab the samr unknown 22 */
samr_io_q_open_user("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_open_user(&q_u, rdata, 0x0);
+
+ return True;
}
@@ -1880,21 +1088,27 @@ static void api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *
*************************************************************************/
static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
{
- struct sam_passwd *sam_pass;
+ struct smb_passwd *smb_pass;
+
+ if (!pdb_rid_is_user(user_rid))
+ {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
become_root(True);
- sam_pass = getsam21pwrid(user_rid);
+ smb_pass = getsmbpwrid(user_rid);
unbecome_root(True);
- if (sam_pass == NULL)
+ if (smb_pass == NULL)
{
DEBUG(4,("User 0x%x not found\n", user_rid));
return False;
}
- DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
+ DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
- make_sam_user_info10(id10, sam_pass->acct_ctrl);
+ init_sam_user_info10(id10, smb_pass->acct_ctrl);
return True;
}
@@ -1904,10 +1118,17 @@ static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
*************************************************************************/
static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
{
+ NTTIME dummy_time;
struct sam_passwd *sam_pass;
LOGON_HRS hrs;
int i;
+ if (!pdb_rid_is_user(user_rid))
+ {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
+
become_root(True);
sam_pass = getsam21pwrid(user_rid);
unbecome_root(True);
@@ -1918,7 +1139,12 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
return False;
}
- DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
+ DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
+
+ dummy_time.low = 0xffffffff;
+ dummy_time.high = 0x7fffffff;
+
+ DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
/* create a LOGON_HRS structure */
hrs.len = sam_pass->hours_len;
@@ -1928,16 +1154,16 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
hrs.hours[i] = sam_pass->hours[i];
}
- make_sam_user_info21(id21,
+ init_sam_user_info21(id21,
- &sam_pass->logon_time,
- &sam_pass->logoff_time,
- &sam_pass->kickoff_time,
- &sam_pass->pass_last_set_time,
- &sam_pass->pass_can_change_time,
- &sam_pass->pass_must_change_time,
+ &dummy_time, /* logon_time */
+ &dummy_time, /* logoff_time */
+ &dummy_time, /* kickoff_time */
+ &dummy_time, /* pass_last_set_time */
+ &dummy_time, /* pass_can_change_time */
+ &dummy_time, /* pass_must_change_time */
- sam_pass->nt_name, /* user_name */
+ sam_pass->smb_name, /* user_name */
sam_pass->full_name, /* full_name */
sam_pass->home_dir, /* home_dir */
sam_pass->dir_drive, /* dir_drive */
@@ -1950,13 +1176,13 @@ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
sam_pass->user_rid, /* RID user_id */
sam_pass->group_rid, /* RID group_id */
- sam_pass->acct_ctrl,
+ sam_pass->acct_ctrl,
- sam_pass->unknown_3, /* unknown_3 */
- sam_pass->logon_divs, /* divisions per week */
- &hrs, /* logon hours */
- sam_pass->unknown_5,
- sam_pass->unknown_6);
+ sam_pass->unknown_3, /* unknown_3 */
+ sam_pass->logon_divs, /* divisions per week */
+ &hrs, /* logon hours */
+ sam_pass->unknown_5,
+ sam_pass->unknown_6);
return True;
}
@@ -1981,15 +1207,15 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
/* search for the handle */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ status = NT_STATUS_INVALID_HANDLE;
}
/* find the user's rid */
- if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
{
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
}
DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
@@ -2002,7 +1228,7 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
case 0x10:
{
info = (void*)&id10;
- status = get_user_info_10(&id10, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
+ status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
break;
}
#if 0
@@ -2023,20 +1249,20 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
case 21:
{
info = (void*)&id21;
- status = get_user_info_21(&id21, rid) ? 0 : (0xC0000000 | NT_STATUS_NO_SUCH_USER);
+ status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
break;
}
default:
{
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ status = NT_STATUS_INVALID_INFO_CLASS;
break;
}
}
}
- make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
+ init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
/* store the response in the SMB stream */
samr_io_r_query_userinfo("", &r_u, rdata, 0);
@@ -2046,296 +1272,19 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
}
/*******************************************************************
- set_user_info_24
- ********************************************************************/
-static BOOL set_user_info_24(SAM_USER_INFO_24 *id24, uint32 rid)
-{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
- UNISTR2 new_pw;
- uint32 len;
-
- if (pwd == NULL)
- {
- return False;
- }
-
- pwdb_init_sam(&new_pwd);
- copy_sam_passwd(&new_pwd, pwd);
-
- if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
- {
- return False;
- }
-
- new_pw.uni_max_len = len / 2;
- new_pw.uni_str_len = len / 2;
-
- nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
-
- new_pwd.smb_passwd = lm_hash;
- new_pwd.smb_nt_passwd = nt_hash;
-
- return mod_sam21pwd_entry(&new_pwd, True);
-}
-
-/*******************************************************************
- set_user_info_23
- ********************************************************************/
-static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
-{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
- static uchar nt_hash[16];
- static uchar lm_hash[16];
- UNISTR2 new_pw;
- uint32 len;
-
- if (id23 == NULL)
- {
- DEBUG(5, ("set_user_info_23: NULL id23\n"));
- return False;
- }
- if (pwd == NULL)
- {
- return False;
- }
-
- pwdb_init_sam(&new_pwd);
- copy_sam_passwd(&new_pwd, pwd);
- copy_id23_to_sam_passwd(&new_pwd, id23);
-
- if (!decode_pw_buffer(id23->pass, (char*)new_pw.buffer, 256, &len))
- {
- return False;
- }
-
- new_pw.uni_max_len = len / 2;
- new_pw.uni_str_len = len / 2;
-
- nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
-
- new_pwd.smb_passwd = lm_hash;
- new_pwd.smb_nt_passwd = nt_hash;
-
- return mod_sam21pwd_entry(&new_pwd, True);
-}
-
-/*******************************************************************
- set_user_info_16
- ********************************************************************/
-static BOOL set_user_info_16(SAM_USER_INFO_16 *id16, uint32 rid)
-{
- struct sam_passwd *pwd = getsam21pwrid(rid);
- struct sam_passwd new_pwd;
-
- if (id16 == NULL)
- {
- DEBUG(5, ("set_user_info_16: NULL id16\n"));
- return False;
- }
- if (pwd == NULL)
- {
- return False;
- }
-
- copy_sam_passwd(&new_pwd, pwd);
-
- new_pwd.acct_ctrl = id16->acb_info;
-
- return mod_sam21pwd_entry(&new_pwd, True);
-}
-
-/*******************************************************************
api_samr_query_userinfo
********************************************************************/
-static void api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_USERINFO q_u;
- samr_io_q_query_userinfo("", &q_u, data, 0);
- samr_reply_query_userinfo(&q_u, rdata);
-}
-
-
-/*******************************************************************
- samr_reply_set_userinfo2
- ********************************************************************/
-static void samr_reply_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
- prs_struct *rdata, uchar user_sess_key[16])
-{
- SAMR_R_SET_USERINFO2 r_u;
-
- uint32 status = 0x0;
- uint32 rid = 0x0;
-
- DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
-
- /* search for the handle */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- /* find the user's rid */
- if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
-
- /* ok! user info levels (there are lots: see MSDEV help), off we go... */
- if (status == 0x0 && q_u->info.id == NULL)
- {
- DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
-
- if (status == 0x0)
- {
- switch (q_u->switch_value)
- {
- case 16:
- {
- SAM_USER_INFO_16 *id16 = q_u->info.id16;
- status = set_user_info_16(id16, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- break;
- }
- default:
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-
- break;
- }
- }
- }
-
- make_samr_r_set_userinfo2(&r_u, status);
-
- /* store the response in the SMB stream */
- samr_io_r_set_userinfo2("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_set_userinfo2
- ********************************************************************/
-static void api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_SET_USERINFO2 q_u;
- ZERO_STRUCT(q_u);
-
- samr_io_q_set_userinfo2("", &q_u, data, 0);
- samr_reply_set_userinfo2(&q_u, rdata, p->user_sess_key);
-
- if (q_u.info.id != NULL)
- {
- free(q_u.info.id);
- }
-}
-
-
-/*******************************************************************
- samr_reply_set_userinfo
- ********************************************************************/
-static void samr_reply_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
- prs_struct *rdata, uchar user_sess_key[16])
-{
- SAMR_R_SET_USERINFO r_u;
-
- uint32 status = 0x0;
- uint32 rid = 0x0;
-
- DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
-
- /* search for the handle */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
- /* find the user's rid */
- if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
-
- /* ok! user info levels (there are lots: see MSDEV help), off we go... */
- if (status == 0x0 && q_u->info.id == NULL)
- {
- DEBUG(5,("samr_reply_set_userinfo: NULL info level\n"));
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
-
- if (status == 0x0)
- {
- switch (q_u->switch_value)
- {
- case 24:
- {
- SAM_USER_INFO_24 *id24 = q_u->info.id24;
- SamOEMhash(id24->pass, user_sess_key, True);
- status = set_user_info_24(id24, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- break;
- }
-
- case 23:
- {
- SAM_USER_INFO_23 *id23 = q_u->info.id23;
- SamOEMhash(id23->pass, user_sess_key, 1);
-#if DEBUG_PASSWORD
- DEBUG(100,("pass buff:\n"));
- dump_data(100, id23->pass, sizeof(id23->pass));
-#endif
- dbgflush();
-
- status = set_user_info_23(id23, rid) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- break;
- }
-
- default:
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
-
- break;
- }
- }
- }
-
- make_samr_r_set_userinfo(&r_u, status);
-
- /* store the response in the SMB stream */
- samr_io_r_set_userinfo("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_set_userinfo
- ********************************************************************/
-static void api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_SET_USERINFO q_u;
- ZERO_STRUCT(q_u);
+ /* grab the samr unknown 24 */
+ samr_io_q_query_userinfo("", &q_u, data, 0);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("set user info: sess_key: "));
- dump_data(100, p->user_sess_key, 16);
-#endif
- samr_io_q_set_userinfo("", &q_u, data, 0);
- samr_reply_set_userinfo(&q_u, rdata, p->user_sess_key);
+ /* construct reply. always indicate success */
+ samr_reply_query_userinfo(&q_u, rdata);
- if (q_u.info.id != NULL)
- {
- free(q_u.info.id);
- }
+ return True;
}
@@ -2356,15 +1305,15 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
{
status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
}
/* find the user's rid */
- if (status == 0x0 && (rid = get_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
{
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
}
if (status == 0x0)
@@ -2381,23 +1330,14 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
if (status == 0x0)
{
- DOMAIN_GRP *mem_grp = NULL;
-
- become_root(True);
- getusergroupsntnam(sam_pass->nt_name, &mem_grp, &num_groups);
- unbecome_root(True);
-
+ pstring groups;
+ get_domain_user_groups(groups, sam_pass->smb_name);
gids = NULL;
- num_groups = make_dom_gids(mem_grp, num_groups, &gids);
-
- if (mem_grp != NULL)
- {
- free(mem_grp);
- }
+ num_groups = make_dom_gids(groups, &gids);
}
/* construct the response. lkclXXXX: gids are not copied! */
- make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
+ init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
/* store the response in the SMB stream */
samr_io_r_query_usergroups("", &r_u, rdata, 0);
@@ -2414,234 +1354,16 @@ static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
/*******************************************************************
api_samr_query_usergroups
********************************************************************/
-static void api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_USERGROUPS q_u;
+ /* grab the samr unknown 32 */
samr_io_q_query_usergroups("", &q_u, data, 0);
- samr_reply_query_usergroups(&q_u, rdata);
-}
-
-
-/*******************************************************************
- opens a samr alias by rid, returns a policy handle.
- ********************************************************************/
-static uint32 open_samr_alias(DOM_SID *sid, POLICY_HND *alias_pol,
- uint32 alias_rid)
-{
- BOOL pol_open = False;
- uint32 status = 0x0;
-
- /* get a (unique) handle. open a policy on it. */
- if (status == 0x0 && !(pol_open = open_policy_hnd(alias_pol)))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- DEBUG(0,("TODO: verify that the alias rid exists\n"));
-
- /* associate a RID with the (unique) handle. */
- if (status == 0x0 && !set_policy_samr_rid(alias_pol, alias_rid))
- {
- /* oh, whoops. don't know what error message to return, here */
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- sid_append_rid(sid, alias_rid);
-
- /* associate an alias SID with the (unique) handle. */
- if (status == 0x0 && !set_policy_samr_sid(alias_pol, sid))
- {
- /* oh, whoops. don't know what error message to return, here */
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- if (status != 0 && pol_open)
- {
- close_policy_hnd(alias_pol);
- }
-
- return status;
-}
-
-/*******************************************************************
- samr_reply_create_dom_alias
- ********************************************************************/
-static void samr_reply_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u,
- prs_struct *rdata)
-{
- SAMR_R_CREATE_DOM_ALIAS r_u;
- DOM_SID dom_sid;
- LOCAL_GRP grp;
- POLICY_HND alias_pol;
- uint32 status = 0x0;
-
- bzero(&alias_pol, sizeof(alias_pol));
-
- DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->dom_pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- /* find the domain sid */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &dom_sid))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!sid_equal(&dom_sid, &global_sam_sid))
- {
- status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
- }
-
- if (status == 0x0)
- {
- unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
- fstrcpy(grp.comment, "");
- grp.rid = 0xffffffff;
-
- become_root(True);
- status = add_alias_entry(&grp) ? 0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
-
- if (status == 0x0)
- {
- status = open_samr_alias(&dom_sid, &alias_pol, grp.rid);
- }
-
- /* construct the response. */
- make_samr_r_create_dom_alias(&r_u, &alias_pol, grp.rid, status);
-
- /* store the response in the SMB stream */
- samr_io_r_create_dom_alias("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_create_dom_alias: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_create_dom_alias
- ********************************************************************/
-static void api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_CREATE_DOM_ALIAS q_u;
- samr_io_q_create_dom_alias("", &q_u, data, 0);
- samr_reply_create_dom_alias(&q_u, rdata);
-}
-
-
-/*******************************************************************
- opens a samr group by rid, returns a policy handle.
- ********************************************************************/
-static uint32 open_samr_group(DOM_SID *sid, POLICY_HND *group_pol,
- uint32 group_rid)
-{
- BOOL pol_open = False;
- uint32 status = 0x0;
-
- /* get a (unique) handle. open a policy on it. */
- if (status == 0x0 && !(pol_open = open_policy_hnd(group_pol)))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- DEBUG(0,("TODO: verify that the group rid exists\n"));
-
- /* associate a RID with the (unique) handle. */
- if (status == 0x0 && !set_policy_samr_rid(group_pol, group_rid))
- {
- /* oh, whoops. don't know what error message to return, here */
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- sid_append_rid(sid, group_rid);
-
- /* associate an group SID with the (unique) handle. */
- if (status == 0x0 && !set_policy_samr_sid(group_pol, sid))
- {
- /* oh, whoops. don't know what error message to return, here */
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
- if (status != 0 && pol_open)
- {
- close_policy_hnd(group_pol);
- }
-
- return status;
-}
-
-/*******************************************************************
- samr_reply_create_dom_group
- ********************************************************************/
-static void samr_reply_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_u,
- prs_struct *rdata)
-{
- SAMR_R_CREATE_DOM_GROUP r_u;
- DOM_SID dom_sid;
- DOMAIN_GRP grp;
- POLICY_HND group_pol;
- uint32 status = 0x0;
-
- bzero(&group_pol, sizeof(group_pol));
-
- DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- /* find the domain sid */
- if (status == 0x0 && !get_policy_samr_sid(&q_u->pol, &dom_sid))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- if (!sid_equal(&dom_sid, &global_sam_sid))
- {
- status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
- }
-
- if (status == 0x0)
- {
- unistr2_to_ascii(grp.name, &q_u->uni_acct_desc, sizeof(grp.name)-1);
- fstrcpy(grp.comment, "");
- grp.rid = 0xffffffff;
- grp.attr = 0x07;
-
- become_root(True);
- status = add_group_entry(&grp) ? 0x0 : (0xC0000000 | NT_STATUS_ACCESS_DENIED);
- unbecome_root(True);
- }
-
- if (status == 0x0)
- {
- status = open_samr_group(&dom_sid, &group_pol, grp.rid);
- }
-
- /* construct the response. */
- make_samr_r_create_dom_group(&r_u, &group_pol, grp.rid, status);
-
- /* store the response in the SMB stream */
- samr_io_r_create_dom_group("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_create_dom_group: %d\n", __LINE__));
-
-}
+ /* construct reply. */
+ samr_reply_query_usergroups(&q_u, rdata);
-/*******************************************************************
- api_samr_create_dom_group
- ********************************************************************/
-static void api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_CREATE_DOM_GROUP q_u;
- samr_io_q_create_dom_group("", &q_u, data, 0);
- samr_reply_create_dom_group(&q_u, rdata);
+ return True;
}
@@ -2664,7 +1386,7 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
{
r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
@@ -2674,38 +1396,10 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
{
switch (q_u->switch_value)
{
- case 0x07:
- {
- switch_value = 0x7;
- make_unk_info7(&ctr.info.inf7);
-
- break;
- }
- case 0x06:
- {
- switch_value = 0x6;
- make_unk_info6(&ctr.info.inf6);
-
- break;
- }
- case 0x03:
- {
- switch_value = 0x3;
- make_unk_info3(&ctr.info.inf3);
-
- break;
- }
case 0x02:
{
switch_value = 0x2;
- make_unk_info2(&ctr.info.inf2, global_sam_name, global_myname);
-
- break;
- }
- case 0x01:
- {
- switch_value = 0x1;
- make_unk_info1(&ctr.info.inf1);
+ init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
break;
}
@@ -2717,7 +1411,7 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
}
}
- make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
+ init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
/* store the response in the SMB stream */
samr_io_r_query_dom_info("", &r_u, rdata, 0);
@@ -2729,123 +1423,96 @@ static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
/*******************************************************************
api_samr_query_dom_info
********************************************************************/
-static void api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_DOMAIN_INFO q_e;
+
+ /* grab the samr unknown 8 command */
samr_io_q_query_dom_info("", &q_e, data, 0);
+
+ /* construct reply. */
samr_reply_query_dom_info(&q_e, rdata);
+
+ return True;
}
/*******************************************************************
- samr_reply_create_user
+ samr_reply_unknown_32
********************************************************************/
-static void samr_reply_create_user(SAMR_Q_CREATE_USER *q_u,
- prs_struct *rdata)
+static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
+ prs_struct *rdata,
+ int status)
{
- struct sam_passwd *sam_pass;
- fstring user_name;
-
- SAMR_R_CREATE_USER r_u;
- POLICY_HND pol;
- uint32 status = 0x0;
- uint32 user_rid = 0x0;
- BOOL pol_open = False;
- uint32 unk_0 = 0x30;
-
- /* find the machine account: tell the caller if it exists.
- lkclXXXX i have *no* idea if this is a problem or not
- or even if you are supposed to construct a different
- reply if the account already exists...
- */
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_policy_by_hnd(&(q_u->domain_pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- /* get a (unique) handle. open a policy on it. */
- if (status == 0x0 && !(pol_open = open_policy_hnd(&pol)))
- {
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- unistr2_to_ascii(user_name, &q_u->uni_name, sizeof(user_name)-1);
-
- sam_pass = getsam21pwntnam(user_name);
+ int i;
+ SAMR_R_UNKNOWN_32 r_u;
- if (sam_pass != NULL)
+ /* set up the SAMR unknown_32 response */
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+ if (status == 0)
{
- /* account exists: say so */
- status = 0xC0000000 | NT_STATUS_USER_EXISTS;
- }
- else
- {
- pstring err_str;
- pstring msg_str;
-
- if (!local_password_change(user_name, True,
- q_u->acb_info | ACB_DISABLED | ACB_PWNOTREQ, 0xffff,
- NULL,
- err_str, sizeof(err_str),
- msg_str, sizeof(msg_str)))
- {
- DEBUG(0,("%s\n", err_str));
- status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
- }
- else
+ for (i = 4; i < POL_HND_SIZE; i++)
{
- sam_pass = getsam21pwntnam(user_name);
- if (sam_pass == NULL)
- {
- /* account doesn't exist: say so */
- status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
- }
- else
- {
- user_rid = sam_pass->user_rid;
- unk_0 = 0x000703ff;
- }
+ r_u.pol.data[i] = i+1;
}
}
- /* associate the RID with the (unique) handle. */
- if (status == 0x0 && !set_policy_samr_rid(&pol, user_rid))
- {
- /* oh, whoops. don't know what error message to return, here */
- status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- if (status != 0 && pol_open)
- {
- close_policy_hnd(&pol);
- }
-
- DEBUG(5,("samr_create_user: %d\n", __LINE__));
+ init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
+ r_u.status = status;
- make_samr_r_create_user(&r_u, &pol, unk_0, user_rid, status);
+ DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
/* store the response in the SMB stream */
- samr_io_r_create_user("", &r_u, rdata, 0);
+ samr_io_r_unknown_32("", &r_u, rdata, 0);
- DEBUG(5,("samr_create_user: %d\n", __LINE__));
+ DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
}
/*******************************************************************
- api_samr_create_user
+ api_samr_unknown_32
********************************************************************/
-static void api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_CREATE_USER q_u;
+ uint32 status = 0;
+ struct sam_passwd *sam_pass;
+ fstring mach_acct;
+
+ SAMR_Q_UNKNOWN_32 q_u;
/* grab the samr unknown 32 */
- samr_io_q_create_user("", &q_u, data, 0);
+ samr_io_q_unknown_32("", &q_u, data, 0);
+
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
+
+ fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
+ q_u.uni_mach_acct.uni_str_len));
+
+ become_root(True);
+ sam_pass = getsam21pwnam(mach_acct);
+ unbecome_root(True);
+
+ if (sam_pass != NULL)
+ {
+ /* machine account exists: say so */
+ status = 0xC0000000 | NT_STATUS_USER_EXISTS;
+ }
+ else
+ {
+ /* this could cause trouble... */
+ DEBUG(0,("trouble!\n"));
+ status = 0;
+ }
/* construct reply. */
- samr_reply_create_user(&q_u, rdata);
+ samr_reply_unknown_32(&q_u, rdata, status);
+
+ return True;
}
@@ -2862,13 +1529,13 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
r_u.status = 0x0;
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
{
/* oh, whoops. don't know what error message to return, here */
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2876,7 +1543,7 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
if (r_u.status != 0 && pol_open)
{
- close_policy_hnd(&(r_u.connect_pol));
+ close_lsa_policy_hnd(&(r_u.connect_pol));
}
DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
@@ -2891,11 +1558,17 @@ static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
/*******************************************************************
api_samr_connect_anon
********************************************************************/
-static void api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CONNECT_ANON q_u;
+
+ /* grab the samr open policy */
samr_io_q_connect_anon("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_connect_anon(&q_u, rdata);
+
+ return True;
}
/*******************************************************************
@@ -2911,13 +1584,13 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
r_u.status = 0x0;
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.connect_pol))))
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
{
/* oh, whoops. don't know what error message to return, here */
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2925,7 +1598,7 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
if (r_u.status != 0 && pol_open)
{
- close_policy_hnd(&(r_u.connect_pol));
+ close_lsa_policy_hnd(&(r_u.connect_pol));
}
DEBUG(5,("samr_connect: %d\n", __LINE__));
@@ -2940,11 +1613,17 @@ static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
/*******************************************************************
api_samr_connect
********************************************************************/
-static void api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CONNECT q_u;
+
+ /* grab the samr open policy */
samr_io_q_connect("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
samr_reply_connect(&q_u, rdata);
+
+ return True;
}
/*******************************************************************
@@ -2954,36 +1633,19 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
prs_struct *rdata)
{
SAMR_R_OPEN_ALIAS r_u;
- DOM_SID sid;
BOOL pol_open = False;
/* set up the SAMR open_alias response */
r_u.status = 0x0;
- if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->dom_pol, &sid))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
/* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_policy_hnd(&(r_u.pol))))
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
{
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- DEBUG(0,("TODO: verify that the alias rid exists\n"));
-
/* associate a RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
- {
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- sid_append_rid(&sid, q_u->rid_alias);
-
- /* associate an alias SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_policy_samr_sid(&(r_u.pol), &sid))
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
{
/* oh, whoops. don't know what error message to return, here */
r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -2991,7 +1653,7 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
if (r_u.status != 0 && pol_open)
{
- close_policy_hnd(&(r_u.pol));
+ close_lsa_policy_hnd(&(r_u.pol));
}
DEBUG(5,("samr_open_alias: %d\n", __LINE__));
@@ -3006,117 +1668,18 @@ static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
/*******************************************************************
api_samr_open_alias
********************************************************************/
-static void api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_OPEN_ALIAS q_u;
- samr_io_q_open_alias("", &q_u, data, 0);
- samr_reply_open_alias(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_open_group
- ********************************************************************/
-static void samr_reply_open_group(SAMR_Q_OPEN_GROUP *q_u,
- prs_struct *rdata)
-{
- SAMR_R_OPEN_GROUP r_u;
- DOM_SID sid;
-
- DEBUG(5,("samr_open_group: %d\n", __LINE__));
- r_u.status = 0x0;
-
- /* find the domain sid associated with the policy handle */
- if (r_u.status == 0x0 && !get_policy_samr_sid(&q_u->domain_pol, &sid))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- if (r_u.status == 0x0 && !sid_equal(&sid, &global_sam_sid))
- {
- r_u.status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
- }
-
- if (r_u.status == 0x0)
- {
- r_u.status = open_samr_group(&sid, &r_u.pol, q_u->rid_group);
- }
-
- /* store the response in the SMB stream */
- samr_io_r_open_group("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_open_group: %d\n", __LINE__));
-
-}
-
-/*******************************************************************
- api_samr_open_group
- ********************************************************************/
-static void api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-
-{
- SAMR_Q_OPEN_GROUP q_u;
- samr_io_q_open_group("", &q_u, data, 0);
- samr_reply_open_group(&q_u, rdata);
-}
-
-/*******************************************************************
- samr_reply_lookup_domain
- ********************************************************************/
-static void samr_reply_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
- prs_struct *rdata)
-{
- SAMR_R_LOOKUP_DOMAIN r_u;
- fstring domain;
-
- DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
-
- r_u.ptr_sid = 0;
- r_u.status = 0x0;
-
- /* find the connection policy handle */
- if (find_policy_by_hnd(&(q_u->connect_pol)) == -1)
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- if (r_u.status == 0x0)
- {
- unistr2_to_ascii(domain, &(q_u->uni_domain), sizeof(domain));
- DEBUG(5, ("Lookup Domain: %s\n", domain));
-
- /* check it's one of ours */
- if (strequal(domain, global_sam_name))
- {
- make_dom_sid2(&(r_u.dom_sid), &global_sam_sid);
- r_u.ptr_sid = 1;
- }
- else if (strequal(domain, "BUILTIN"))
- {
- make_dom_sid2(&(r_u.dom_sid), &global_sid_S_1_5_20);
- r_u.ptr_sid = 1;
- }
- else
- {
- r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_DOMAIN;
- }
- }
-
- /* store the response in the SMB stream */
- samr_io_r_lookup_domain("", &r_u, rdata, 0);
+ /* grab the samr open policy */
+ samr_io_q_open_alias("", &q_u, data, 0);
- DEBUG(5,("samr_lookup_domain: %d\n", __LINE__));
-}
+ /* construct reply. always indicate success */
+ samr_reply_open_alias(&q_u, rdata);
-/*******************************************************************
- api_samr_lookup_domain
- ********************************************************************/
-static void api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_LOOKUP_DOMAIN q_u;
- samr_io_q_lookup_domain("", &q_u, data, 0);
- samr_reply_lookup_domain(&q_u, rdata);
+ return True;
}
/*******************************************************************
@@ -3127,51 +1690,32 @@ static struct api_struct api_samr_cmds [] =
{ "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
{ "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
{ "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
- { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
{ "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
{ "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
{ "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
- { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
- { "SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem },
- { "SAMR_QUERY_GROUPMEM" , SAMR_QUERY_GROUPMEM , api_samr_query_groupmem },
- { "SAMR_ADD_ALIASMEM" , SAMR_ADD_ALIASMEM , api_samr_add_aliasmem },
- { "SAMR_DEL_ALIASMEM" , SAMR_DEL_ALIASMEM , api_samr_del_aliasmem },
- { "SAMR_ADD_GROUPMEM" , SAMR_ADD_GROUPMEM , api_samr_add_groupmem },
- { "SAMR_DEL_GROUPMEM" , SAMR_DEL_GROUPMEM , api_samr_del_groupmem },
- { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
- { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
- { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
- { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
+ { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
{ "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
{ "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
{ "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
- { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
- { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
- { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
+ { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
{ "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
{ "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
- { "SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo },
- { "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
{ "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
- { "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
- { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
- { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
- { "SAMR_GET_DOM_PWINFO" , SAMR_GET_DOM_PWINFO , api_samr_unknown_38 },
+ { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
+ { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
+ { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
{ "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
{ "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
- { "SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
{ "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
- { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
- { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_unknown_3 },
- { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_unknown_2c },
+ { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
+ { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
{ NULL , 0 , NULL }
};
/*******************************************************************
receives a samr pipe and responds.
********************************************************************/
-BOOL api_samr_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
}
-
diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
index 8dd99cccc6..f42b94832b 100644
--- a/source3/rpc_server/srv_srvsvc.c
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -30,248 +30,253 @@ extern int DEBUGLEVEL;
extern pstring global_myname;
/*******************************************************************
- fill in a share info level 1 structure.
+ Fill in a share info level 1 structure.
+ ********************************************************************/
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
+static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
+{
+ int len_net_name;
+ pstring net_name;
+ pstring remark;
+ uint32 type;
- see ipc.c:fill_share_info()
+ pstrcpy(net_name, lp_servicename(snum));
+ pstrcpy(remark, lp_comment(snum));
+ pstring_sub(remark,"%S",lp_servicename(snum));
+ len_net_name = strlen(net_name);
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
+
+ init_srv_share_info1(&sh1->info_1, net_name, type, remark);
+ init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
+}
+
+/*******************************************************************
+ Fill in a share info level 2 structure.
********************************************************************/
-static void make_srv_share_1_info(SH_INFO_1 *sh1,
- SH_INFO_1_STR *str1, int snum)
+
+static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
{
int len_net_name;
pstring net_name;
pstring remark;
+ pstring path;
+ pstring passwd;
uint32 type;
pstrcpy(net_name, lp_servicename(snum));
- pstrcpy(remark , lp_comment (snum));
+ pstrcpy(remark, lp_comment(snum));
+ pstring_sub(remark,"%S",lp_servicename(snum));
+ pstrcpy(path, lp_pathname(snum));
+ pstrcpy(passwd, "");
len_net_name = strlen(net_name);
/* work out the share type */
type = STYPE_DISKTREE;
- if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC$", net_name)) type = STYPE_IPC;
- if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
-
- make_srv_share_info1 (sh1 , net_name, type, remark);
- make_srv_share_info1_str(str1, net_name, remark);
+ if (lp_print_ok(snum))
+ type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name))
+ type = STYPE_IPC;
+ if (net_name[len_net_name] == '$')
+ type |= STYPE_HIDDEN;
+
+ init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
+ init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
}
/*******************************************************************
- fill in a share info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
+ Fill in a share info structure.
********************************************************************/
-static void make_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, uint32 *snum, uint32 *svcs)
+
+static BOOL init_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
+ uint32 info_level, uint32 *resume_hnd, uint32 *total_entries)
{
- uint32 num_entries = 0;
- (*svcs) = lp_numservices();
+ int num_entries = 0;
+ int num_services = lp_numservices();
+ int snum;
- if (sh1 == NULL)
- {
- (*snum) = 0;
- return;
+ DEBUG(5,("init_srv_share_info_ctr\n"));
+
+ ZERO_STRUCTPN(ctr);
+
+ ctr->info_level = ctr->switch_value = info_level;
+ *resume_hnd = 0;
+
+ /* Count the number of entries. */
+ for (snum = 0; snum < num_services; snum++) {
+ if (lp_browseable(snum) && lp_snum_ok(snum))
+ num_entries++;
}
- DEBUG(5,("make_srv_share_1_sh1\n"));
+ *total_entries = num_entries;
+ ctr->num_entries2 = ctr->num_entries = num_entries;
+ ctr->ptr_share_info = ctr->ptr_entries = 1;
- for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
+ if (!num_entries)
+ return True;
+
+ switch (info_level) {
+ case 1:
{
- if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
- {
- make_srv_share_1_info(&(sh1->info_1 [num_entries]),
- &(sh1->info_1_str[num_entries]), (*snum));
+ SRV_SHARE_INFO_1 *info1;
+ int i = 0;
- /* move on to creating next share */
- num_entries++;
+ info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1));
+
+ for (snum = *resume_hnd; snum < num_services; snum++) {
+ if (lp_browseable(snum) && lp_snum_ok(snum)) {
+ init_srv_share_info_1(&info1[i++], snum);
+ }
}
+
+ ctr->share.info1 = info1;
+ break;
}
- sh1->num_entries_read = num_entries;
- sh1->ptr_share_info = num_entries > 0 ? 1 : 0;
- sh1->num_entries_read2 = num_entries;
-
- if ((*snum) >= (*svcs))
+ case 2:
{
- (*snum) = 0;
+ SRV_SHARE_INFO_2 *info2;
+ int i = 0;
+
+ info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2));
+
+ for (snum = *resume_hnd; snum < num_services; snum++) {
+ if (lp_browseable(snum) && lp_snum_ok(snum)) {
+ init_srv_share_info_2(&info2[i++], snum);
+ }
+ }
+
+ ctr->share.info2 = info2;
+ break;
}
-}
-/*******************************************************************
- fill in a share info level 2 structure.
+ default:
+ DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
+ return False;
+ }
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
+ return True;
+}
- see ipc.c:fill_share_info()
+/*******************************************************************
+ Inits a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
- ********************************************************************/
-static void make_srv_share_2_info(SH_INFO_2 *sh2,
- SH_INFO_2_STR *str2, int snum)
+static void init_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
+ uint32 info_level, uint32 resume_hnd)
{
- int len_net_name;
- pstring net_name;
- pstring remark;
- pstring path;
- pstring passwd;
- uint32 type;
+ DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
- pstrcpy(net_name, lp_servicename(snum));
- pstrcpy(remark , lp_comment (snum));
- pstrcpy(path , lp_pathname (snum));
- pstrcpy(passwd , "");
- len_net_name = strlen(net_name);
-
- /* work out the share type */
- type = STYPE_DISKTREE;
-
- if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC$", net_name)) type = STYPE_IPC;
- if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+ if (init_srv_share_info_ctr(&r_n->ctr, info_level,
+ &resume_hnd, &r_n->total_entries)) {
+ r_n->status = 0x0;
+ } else {
+ r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
- make_srv_share_info2 (sh2 , net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
- make_srv_share_info2_str(str2, net_name, remark, path, passwd);
+ init_enum_hnd(&r_n->enum_hnd, resume_hnd);
}
/*******************************************************************
- fill in a share info level 2 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
+ Net share enum.
+********************************************************************/
- ********************************************************************/
-static void make_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, uint32 *snum, uint32 *svcs)
+static BOOL srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ prs_struct *rdata)
{
- uint32 num_entries = 0;
- (*svcs) = lp_numservices();
+ SRV_R_NET_SHARE_ENUM r_n;
+ BOOL ret;
- if (sh2 == NULL)
- {
- (*snum) = 0;
- return;
- }
+ DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
- DEBUG(5,("make_srv_share_2_sh1\n"));
+ /* Create the list of shares for the response. */
+ init_srv_r_net_share_enum(&r_n,
+ q_n->ctr.info_level,
+ get_enum_hnd(&q_n->enum_hnd));
- for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
- {
- if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
- {
- make_srv_share_2_info(&(sh2->info_2 [num_entries]),
- &(sh2->info_2_str[num_entries]), (*snum));
+ /* store the response in the SMB stream */
+ ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
- /* move on to creating next share */
- num_entries++;
- }
- }
+ /* Free the memory used by the response. */
+ free_srv_r_net_share_enum(&r_n);
- sh2->num_entries_read = num_entries;
- sh2->ptr_share_info = num_entries > 0 ? 1 : 0;
- sh2->num_entries_read2 = num_entries;
-
- if ((*snum) >= (*svcs))
- {
- (*snum) = 0;
- }
+ DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
+
+ return ret;
}
/*******************************************************************
- makes a SRV_R_NET_SHARE_ENUM structure.
+ Inits a SRV_R_NET_SHARE_GET_INFO structure.
********************************************************************/
-static uint32 make_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+
+static void init_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
+ char *share_name, uint32 info_level)
{
uint32 status = 0x0;
- DEBUG(5,("make_srv_share_info_ctr: %d\n", __LINE__));
+ int snum;
- ctr->switch_value = switch_value;
+ DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
- switch (switch_value)
- {
+ r_n->switch_value = info_level;
+
+ snum = find_service(share_name);
+
+ if (snum >= 0) {
+ switch (info_level) {
case 1:
- {
- make_srv_share_info_1(&(ctr->share.info1), resume_hnd, total_entries);
- ctr->ptr_share_ctr = 1;
+ init_srv_share_info_1(&r_n->share.info1, snum);
break;
- }
case 2:
- {
- make_srv_share_info_2(&(ctr->share.info2), resume_hnd, total_entries);
- ctr->ptr_share_ctr = 2;
+ init_srv_share_info_2(&r_n->share.info2, snum);
break;
- }
default:
- {
- DEBUG(5,("make_srv_share_info_ctr: unsupported switch value %d\n",
- switch_value));
- (*resume_hnd = 0);
- (*total_entries) = 0;
- ctr->ptr_share_ctr = 0;
+ DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
break;
}
+ } else {
+ status = 0xC0000000 | NT_STATUS_BAD_NETWORK_NAME;
}
- return status;
+ r_n->ptr_share_ctr = (status == 0x0) ? 1 : 0;
+ r_n->status = status;
}
/*******************************************************************
- makes a SRV_R_NET_SHARE_ENUM structure.
+ Net share get info.
********************************************************************/
-static void make_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
- uint32 resume_hnd, int share_level, int switch_value)
-{
- DEBUG(5,("make_srv_r_net_share_enum: %d\n", __LINE__));
-
- r_n->share_level = share_level;
- if (share_level == 0)
- {
- r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- else
- {
- r_n->status = make_srv_share_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
- }
- if (r_n->status != 0x0)
- {
- resume_hnd = 0;
- }
- make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
-}
-/*******************************************************************
-net share enum
-********************************************************************/
-static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
- prs_struct *rdata)
+static BOOL srv_reply_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
+ prs_struct *rdata)
{
- SRV_R_NET_SHARE_ENUM r_n;
- SRV_SHARE_INFO_CTR ctr;
+ SRV_R_NET_SHARE_GET_INFO r_n;
+ char *share_name;
+ BOOL ret;
- r_n.ctr = &ctr;
+ DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
- DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
-
- /* set up the */
- make_srv_r_net_share_enum(&r_n,
- get_enum_hnd(&q_n->enum_hnd),
- q_n->share_level,
- q_n->ctr->switch_value);
+ /* Create the list of shares for the response. */
+ share_name = dos_unistr2_to_str(&q_n->uni_share_name);
+ init_srv_r_net_share_get_info(&r_n, share_name, q_n->info_level);
/* store the response in the SMB stream */
- srv_io_r_net_share_enum("", &r_n, rdata, 0);
+ ret = srv_io_r_net_share_get_info("", &r_n, rdata, 0);
- DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
+ /* Free the memory used by the response. */
+ free_srv_r_net_share_get_info(&r_n);
+
+ DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
+
+ return ret;
}
/*******************************************************************
@@ -282,11 +287,11 @@ static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
functions itself. yuck.
********************************************************************/
-static void make_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
+static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
char *name)
{
- make_srv_sess_info0 (se0 , name);
- make_srv_sess_info0_str(str0, name);
+ init_srv_sess_info0 (se0 , name);
+ init_srv_sess_info0_str(str0, name);
}
/*******************************************************************
@@ -297,39 +302,26 @@ static void make_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
functions itself. yuck.
********************************************************************/
-static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
{
uint32 num_entries = 0;
- struct connect_record *crec;
- uint32 session_count;
+ (*stot) = 1;
- if (!get_session_count(&crec, &session_count))
- {
- (*snum) = 0;
- (*stot) = 0;
- return;
- }
-
- (*stot) = session_count;
-
- DEBUG(0,("Session Count : %u\n",session_count));
-
if (ss0 == NULL)
{
(*snum) = 0;
- free(crec);
return;
}
+ DEBUG(5,("init_srv_sess_0_ss0\n"));
+
if (snum)
{
- DEBUG(0,("snum ok\n"));
for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
{
- make_srv_sess_0_info(&(ss0->info_0 [num_entries]),
- &(ss0->info_0_str[num_entries]), crec[num_entries].machine);
+ init_srv_sess_0_info(&(ss0->info_0 [num_entries]),
+ &(ss0->info_0_str[num_entries]), "MACHINE");
- DEBUG(0,("make_srv_sess_0_info\n"));
/* move on to creating next session */
/* move on to creating next sess */
num_entries++;
@@ -350,7 +342,6 @@ static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
ss0->ptr_sess_info = 0;
ss0->num_entries_read2 = 0;
}
- free(crec);
}
/*******************************************************************
@@ -361,14 +352,14 @@ static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *sto
functions itself. yuck.
********************************************************************/
-static void make_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
+static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
char *name, char *user,
uint32 num_opens,
uint32 open_time, uint32 idle_time,
uint32 usr_flgs)
{
- make_srv_sess_info1 (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
- make_srv_sess_info1_str(str1, name, user);
+ init_srv_sess_info1 (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
+ init_srv_sess_info1_str(str1, name, user);
}
/*******************************************************************
@@ -379,41 +370,26 @@ static void make_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
functions itself. yuck.
********************************************************************/
-static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
{
uint32 num_entries = 0;
- struct connect_record *crec;
- uint32 session_count;
+ (*stot) = 1;
- if (!get_session_count(&crec, &session_count))
- {
- (*snum) = 0;
- (*stot) = 0;
- return;
- }
-
- (*stot) = session_count;
-
- DEBUG(0,("Session Count (info1) : %u\n",session_count));
if (ss1 == NULL)
{
(*snum) = 0;
- free(crec);
return;
}
- DEBUG(5,("make_srv_sess_1_ss1\n"));
+ DEBUG(5,("init_srv_sess_1_ss1\n"));
if (snum)
{
for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
{
- DEBUG(0,("sess1 machine: %s, uid : %u\n",crec[num_entries].machine,crec[num_entries].uid));
- make_srv_sess_1_info(&(ss1->info_1 [num_entries]),
+ init_srv_sess_1_info(&(ss1->info_1 [num_entries]),
&(ss1->info_1_str[num_entries]),
- crec[num_entries].machine,
- uidtoname(crec[num_entries].uid), 1, 10, 5, 0);
-/* What are these on the End ??? */
+ "MACHINE", "dummy_user", 1, 10, 5, 0);
/* move on to creating next session */
/* move on to creating next sess */
@@ -437,17 +413,16 @@ static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *sto
(*stot) = 0;
}
- free(crec);
}
/*******************************************************************
makes a SRV_R_NET_SESS_ENUM structure.
********************************************************************/
-static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
+static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
uint32 status = 0x0;
- DEBUG(5,("make_srv_sess_info_ctr: %d\n", __LINE__));
+ DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -455,19 +430,19 @@ static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
{
case 0:
{
- make_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
+ init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
ctr->ptr_sess_ctr = 1;
break;
}
case 1:
{
- make_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
+ init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
ctr->ptr_sess_ctr = 1;
break;
}
default:
{
- DEBUG(5,("make_srv_sess_info_ctr: unsupported switch value %d\n",
+ DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n",
switch_value));
(*resume_hnd) = 0;
(*total_entries) = 0;
@@ -483,10 +458,10 @@ static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
/*******************************************************************
makes a SRV_R_NET_SESS_ENUM structure.
********************************************************************/
-static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
+static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
uint32 resume_hnd, int sess_level, int switch_value)
{
- DEBUG(5,("make_srv_r_net_sess_enum: %d\n", __LINE__));
+ DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
r_n->sess_level = sess_level;
if (sess_level == -1)
@@ -495,13 +470,13 @@ static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
}
else
{
- r_n->status = make_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+ r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
}
if (r_n->status != 0x0)
{
resume_hnd = 0;
}
- make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+ init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
}
/*******************************************************************
@@ -518,7 +493,7 @@ static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
/* set up the */
- make_srv_r_net_sess_enum(&r_n,
+ init_srv_r_net_sess_enum(&r_n,
get_enum_hnd(&q_n->enum_hnd),
q_n->sess_level,
q_n->ctr->switch_value);
@@ -537,20 +512,10 @@ static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
functions itself. yuck.
********************************************************************/
-static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
{
- uint32 num_entries = 0;
- struct connect_record *crec;
- uint32 connection_count;
-
- if (!get_connection_status(&crec, &connection_count))
- {
- (*snum) = 0;
- (*stot) = 0;
- return;
- }
-
- (*stot) = connection_count;
+ uint32 num_entries = 0;
+ (*stot) = 1;
if (ss0 == NULL)
{
@@ -558,13 +523,13 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
return;
}
- DEBUG(0,("make_srv_conn_0_ss0\n"));
+ DEBUG(5,("init_srv_conn_0_ss0\n"));
if (snum)
{
for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
{
- make_srv_conn_info0(&(ss0->info_0 [num_entries]), (*snum));
+ init_srv_conn_info0(&(ss0->info_0 [num_entries]), (*stot));
/* move on to creating next connection */
/* move on to creating next conn */
@@ -590,8 +555,6 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
(*stot) = 0;
}
-
- free(crec);
}
/*******************************************************************
@@ -602,13 +565,13 @@ static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto
functions itself. yuck.
********************************************************************/
-static void make_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
+static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
uint32 id, uint32 type,
uint32 num_opens, uint32 num_users, uint32 open_time,
char *usr_name, char *net_name)
{
- make_srv_conn_info1 (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
- make_srv_conn_info1_str(str1, usr_name, net_name);
+ init_srv_conn_info1 (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
+ init_srv_conn_info1_str(str1, usr_name, net_name);
}
/*******************************************************************
@@ -619,23 +582,10 @@ static void make_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
functions itself. yuck.
********************************************************************/
-static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
{
- uint32 num_entries = 0;
- time_t current_time;
- time_t diff;
-
- struct connect_record *crec;
- uint32 connection_count;
-
- if (!get_connection_status(&crec, &connection_count))
- {
- (*snum) = 0;
- (*stot) = 0;
- return;
- }
-
- (*stot) = connection_count;
+ uint32 num_entries = 0;
+ (*stot) = 1;
if (ss1 == NULL)
{
@@ -643,21 +593,15 @@ static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
return;
}
- current_time=time(NULL);
-
- DEBUG(5,("make_srv_conn_1_ss1\n"));
+ DEBUG(5,("init_srv_conn_1_ss1\n"));
if (snum)
{
for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
{
- diff = current_time - crec[num_entries].start;
- make_srv_conn_1_info(&(ss1->info_1 [num_entries]),
+ init_srv_conn_1_info(&(ss1->info_1 [num_entries]),
&(ss1->info_1_str[num_entries]),
- (*snum), 0, 0, 1, diff,uidtoname(crec[num_entries].uid),
- crec[num_entries].name);
-
-/* FIXME : type of connection + number of locked files */
+ (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
/* move on to creating next connection */
/* move on to creating next conn */
@@ -682,18 +626,16 @@ static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto
(*stot) = 0;
}
-
- free(crec);
}
/*******************************************************************
makes a SRV_R_NET_CONN_ENUM structure.
********************************************************************/
-static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
+static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
uint32 status = 0x0;
- DEBUG(5,("make_srv_conn_info_ctr: %d\n", __LINE__));
+ DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -701,19 +643,19 @@ static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
{
case 0:
{
- make_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
+ init_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
ctr->ptr_conn_ctr = 1;
break;
}
case 1:
{
- make_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
+ init_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
ctr->ptr_conn_ctr = 1;
break;
}
default:
{
- DEBUG(5,("make_srv_conn_info_ctr: unsupported switch value %d\n",
+ DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n",
switch_value));
(*resume_hnd = 0);
(*total_entries) = 0;
@@ -729,10 +671,10 @@ static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
/*******************************************************************
makes a SRV_R_NET_CONN_ENUM structure.
********************************************************************/
-static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
+static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
uint32 resume_hnd, int conn_level, int switch_value)
{
- DEBUG(5,("make_srv_r_net_conn_enum: %d\n", __LINE__));
+ DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
r_n->conn_level = conn_level;
if (conn_level == -1)
@@ -741,13 +683,13 @@ static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
}
else
{
- r_n->status = make_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+ r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
}
if (r_n->status != 0x0)
{
resume_hnd = 0;
}
- make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+ init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
}
/*******************************************************************
@@ -764,7 +706,7 @@ static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
/* set up the */
- make_srv_r_net_conn_enum(&r_n,
+ init_srv_r_net_conn_enum(&r_n,
get_enum_hnd(&q_n->enum_hnd),
q_n->conn_level,
q_n->ctr->switch_value);
@@ -778,12 +720,12 @@ static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
/*******************************************************************
fill in a file info level 3 structure.
********************************************************************/
-static void make_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
+static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
uint32 fnum, uint32 perms, uint32 num_locks,
char *path_name, char *user_name)
{
- make_srv_file_info3 (fl3 , fnum, perms, num_locks, path_name, user_name);
- make_srv_file_info3_str(str3, path_name, user_name);
+ init_srv_file_info3 (fl3 , fnum, perms, num_locks, path_name, user_name);
+ init_srv_file_info3_str(str3, path_name, user_name);
}
/*******************************************************************
@@ -794,7 +736,7 @@ static void make_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
functions itself. yuck.
********************************************************************/
-static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
+static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
{
uint32 num_entries = 0;
(*ftot) = 1;
@@ -805,11 +747,11 @@ static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
return;
}
- DEBUG(5,("make_srv_file_3_fl3\n"));
+ DEBUG(5,("init_srv_file_3_fl3\n"));
for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
{
- make_srv_file_3_info(&(fl3->info_3 [num_entries]),
+ init_srv_file_3_info(&(fl3->info_3 [num_entries]),
&(fl3->info_3_str[num_entries]),
(*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
@@ -830,11 +772,11 @@ static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *fto
/*******************************************************************
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
int switch_value, uint32 *resume_hnd, uint32 *total_entries)
{
uint32 status = 0x0;
- DEBUG(5,("make_srv_file_info_ctr: %d\n", __LINE__));
+ DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
ctr->switch_value = switch_value;
@@ -842,13 +784,13 @@ static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
{
case 3:
{
- make_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
+ init_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
ctr->ptr_file_ctr = 1;
break;
}
default:
{
- DEBUG(5,("make_srv_file_info_ctr: unsupported switch value %d\n",
+ DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n",
switch_value));
(*resume_hnd = 0);
(*total_entries) = 0;
@@ -864,10 +806,10 @@ static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
/*******************************************************************
makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
+static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
uint32 resume_hnd, int file_level, int switch_value)
{
- DEBUG(5,("make_srv_r_net_file_enum: %d\n", __LINE__));
+ DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
r_n->file_level = file_level;
if (file_level == 0)
@@ -876,13 +818,13 @@ static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
}
else
{
- r_n->status = make_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
+ r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
}
if (r_n->status != 0x0)
{
resume_hnd = 0;
}
- make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+ init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
}
/*******************************************************************
@@ -899,7 +841,7 @@ static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
/* set up the */
- make_srv_r_net_file_enum(&r_n,
+ init_srv_r_net_file_enum(&r_n,
get_enum_hnd(&q_n->enum_hnd),
q_n->file_level,
q_n->ctr->switch_value);
@@ -913,6 +855,7 @@ static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
/*******************************************************************
net server get info
********************************************************************/
+
static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
prs_struct *rdata)
{
@@ -927,12 +870,10 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
{
case 102:
{
- make_srv_info_102(&ctr.srv.sv102,
- 500, /* platform id */
- global_myname,
- lp_serverstring(),
- lp_major_announce_version(),
- lp_minor_announce_version(),
+ init_srv_info_102(&ctr.srv.sv102,
+ 500, global_myname,
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
+ lp_major_announce_version(), lp_minor_announce_version(),
lp_default_server_announce(),
0xffffffff, /* users */
0xf, /* disc */
@@ -945,13 +886,11 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
}
case 101:
{
- make_srv_info_101(&ctr.srv.sv101,
- 500, /* platform id */
- global_myname,
- lp_major_announce_version(),
- lp_minor_announce_version(),
+ init_srv_info_101(&ctr.srv.sv101,
+ 500, global_myname,
+ lp_major_announce_version(), lp_minor_announce_version(),
lp_default_server_announce(),
- lp_serverstring());
+ string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
break;
}
default:
@@ -962,7 +901,7 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
}
/* set up the net server get info structure */
- make_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
+ init_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
/* store the response in the SMB stream */
srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
@@ -972,7 +911,7 @@ static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
/*******************************************************************
********************************************************************/
-static void api_srv_net_srv_get_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_srv_get_info( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_SRV_GET_INFO q_n;
@@ -982,12 +921,14 @@ static void api_srv_net_srv_get_info( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
srv_reply_net_srv_get_info(&q_n, rdata);
+
+ return True;
}
/*******************************************************************
********************************************************************/
-static void api_srv_net_file_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_file_enum( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_FILE_ENUM q_n;
@@ -1000,12 +941,14 @@ static void api_srv_net_file_enum( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
srv_reply_net_file_enum(&q_n, rdata);
+
+ return True;
}
/*******************************************************************
********************************************************************/
-static void api_srv_net_conn_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_conn_enum( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_CONN_ENUM q_n;
@@ -1018,12 +961,14 @@ static void api_srv_net_conn_enum( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
srv_reply_net_conn_enum(&q_n, rdata);
+
+ return True;
}
/*******************************************************************
********************************************************************/
-static void api_srv_net_sess_enum( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_sess_enum( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_SESS_ENUM q_n;
@@ -1036,30 +981,63 @@ static void api_srv_net_sess_enum( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
srv_reply_net_sess_enum(&q_n, rdata);
+
+ return True;
}
/*******************************************************************
+ RPC to enumerate shares.
********************************************************************/
-static void api_srv_net_share_enum( rpcsrv_struct *p, prs_struct *data,
+
+static BOOL api_srv_net_share_enum( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_SHARE_ENUM q_n;
- SRV_SHARE_INFO_CTR ctr;
+ BOOL ret;
- q_n.ctr = &ctr;
+ /* Unmarshall the net server get enum. */
+ if(!srv_io_q_net_share_enum("", &q_n, data, 0)) {
+ DEBUG(0,("api_srv_net_share_enum: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n"));
+ return False;
+ }
- /* grab the net server get enum */
- srv_io_q_net_share_enum("", &q_n, data, 0);
+ ret = srv_reply_net_share_enum(&q_n, rdata);
- /* construct reply. always indicate success */
- srv_reply_net_share_enum(&q_n, rdata);
+ /* Free any data allocated in the unmarshalling. */
+ free_srv_q_net_share_enum(&q_n);
+
+ return ret;
+}
+
+/*******************************************************************
+ RPC to return share information.
+********************************************************************/
+
+static BOOL api_srv_net_share_get_info( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_SHARE_GET_INFO q_n;
+ BOOL ret;
+
+ /* Unmarshall the net server get info. */
+ if(!srv_io_q_net_share_get_info("", &q_n, data, 0)) {
+ DEBUG(0,("api_srv_net_share_get_info: Failed to unmarshall SRV_Q_NET_SHARE_GET_INFO.\n"));
+ return False;
+ }
+
+ ret = srv_reply_net_share_get_info(&q_n, rdata);
+
+ /* Free any data allocated in the unmarshalling. */
+ free_srv_q_net_share_get_info(&q_n);
+
+ return ret;
}
/*******************************************************************
time of day
********************************************************************/
-static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
+static BOOL srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
prs_struct *rdata)
{
SRV_R_NET_REMOTE_TOD r_n;
@@ -1076,7 +1054,7 @@ static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
t = gmtime(&unixdate);
/* set up the */
- make_time_of_day_info(&tod,
+ init_time_of_day_info(&tod,
unixdate,
0,
t->tm_hour,
@@ -1094,10 +1072,12 @@ static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
srv_io_r_net_remote_tod("", &r_n, rdata, 0);
DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
+
+ return True;
}
/*******************************************************************
********************************************************************/
-static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_srv_net_remote_tod( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
SRV_Q_NET_REMOTE_TOD q_n;
@@ -1107,6 +1087,8 @@ static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
srv_reply_net_remote_tod(&q_n, rdata);
+
+ return True;
}
@@ -1115,20 +1097,20 @@ static void api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
********************************************************************/
struct api_struct api_srv_cmds[] =
{
- { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
- { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
- { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
- { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
- { "SRV_NET_SRV_GET_INFO", SRV_NET_SRV_GET_INFO, api_srv_net_srv_get_info },
- { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
- { NULL , 0 , NULL }
+ { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
+ { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
+ { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
+ { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info },
+ { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
+ { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info },
+ { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
+ { NULL , 0 , NULL }
};
/*******************************************************************
receives a srvsvc pipe and responds.
********************************************************************/
-BOOL api_srvsvc_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
}
-
diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c
index 25dceb41a0..097ab92d76 100644
--- a/source3/rpc_server/srv_util.c
+++ b/source3/rpc_server/srv_util.c
@@ -22,4 +22,325 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* retired module */
+/* this module apparently provides an implementation of DCE/RPC over a
+ * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
+ * documentation are available (in on-line form) from the X-Open group.
+ *
+ * this module should provide a level of abstraction between SMB
+ * and DCE/RPC, while minimising the amount of mallocs, unnecessary
+ * data copies, and network traffic.
+ *
+ * in this version, which takes a "let's learn what's going on and
+ * get something running" approach, there is additional network
+ * traffic generated, but the code should be easier to understand...
+ *
+ * ... if you read the docs. or stare at packets for weeks on end.
+ *
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/*
+ * A list of the rids of well known BUILTIN and Domain users
+ * and groups.
+ */
+
+rid_name builtin_alias_rids[] =
+{
+ { BUILTIN_ALIAS_RID_ADMINS , "Administrators" },
+ { BUILTIN_ALIAS_RID_USERS , "Users" },
+ { BUILTIN_ALIAS_RID_GUESTS , "Guests" },
+ { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" },
+
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" },
+ { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" },
+ { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" },
+ { 0 , NULL }
+};
+
+/* array lookup of well-known Domain RID users. */
+rid_name domain_user_rids[] =
+{
+ { DOMAIN_USER_RID_ADMIN , "Administrator" },
+ { DOMAIN_USER_RID_GUEST , "Guest" },
+ { 0 , NULL }
+};
+
+/* array lookup of well-known Domain RID groups. */
+rid_name domain_group_rids[] =
+{
+ { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" },
+ { DOMAIN_GROUP_RID_USERS , "Domain Users" },
+ { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
+ { 0 , NULL }
+};
+
+int make_dom_gids(char *gids_str, DOM_GID **ppgids)
+{
+ char *ptr;
+ pstring s2;
+ int count;
+ DOM_GID *gids;
+
+ *ppgids = NULL;
+
+ DEBUG(4,("make_dom_gids: %s\n", gids_str));
+
+ if (gids_str == NULL || *gids_str == 0)
+ return 0;
+
+ for (count = 0, ptr = gids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2));
+ count++)
+ ;
+
+ gids = (DOM_GID *)malloc( sizeof(DOM_GID) * count );
+ if(!gids)
+ {
+ DEBUG(0,("make_dom_gids: malloc fail !\n"));
+ return 0;
+ }
+
+ for (count = 0, ptr = gids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2)) &&
+ count < LSA_MAX_GROUPS;
+ count++)
+ {
+ /* the entries are of the form GID/ATTR, ATTR being optional.*/
+ char *attr;
+ uint32 rid = 0;
+ int i;
+
+ attr = strchr(s2,'/');
+ if (attr)
+ *attr++ = 0;
+
+ if (!attr || !*attr)
+ attr = "7"; /* default value for attribute is 7 */
+
+ /* look up the RID string and see if we can turn it into a rid number */
+ for (i = 0; builtin_alias_rids[i].name != NULL; i++)
+ {
+ if (strequal(builtin_alias_rids[i].name, s2))
+ {
+ rid = builtin_alias_rids[i].rid;
+ break;
+ }
+ }
+
+ if (rid == 0)
+ rid = atoi(s2);
+
+ if (rid == 0)
+ {
+ DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n", s2, attr));
+ count--;
+ }
+ else
+ {
+ gids[count].g_rid = rid;
+ gids[count].attr = atoi(attr);
+
+ DEBUG(5,("group id: %d attr: %d\n", gids[count].g_rid, gids[count].attr));
+ }
+ }
+
+ *ppgids = gids;
+ return count;
+}
+
+
+/*******************************************************************
+ gets a domain user's groups
+ ********************************************************************/
+void get_domain_user_groups(char *domain_groups, char *user)
+{
+ pstring tmp;
+
+ if (domain_groups == NULL || user == NULL) return;
+
+ /* any additional groups this user is in. e.g power users */
+ pstrcpy(domain_groups, lp_domain_groups());
+
+ /* can only be a user or a guest. cannot be guest _and_ admin */
+ if (user_in_list(user, lp_domain_guest_group()))
+ {
+ slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
+ pstrcat(domain_groups, tmp);
+
+ DEBUG(3,("domain guest group access %s granted\n", tmp));
+ }
+ else
+ {
+ slprintf(tmp, sizeof(tmp) -1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
+ pstrcat(domain_groups, tmp);
+
+ DEBUG(3,("domain group access %s granted\n", tmp));
+
+ if (user_in_list(user, lp_domain_admin_group()))
+ {
+ slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
+ pstrcat(domain_groups, tmp);
+
+ DEBUG(3,("domain admin group access %s granted\n", tmp));
+ }
+ }
+}
+
+
+/*******************************************************************
+ lookup_group_name
+ ********************************************************************/
+uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type)
+{
+ int i = 0;
+ (*type) = SID_NAME_DOM_GRP;
+
+ DEBUG(5,("lookup_group_name: rid: %d", rid));
+
+ while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
+ {
+ i++;
+ }
+
+ if (domain_group_rids[i].rid != 0)
+ {
+ fstrcpy(group_name, domain_group_rids[i].name);
+ DEBUG(5,(" = %s\n", group_name));
+ return 0x0;
+ }
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_alias_name
+ ********************************************************************/
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
+{
+ int i = 0;
+ (*type) = SID_NAME_WKN_GRP;
+
+ DEBUG(5,("lookup_alias_name: rid: %d", rid));
+
+ while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
+ {
+ i++;
+ }
+
+ if (builtin_alias_rids[i].rid != 0)
+ {
+ fstrcpy(alias_name, builtin_alias_rids[i].name);
+ DEBUG(5,(" = %s\n", alias_name));
+ return 0x0;
+ }
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_name
+ ********************************************************************/
+uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type)
+{
+ struct sam_disp_info *disp_info;
+ int i = 0;
+ (*type) = SID_NAME_USER;
+
+ DEBUG(5,("lookup_user_name: rid: %d", rid));
+
+ /* look up the well-known domain user rids first */
+ while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
+ {
+ i++;
+ }
+
+ if (domain_user_rids[i].rid != 0)
+ {
+ fstrcpy(user_name, domain_user_rids[i].name);
+ DEBUG(5,(" = %s\n", user_name));
+ return 0x0;
+ }
+
+ /* ok, it's a user. find the user account */
+ become_root(True);
+ disp_info = getsamdisprid(rid);
+ unbecome_root(True);
+
+ if (disp_info != NULL)
+ {
+ fstrcpy(user_name, disp_info->smb_name);
+ DEBUG(5,(" = %s\n", user_name));
+ return 0x0;
+ }
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_group_rid
+ ********************************************************************/
+uint32 lookup_group_rid(char *group_name, uint32 *rid)
+{
+ char *grp_name;
+ int i = -1; /* start do loop at -1 */
+
+ do /* find, if it exists, a group rid for the group name*/
+ {
+ i++;
+ (*rid) = domain_group_rids[i].rid;
+ grp_name = domain_group_rids[i].name;
+
+ } while (grp_name != NULL && !strequal(grp_name, group_name));
+
+ return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_alias_rid
+ ********************************************************************/
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid)
+{
+ char *als_name;
+ int i = -1; /* start do loop at -1 */
+
+ do /* find, if it exists, a alias rid for the alias name*/
+ {
+ i++;
+ (*rid) = builtin_alias_rids[i].rid;
+ als_name = builtin_alias_rids[i].name;
+
+ } while (als_name != NULL && !strequal(als_name, alias_name));
+
+ return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_rid
+ ********************************************************************/
+uint32 lookup_user_rid(char *user_name, uint32 *rid)
+{
+ struct sam_passwd *sam_pass;
+ (*rid) = 0;
+
+ /* find the user account */
+ become_root(True);
+ sam_pass = getsam21pwnam(user_name);
+ unbecome_root(True);
+
+ if (sam_pass != NULL)
+ {
+ (*rid) = sam_pass->user_rid;
+ return 0x0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
diff --git a/source3/rpc_server/srv_wkssvc.c b/source3/rpc_server/srv_wkssvc.c
index e97ae1ee6e..658cadc625 100644
--- a/source3/rpc_server/srv_wkssvc.c
+++ b/source3/rpc_server/srv_wkssvc.c
@@ -46,7 +46,7 @@ static void create_wks_info_100(WKS_INFO_100 *inf)
pstrcpy (domain , lp_workgroup());
strupper(domain);
- make_wks_info_100(inf,
+ init_wks_info_100(inf,
0x000001f4, /* platform id info */
lp_major_announce_version(),
lp_minor_announce_version(),
@@ -69,7 +69,7 @@ static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
DEBUG(5,("wks_query_info: %d\n", __LINE__));
create_wks_info_100(&wks100);
- make_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
+ init_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
/* store the response in the SMB stream */
wks_io_r_query_info("", &r_u, rdata, 0);
@@ -80,7 +80,7 @@ static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
/*******************************************************************
api_wks_query_info
********************************************************************/
-static void api_wks_query_info( rpcsrv_struct *p, prs_struct *data,
+static BOOL api_wks_query_info( uint16 vuid, prs_struct *data,
prs_struct *rdata )
{
WKS_Q_QUERY_INFO q_u;
@@ -90,6 +90,8 @@ static void api_wks_query_info( rpcsrv_struct *p, prs_struct *data,
/* construct reply. always indicate success */
wks_reply_query_info(&q_u, rdata, 0x0);
+
+ return True;
}
@@ -105,7 +107,7 @@ struct api_struct api_wks_cmds[] =
/*******************************************************************
receives a wkssvc pipe and responds.
********************************************************************/
-BOOL api_wkssvc_rpc(rpcsrv_struct *p, prs_struct *data)
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data)
{
return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds, data);
}