diff options
-rw-r--r-- | source3/include/proto.h | 23 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 42 | ||||
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/passdb/ldap.c | 6 | ||||
-rw-r--r-- | source3/passdb/nispass.c | 6 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 27 | ||||
-rw-r--r-- | source3/passdb/smbpass.c | 1 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 325 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr.c | 186 | ||||
-rw-r--r-- | source3/rpc_server/srv_util.c | 2 |
10 files changed, 593 insertions, 26 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 83848e45e7..11c9f19393 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1140,6 +1140,7 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd, /*The following definitions come from passdb/passdb.c */ BOOL initialize_password_db(void); +struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid); struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid); struct smb_passwd *iterate_getsmbpwnam(char *name); void *startsmbpwent(BOOL update); @@ -1148,6 +1149,7 @@ struct smb_passwd *getsmbpwent(void *vp); BOOL add_smbpwd_entry(struct smb_passwd *newpwd); BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override); struct smb_passwd *getsmbpwnam(char *name); +struct smb_passwd *getsmbpwrid(uint32 user_rid); struct smb_passwd *getsmbpwuid(uid_t smb_userid); struct sam_passwd *iterate_getsam21pwnam(char *name); struct sam_passwd *iterate_getsam21pwrid(uint32 rid); @@ -1174,6 +1176,7 @@ void pdb_sethexpwd(char *p, char *pwd, uint16 acct_ctrl); BOOL pdb_gethexpwd(char *p, char *pwd); BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid); BOOL pdb_generate_machine_sid(void); +uid_t pdb_user_rid_to_uid(uint32 user_rid); uint32 pdb_uid_to_user_rid(uid_t uid); uint32 pdb_gid_to_group_rid(gid_t gid); BOOL pdb_rid_is_user(uint32 rid); @@ -1610,12 +1613,22 @@ void make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u, DOM_SID *sid); void samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth); void samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth); +void make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol); +void samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth); +void make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status); +void samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth); void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, POLICY_HND *user_pol, uint16 switch_value); void samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth); void make_samr_q_unknown_8(SAMR_Q_UNKNOWN_8 *q_u, POLICY_HND *domain_pol, uint16 switch_value); void samr_io_q_unknown_8(char *desc, SAMR_Q_UNKNOWN_8 *q_u, prs_struct *ps, int depth); +void make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server); +void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth); +void make_samr_r_unknown_8(SAMR_R_UNKNOWN_8 *r_u, + uint16 switch_value, SAM_UNK_CTR *ctr, + uint32 status); +void samr_io_r_unknown_8(char *desc, SAMR_R_UNKNOWN_8 *r_u, prs_struct *ps, int depth); void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid); void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u, uint16 unknown_2, uint16 unknown_3, @@ -1692,6 +1705,16 @@ void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_s void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u, POLICY_HND *hnd, uint16 switch_value); void samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth); +void make_sam_user_info10(SAM_USER_INFO_10 *usr, + uint32 acb_info); +void sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth); +void make_sam_user_info11(SAM_USER_INFO_11 *usr, + NTTIME *expiry, + char *mach_acct, + uint32 rid_user, + uint32 rid_group, + uint16 acct_ctrl); +void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth); void make_sam_user_info21(SAM_USER_INFO_21 *usr, NTTIME *logon_time, diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index baae9a3bd9..2a22919642 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -89,6 +89,7 @@ SamrTestPrivateFunctionsUser #define SAMR_QUERY_USERGROUPS 0x27 #define SAMR_UNKNOWN_12 0x12 #define SAMR_UNKNOWN_21 0x21 +#define SAMR_UNKNOWN_2C 0x2c #define SAMR_UNKNOWN_32 0x32 #define SAMR_UNKNOWN_34 0x34 #define SAMR_CHGPASSWD_USER 0x37 @@ -210,7 +211,7 @@ typedef struct sam_user_info_11 /* SAM_USER_INFO_10 */ typedef struct sam_user_info_10 { - uint32 rid_group; + uint32 acb_info; } SAM_USER_INFO_10; @@ -234,13 +235,39 @@ typedef struct r_samr_close_hnd_info /**************************************************************************** +SAMR_Q_UNKNOWN_2C - a "set user info" occurs just after this +*****************************************************************************/ + +/* SAMR_Q_UNKNOWN_2C */ +typedef struct q_samr_unknown_2c_info +{ + POLICY_HND user_pol; /* policy handle */ + +} SAMR_Q_UNKNOWN_2C; + + +/**************************************************************************** +SAMR_R_UNKNOWN_2C - a "set user info" occurs just after this +*****************************************************************************/ + +/* SAMR_R_UNKNOWN_2C */ +typedef struct r_samr_unknown_2c_info +{ + uint32 unknown_0; /* 0x0016 0000 */ + uint32 unknown_1; /* 0x0000 0000 */ + uint32 status; + +} SAMR_R_UNKNOWN_2C; + + +/**************************************************************************** SAMR_Q_UNKNOWN_3 - info level 4. returns SIDs. *****************************************************************************/ /* SAMR_Q_UNKNOWN_3 - probably get domain info... */ typedef struct q_samr_unknown_3_info { - POLICY_HND user_pol; /* policy handle */ + POLICY_HND user_pol; /* policy handle */ uint16 switch_value; /* 0x0000 0004 */ /* uint8 pad[2] */ @@ -317,7 +344,7 @@ SAMR_Q_UNKNOWN_8 - probably a query on domain group info. /* SAMR_Q_UNKNOWN_8 - */ typedef struct q_samr_unknown_8_info { - POLICY_HND domain_pol; /* policy handle */ + POLICY_HND domain_pol; /* policy handle */ uint16 switch_value; /* 0x0002 */ } SAMR_Q_UNKNOWN_8; @@ -325,9 +352,8 @@ typedef struct q_samr_unknown_8_info typedef struct sam_unkown_info_2_info { uint32 unknown_0; /* 0x0000 0000 */ - uint32 unknown_1; /* 0x0000 0000 */ - uint32 unknown_2; /* 0x8000 0000 */ - uint32 unknown_3; /* 0x0000 0000 */ + uint32 unknown_1; /* 0x8000 0000 */ + uint32 unknown_2; /* 0x0000 0000 */ uint32 ptr_0; /* pointer to unknown structure */ UNIHDR hdr_domain; /* domain name unicode header */ @@ -337,7 +363,7 @@ typedef struct sam_unkown_info_2_info pointer is referring to */ - uint32 unknown_4; /* 0x0000 0099 */ + uint32 unknown_4; /* 0x0000 0099 or 0x1000 0000 */ uint32 unknown_5; /* 0x0000 0000 */ uint32 unknown_6 ; /* 0x0000 0001 */ @@ -368,7 +394,7 @@ typedef struct sam_unknown_ctr_info /* SAMR_R_UNKNOWN_8 - */ typedef struct r_samr_unknown_8_info { - uint32 ptr_1; + uint32 ptr_0; uint16 switch_value; /* same as in query */ SAM_UNK_CTR *ctr; diff --git a/source3/include/smb.h b/source3/include/smb.h index 4cc5599f44..f755b81b92 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -667,6 +667,7 @@ struct passdb_ops { */ struct smb_passwd *(*getsmbpwnam)(char *); struct smb_passwd *(*getsmbpwuid)(uid_t); + struct smb_passwd *(*getsmbpwrid)(uint32); struct smb_passwd *(*getsmbpwent)(void *); /* diff --git a/source3/passdb/ldap.c b/source3/passdb/ldap.c index 59b06d7e6f..b673b81683 100644 --- a/source3/passdb/ldap.c +++ b/source3/passdb/ldap.c @@ -930,6 +930,11 @@ static struct smb_passwd *getldappwuid(uid_t smb_userid) return pdb_sam_to_smb(iterate_getsam21pwuid(smb_userid)); } +static struct smb_passwd *getldappwrid(uint32 user_rid) +{ + return pdb_sam_to_smb(iterate_getsam21pwuid(pdb_user_rid_to_uid(user_rid))); +} + static struct smb_passwd *getldappwent(void *vp) { return pdb_sam_to_smb(getldap21pwent(vp)); @@ -973,6 +978,7 @@ static struct passdb_ops ldap_ops = setldappwpos, getldappwnam, getldappwuid, + getldappwrid, getldappwent, add_ldappwd_entry, mod_ldappwd_entry, diff --git a/source3/passdb/nispass.c b/source3/passdb/nispass.c index 32cf42f95b..e750fec1a1 100644 --- a/source3/passdb/nispass.c +++ b/source3/passdb/nispass.c @@ -626,6 +626,11 @@ static struct sam_passwd *getnisp21pwuid(uid_t smb_userid) return getnisp21pwrid(pdb_uid_to_user_rid(smb_userid)); } +static struct smb_passwd *getnisppwrid(uid_t user_rid) +{ + return pdb_sam_to_smb(getnisp21pwuid(pdb_user_rid_to_uid(user_rid))); +} + static struct smb_passwd *getnisppwuid(uid_t smb_userid) { return pdb_sam_to_smb(getnisp21pwuid(smb_userid)); @@ -653,6 +658,7 @@ static struct passdb_ops nispasswd_ops = { setnisppwpos, getnisppwnam, getnisppwuid, + getnisppwrid, getnisppwent, add_nisppwd_entry, mod_nisppwd_entry, diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index a4bb657e80..0cd2f6ef2e 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -85,6 +85,15 @@ BOOL initialize_password_db(void) */ /************************************************************************ + Utility function to search smb passwd by rid. +*************************************************************************/ + +struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid) +{ + return iterate_getsmbpwuid(pdb_user_rid_to_uid(user_rid)); +} + +/************************************************************************ Utility function to search smb passwd by uid. use this if your database does not have search facilities. *************************************************************************/ @@ -223,6 +232,15 @@ struct smb_passwd *getsmbpwnam(char *name) } /************************************************************************ + Routine to search smb passwd by user rid. +*************************************************************************/ + +struct smb_passwd *getsmbpwrid(uint32 user_rid) +{ + return pdb_ops->getsmbpwrid(user_rid); +} + +/************************************************************************ Routine to search smb passwd by uid. *************************************************************************/ @@ -966,6 +984,15 @@ Error was %s\n", sid_file, strerror(errno) )); converts UNIX uid to an NT User RID. ********************************************************************/ +uid_t pdb_user_rid_to_uid(uint32 user_rid) +{ + return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER); +} + +/******************************************************************* + converts UNIX uid to an NT User RID. + ********************************************************************/ + uint32 pdb_uid_to_user_rid(uid_t uid) { return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE); diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index bde696290d..c8d817dc40 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -990,6 +990,7 @@ static struct passdb_ops file_ops = { setsmbfilepwpos, iterate_getsmbpwnam, /* In passdb.c */ iterate_getsmbpwuid, /* In passdb.c */ + iterate_getsmbpwrid, /* In passdb.c */ getsmbfilepwent, add_smbfilepwd_entry, mod_smbfilepwd_entry, diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index 40041e67c5..416498a186 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -133,6 +133,67 @@ void samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, /******************************************************************* reads or writes a structure. ********************************************************************/ +void make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol) +{ + if (q_u == NULL) return; + + DEBUG(5,("samr_make_q_unknown_2c\n")); + + memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol)); +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_q_unknown_2c"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth); + prs_align(ps); +} + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status) +{ + if (q_u == NULL) return; + + DEBUG(5,("samr_make_r_unknown_2c\n")); + + q_u->unknown_0 = 0x00160000; + q_u->unknown_1 = 0x00000000; + q_u->status = status; +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_unknown_2c"); + depth++; + + prs_align(ps); + + prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0)); + prs_uint32("unknown_1", ps, depth, &(r_u->unknown_1)); + prs_uint32("status ", ps, depth, &(r_u->status )); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, POLICY_HND *user_pol, uint16 switch_value) { @@ -196,6 +257,139 @@ void samr_io_q_unknown_8(char *desc, SAMR_Q_UNKNOWN_8 *q_u, prs_struct *ps, int prs_uint16("switch_value", ps, depth, &(q_u->switch_value)); prs_align(ps); } + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server) +{ + int len_domain = strlen(domain); + int len_server = strlen(server); + + if (u_2 == NULL) return; + + u_2->unknown_0 = 0x00000000; + u_2->unknown_1 = 0x80000000; + u_2->unknown_2 = 0x00000000; + + u_2->ptr_0 = 1; + make_uni_hdr(&(u_2->hdr_domain), len_domain, len_domain, 1); + make_uni_hdr(&(u_2->hdr_server), len_server, len_server, 1); + + u_2->unknown_4 = 0x10000000; + u_2->unknown_5 = 0x00000000; + + u_2->unknown_6 = 0x00000001; + u_2->unknown_7 = 0x00000003; + u_2->unknown_8 = 0x00000001; + u_2->unknown_9 = 0x00000008; + u_2->unknown_10 = 0x00000003; + + memset(u_2->padding, 0, sizeof(u_2->padding)); /* 16 bytes zeros */ + + make_unistr2(&u_2->uni_domain, domain, len_domain); + make_unistr2(&u_2->uni_server, server, len_server); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth) +{ + if (u_2 == NULL) return; + + prs_debug(ps, depth, desc, "sam_io_unk_info2"); + depth++; + + prs_uint32("unknown_0", ps, depth, &u_2->unknown_0); /* 0x0000 0000 */ + prs_uint32("unknown_1", ps, depth, &u_2->unknown_1); /* 0x8000 0000 */ + prs_uint32("unknown_2", ps, depth, &u_2->unknown_2); /* 0x0000 0000 */ + + prs_uint32("ptr_0", ps, depth, &u_2->ptr_0); /* pointer to unknown structure */ + smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth); /* domain name unicode header */ + smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth); /* server name unicode header */ + + /* put all the data in here, at the moment, including what the above + pointer is referring to + */ + + prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 ); /* 0x0000 0099 or 0x1000 0000 */ + prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 ); /* 0x0000 0000 */ + + prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 ); /* 0x0000 0001 */ + prs_uint32("unknown_7 ", ps, depth, &u_2->unknown_7 ); /* 0x0000 0003 */ + prs_uint32("unknown_8 ", ps, depth, &u_2->unknown_8 ); /* 0x0000 0001 */ + prs_uint32("unknown_9 ", ps, depth, &u_2->unknown_9 ); /* 0x0000 0008 */ + prs_uint32("unknown_10", ps, depth, &u_2->unknown_10); /* 0x0000 0003 */ + + prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding)); /* 16 bytes zeros */ + + smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth); /* domain name unicode string */ + smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth); /* server name unicode string */ + + prs_align(ps); + +} + +/******************************************************************* +makes a SAMR_R_UNKNOWN_8 structure. +********************************************************************/ +void make_samr_r_unknown_8(SAMR_R_UNKNOWN_8 *r_u, + uint16 switch_value, SAM_UNK_CTR *ctr, + uint32 status) +{ + if (r_u == NULL || ctr == NULL) return; + + DEBUG(5,("make_samr_r_unknown_8\n")); + + r_u->ptr_0 = 0; + r_u->switch_value = 0; + r_u->status = status; /* return status */ + + if (status == 0) + { + r_u->switch_value = switch_value; + r_u->ptr_0 = 1; + r_u->ctr = ctr; + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void samr_io_r_unknown_8(char *desc, SAMR_R_UNKNOWN_8 *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_unknown_8"); + depth++; + + prs_align(ps); + + prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0)); + prs_uint16("switch_value", ps, depth, &(r_u->switch_value)); + prs_align(ps); + + if (r_u->ptr_0 != 0 && r_u->ctr != NULL) + { + switch (r_u->switch_value) + { + case 0x02: + { + sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth); + break; + } + default: + { + DEBUG(3,("samr_io_r_unknown_8: unknown switch level 0x%x\n", + r_u->switch_value)); + return; + } + } + } +} + + /******************************************************************* makes a DOM_SID3 structure. @@ -2011,6 +2205,131 @@ static void sam_io_logon_hrs(char *desc, LOGON_HRS *hrs, prs_struct *ps, int de prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len); } +/******************************************************************* +makes a SAM_USER_INFO_10 structure. +********************************************************************/ +void make_sam_user_info10(SAM_USER_INFO_10 *usr, + uint32 acb_info) +{ + if (usr == NULL) return; + + DEBUG(5,("make_sam_user_info10\n")); + + usr->acb_info = acb_info; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth) +{ + if (usr == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_user_info10"); + depth++; + + prs_align(ps); + + prs_uint32("acb_info", ps, depth, &(usr->acb_info)); +} + +/******************************************************************* +makes a SAM_USER_INFO_11 structure. +********************************************************************/ +void make_sam_user_info11(SAM_USER_INFO_11 *usr, + NTTIME *expiry, + char *mach_acct, + uint32 rid_user, + uint32 rid_group, + uint16 acct_ctrl) + +{ + int len_mach_acct; + if (usr == NULL || expiry == NULL || mach_acct == NULL) return; + + DEBUG(5,("make_sam_user_info11\n")); + + len_mach_acct = strlen(mach_acct); + + memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */ + bzero(usr->padding_1, sizeof(usr->padding_1)); /* 0 - padding 24 bytes */ + + make_uni_hdr(&(usr->hdr_mach_acct), len_mach_acct, len_mach_acct, 4); /* unicode header for machine account */ + usr->padding_2 = 0; /* 0 - padding 4 bytes */ + + usr->ptr_1 = 1; /* pointer */ + bzero(usr->padding_3, sizeof(usr->padding_3)); /* 0 - padding 32 bytes */ + usr->padding_4 = 0; /* 0 - padding 4 bytes */ + + usr->ptr_2 = 1; /* pointer */ + usr->padding_5 = 0; /* 0 - padding 4 bytes */ + + usr->ptr_3 = 1; /* pointer */ + bzero(usr->padding_6, sizeof(usr->padding_6)); /* 0 - padding 32 bytes */ + + usr->rid_user = rid_user; + usr->rid_group = rid_group; + + usr->acct_ctrl = acct_ctrl; + usr->unknown_3 = 0x0000; + + usr->unknown_4 = 0x003f; /* 0x003f - 16 bit unknown */ + usr->unknown_5 = 0x003c; /* 0x003c - 16 bit unknown */ + + bzero(usr->padding_7, sizeof(usr->padding_7)); /* 0 - padding 16 bytes */ + usr->padding_8 = 0; /* 0 - padding 4 bytes */ + + make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct); /* unicode string for machine account */ + + bzero(usr->padding_9, sizeof(usr->padding_9)); /* 0 - padding 48 bytes */ +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth) +{ + if (usr == NULL) return; + + prs_debug(ps, depth, desc, "samr_io_r_unknown_24"); + depth++; + + prs_align(ps); + + prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0)); + + smb_io_time("time", &(usr->expiry), ps, depth); + + prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1)); + + smb_io_unihdr ("unihdr", &(usr->hdr_mach_acct), ps, depth); + prs_uint32( "padding_2", ps, depth, &(usr->padding_2)); + + prs_uint32( "ptr_1 ", ps, depth, &(usr->ptr_1 )); + prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3)); + prs_uint32( "padding_4", ps, depth, &(usr->padding_4)); + + prs_uint32( "ptr_2 ", ps, depth, &(usr->ptr_2 )); + prs_uint32( "padding_5", ps, depth, &(usr->padding_5)); + + prs_uint32( "ptr_3 ", ps, depth, &(usr->ptr_3 )); + prs_uint8s (False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6)); + + prs_uint32( "rid_user ", ps, depth, &(usr->rid_user )); + prs_uint32( "rid_group", ps, depth, &(usr->rid_group)); + prs_uint16( "acct_ctrl", ps, depth, &(usr->acct_ctrl)); + prs_uint16( "unknown_3", ps, depth, &(usr->unknown_3)); + prs_uint16( "unknown_4", ps, depth, &(usr->unknown_4)); + prs_uint16( "unknown_5", ps, depth, &(usr->unknown_5)); + + prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7)); + prs_uint32( "padding_8", ps, depth, &(usr->padding_8)); + + smb_io_unistr2("unistr2", &(usr->uni_mach_acct), True, ps, depth); + prs_align(ps); + + prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9)); +} /************************************************************************* make_sam_user_info21 @@ -2262,7 +2581,6 @@ void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struc { switch (r_u->switch_value) { -/* case 0x10: { if (r_u->info.id10 != NULL) @@ -2272,10 +2590,11 @@ void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struc else { DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n")); - return NULL; + return; } break; } +/* case 0x11: { if (r_u->info.id11 != NULL) @@ -2285,7 +2604,7 @@ void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struc else { DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n")); - return NULL; + return; } break; } diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c index f82a1f5afe..06ed6603b3 100644 --- a/source3/rpc_server/srv_samr.c +++ b/source3/rpc_server/srv_samr.c @@ -30,6 +30,8 @@ extern int DEBUGLEVEL; extern BOOL sam_logon_in_ssb; extern pstring samlogon_user; +extern pstring global_myworkgroup; +extern pstring global_myname; extern DOM_SID global_machine_sid; extern rid_name domain_group_rids[]; @@ -216,6 +218,54 @@ static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rda /******************************************************************* + samr_reply_unknown_2c + ********************************************************************/ +static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, + prs_struct *rdata) +{ + SAMR_R_UNKNOWN_2C r_u; + uint32 status = 0x0; + uint32 rid; + + /* find the policy handle. open a policy on it. */ + 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_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff) + { + status = NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + make_samr_r_unknown_2c(&r_u, status); + + DEBUG(5,("samr_unknown_2c: %d\n", __LINE__)); + + /* store the response in the SMB stream */ + samr_io_r_unknown_2c("", &r_u, rdata, 0); + + DEBUG(5,("samr_unknown_2c: %d\n", __LINE__)); + +} + +/******************************************************************* + api_samr_unknown_2c + ********************************************************************/ +static void 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); +} + + +/******************************************************************* samr_reply_unknown_3 ********************************************************************/ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, @@ -242,24 +292,24 @@ static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u, if (status == 0x0) { - DOM_SID user_sid; - DOM_SID other_sid; + DOM_SID user_sid; + DOM_SID everyone_sid; - user_sid = global_machine_sid; + user_sid = global_machine_sid; - SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1); + SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1); - /* - * Add the user RID. - */ - user_sid.sub_auths[user_sid.num_auths++] = rid; - - string_to_sid(&other_sid, "S-1-1"); + /* + * Add the user RID. + */ + user_sid.sub_auths[user_sid.num_auths++] = rid; + + string_to_sid(&everyone_sid, "S-1-1"); - /* maybe need another 1 or 2 (S-1-5-20-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, &other_sid); - make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid); + /* maybe need another 1 or 2 (S-1-5-20-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, &everyone_sid); + make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid); } make_samr_r_unknown_3(&r_u, @@ -946,6 +996,36 @@ static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata /************************************************************************* + get_user_info_10 + *************************************************************************/ +static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid) +{ + 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); + smb_pass = getsmbpwrid(user_rid); + unbecome_root(True); + + if (smb_pass == NULL) + { + DEBUG(4,("User 0x%x not found\n", user_rid)); + return False; + } + + DEBUG(3,("User:[%s]\n", smb_pass->smb_name)); + + make_sam_user_info10(id10, smb_pass->acct_ctrl); + + return True; +} + +/************************************************************************* get_user_info_21 *************************************************************************/ static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid) @@ -1029,6 +1109,7 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u, #if 0 SAM_USER_INFO_11 id11; #endif + SAM_USER_INFO_10 id10; SAM_USER_INFO_21 id21; void *info = NULL; @@ -1056,6 +1137,12 @@ static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u, { switch (q_u->switch_value) { + case 0x10: + { + info = (void*)&id10; + status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER; + break; + } #if 0 /* whoops - got this wrong. i think. or don't understand what's happening. */ case 0x11: @@ -1189,6 +1276,75 @@ static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct /******************************************************************* + samr_reply_unknown_8 + ********************************************************************/ +static void samr_reply_unknown_8(SAMR_Q_UNKNOWN_8 *q_u, + prs_struct *rdata) +{ + SAMR_R_UNKNOWN_8 r_u; + SAM_UNK_CTR ctr; + uint16 switch_value = 0x0; + uint32 status = 0x0; + + ZERO_STRUCT(r_u); + ZERO_STRUCT(ctr); + + r_u.ctr = &ctr; + + DEBUG(5,("samr_reply_unknown_8: %d\n", __LINE__)); + + /* find the policy handle. open a policy on it. */ + 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_unknown_8: invalid handle\n")); + } + + if (status == 0x0) + { + switch (q_u->switch_value) + { + case 0x02: + { + switch_value = 0x2; + make_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname); + + break; + } + default: + { + status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS; + break; + } + } + } + + make_samr_r_unknown_8(&r_u, switch_value, &ctr, status); + + /* store the response in the SMB stream */ + samr_io_r_unknown_8("", &r_u, rdata, 0); + + DEBUG(5,("samr_unknown_8: %d\n", __LINE__)); + +} + +/******************************************************************* + api_samr_unknown_8 + ********************************************************************/ +static void api_samr_unknown_8( uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SAMR_Q_UNKNOWN_8 q_e; + + /* grab the samr unknown 8 command */ + samr_io_q_unknown_8("", &q_e, data, 0); + + /* construct reply. */ + samr_reply_unknown_8(&q_e, rdata); +} + + + +/******************************************************************* samr_reply_unknown_32 ********************************************************************/ static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u, @@ -1439,6 +1595,7 @@ static struct api_struct api_samr_cmds [] = { "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_UNKNOWN_8" , SAMR_UNKNOWN_8 , api_samr_unknown_8 }, { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups }, { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo }, { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo }, @@ -1449,6 +1606,7 @@ static struct api_struct api_samr_cmds [] = { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias }, { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain }, { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 }, + { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c }, { NULL , 0 , NULL } }; diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c index 3269ab4e61..4756d2f338 100644 --- a/source3/rpc_server/srv_util.c +++ b/source3/rpc_server/srv_util.c @@ -224,7 +224,7 @@ BOOL create_rpc_reply(pipes_struct *p, } else { - data_len = p->hdr.frag_len; + data_len = p->hdr.frag_len - 0x18; } p->rhdr.data->offset.start = 0; |