diff options
Diffstat (limited to 'source4/librpc')
-rw-r--r-- | source4/librpc/idl/samr.idl | 32 | ||||
-rw-r--r-- | source4/librpc/ndr/libndr.h | 4 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_basic.c | 18 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_samr.c | 141 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_samr.h | 32 |
5 files changed, 226 insertions, 1 deletions
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl index c703f99817..eed1f342a6 100644 --- a/source4/librpc/idl/samr.idl +++ b/source4/librpc/idl/samr.idl @@ -326,8 +326,40 @@ samr_Name comment; } samr_UserInfo1; + typedef struct { + samr_Name comment; + uint32 foo1; + uint32 foo2; + uint16 country_code; + uint16 code_page; + } samr_UserInfo2; + + typedef struct { + samr_Name username; + samr_Name full_name; + uint32 Rid; + uint32 primary_group_rid; + samr_Name home_directory; + samr_Name home_drive; + samr_Name logon_script; + samr_Name profile; + samr_Name workstations; + NTTIME last_logon; + NTTIME last_logoff; + NTTIME last_pwd_change; + NTTIME allow_pwd_change; + NTTIME force_pwd_change; /* uncertain about this one */ + uint32 units_per_week; + [size_is(1260), length_is(units_per_week/8)] uint8 *logon_hours; + uint16 bad_pwd_count; + uint16 num_logons; + uint32 acct_flags; + } samr_UserInfo3; + typedef union { case(1) samr_UserInfo1 info1; + case(2) samr_UserInfo2 info2; + case(3) samr_UserInfo3 info3; } samr_UserInfo; NTSTATUS samr_QueryUserInfo( diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 25ed1fc6f1..8347aa8f28 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -79,7 +79,9 @@ struct ndr_print { enum ndr_err_code { NDR_ERR_CONFORMANT_SIZE, NDR_ERR_ARRAY_SIZE, - NDR_ERR_BAD_SWITCH + NDR_ERR_BAD_SWITCH, + NDR_ERR_OFFSET, + NDR_ERR_LENGTH }; /* diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c index 89c16ca76a..6239e56b3f 100644 --- a/source4/librpc/ndr/ndr_basic.c +++ b/source4/librpc/ndr/ndr_basic.c @@ -483,6 +483,24 @@ void ndr_print_array_uint32(struct ndr_print *ndr, const char *name, ndr->depth--; } +void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, + uint8 *data, uint32 count) +{ + int i; + + ndr->print(ndr, "%s: ARRAY(%d)", name, count); + ndr->depth++; + for (i=0;i<count;i++) { + char *idx=NULL; + asprintf(&idx, "[%d]", i); + if (idx) { + ndr_print_uint8(ndr, idx, data[i]); + free(idx); + } + } + ndr->depth--; +} + void ndr_print_GUID(struct ndr_print *ndr, const char *name, struct GUID *guid) { ndr->print(ndr, "%-25s: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", diff --git a/source4/librpc/ndr/ndr_samr.c b/source4/librpc/ndr/ndr_samr.c index 95c38e70c1..e592a65de1 100644 --- a/source4/librpc/ndr/ndr_samr.c +++ b/source4/librpc/ndr/ndr_samr.c @@ -1159,6 +1159,80 @@ done: return NT_STATUS_OK; } +static NTSTATUS ndr_pull_samr_UserInfo2(struct ndr_pull *ndr, int ndr_flags, struct samr_UserInfo2 *r) +{ + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->comment)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->foo1)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->foo2)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->country_code)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->code_page)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->comment)); +done: + return NT_STATUS_OK; +} + +static NTSTATUS ndr_pull_samr_UserInfo3(struct ndr_pull *ndr, int ndr_flags, struct samr_UserInfo3 *r) +{ + uint32 _ptr_logon_hours; + if (!(ndr_flags & NDR_SCALARS)) goto buffers; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->username)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->full_name)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->Rid)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->primary_group_rid)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->home_directory)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->home_drive)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->logon_script)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->profile)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_SCALARS, &r->workstations)); + NDR_CHECK(ndr_pull_NTTIME(ndr, &r->last_logon)); + NDR_CHECK(ndr_pull_NTTIME(ndr, &r->last_logoff)); + NDR_CHECK(ndr_pull_NTTIME(ndr, &r->last_pwd_change)); + NDR_CHECK(ndr_pull_NTTIME(ndr, &r->allow_pwd_change)); + NDR_CHECK(ndr_pull_NTTIME(ndr, &r->max_storage)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->units_per_week)); + NDR_CHECK(ndr_pull_uint32(ndr, &_ptr_logon_hours)); + if (_ptr_logon_hours) { + NDR_ALLOC(ndr, r->logon_hours); + } else { + r->logon_hours = NULL; + } + NDR_CHECK(ndr_pull_uint16(ndr, &r->bad_pwd_count)); + NDR_CHECK(ndr_pull_uint16(ndr, &r->num_logons)); + NDR_CHECK(ndr_pull_uint32(ndr, &r->acct_flags)); +buffers: + if (!(ndr_flags & NDR_BUFFERS)) goto done; + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->username)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->full_name)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->home_directory)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->home_drive)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->logon_script)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->profile)); + NDR_CHECK(ndr_pull_samr_Name(ndr, NDR_BUFFERS, &r->workstations)); + if (r->logon_hours) { + { + uint32 _array_size; + NDR_CHECK(ndr_pull_uint32(ndr, &_array_size)); + if (1260 > _array_size) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should be %u", _array_size, 1260); + } + } + NDR_ALLOC_N_SIZE(ndr, r->logon_hours, 1260, sizeof(r->logon_hours[0])); + uint32 _offset, _length; + NDR_CHECK(ndr_pull_uint32(ndr, &_offset)); + NDR_CHECK(ndr_pull_uint32(ndr, &_length)); + if (_offset != 0) return ndr_pull_error(ndr, NDR_ERR_OFFSET, "Bad array offset 0x%08x", _offset); + if (_length > 1260 || _length != r->units_per_week/8) return ndr_pull_error(ndr, NDR_ERR_LENGTH, "Bad array length 0x%08x > size 0x%08x", _offset, 1260); + NDR_CHECK(ndr_pull_array_uint8(ndr, r->logon_hours, _length)); + } +done: + return NT_STATUS_OK; +} + static NTSTATUS ndr_pull_samr_UserInfo(struct ndr_pull *ndr, int ndr_flags, uint16 *level, union samr_UserInfo *r) { if (!(ndr_flags & NDR_SCALARS)) goto buffers; @@ -1168,6 +1242,14 @@ static NTSTATUS ndr_pull_samr_UserInfo(struct ndr_pull *ndr, int ndr_flags, uint NDR_CHECK(ndr_pull_samr_UserInfo1(ndr, NDR_SCALARS, &r->info1)); break; } + case 2: { + NDR_CHECK(ndr_pull_samr_UserInfo2(ndr, NDR_SCALARS, &r->info2)); + break; } + + case 3: { + NDR_CHECK(ndr_pull_samr_UserInfo3(ndr, NDR_SCALARS, &r->info3)); + break; } + default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", *level); } @@ -1178,6 +1260,14 @@ buffers: NDR_CHECK(ndr_pull_samr_UserInfo1(ndr, NDR_BUFFERS, &r->info1)); break; + case 2: + NDR_CHECK(ndr_pull_samr_UserInfo2(ndr, NDR_BUFFERS, &r->info2)); + break; + + case 3: + NDR_CHECK(ndr_pull_samr_UserInfo3(ndr, NDR_BUFFERS, &r->info3)); + break; + default: return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", *level); } @@ -1659,6 +1749,49 @@ void ndr_print_samr_UserInfo1(struct ndr_print *ndr, const char *name, struct sa ndr->depth--; } +void ndr_print_samr_UserInfo2(struct ndr_print *ndr, const char *name, struct samr_UserInfo2 *r) +{ + ndr_print_struct(ndr, name, "samr_UserInfo2"); + ndr->depth++; + ndr_print_samr_Name(ndr, "comment", &r->comment); + ndr_print_uint32(ndr, "foo1", r->foo1); + ndr_print_uint32(ndr, "foo2", r->foo2); + ndr_print_uint16(ndr, "country_code", r->country_code); + ndr_print_uint16(ndr, "code_page", r->code_page); + ndr->depth--; +} + +void ndr_print_samr_UserInfo3(struct ndr_print *ndr, const char *name, struct samr_UserInfo3 *r) +{ + ndr_print_struct(ndr, name, "samr_UserInfo3"); + ndr->depth++; + ndr_print_samr_Name(ndr, "username", &r->username); + ndr_print_samr_Name(ndr, "full_name", &r->full_name); + ndr_print_uint32(ndr, "Rid", r->Rid); + ndr_print_uint32(ndr, "primary_group_rid", r->primary_group_rid); + ndr_print_samr_Name(ndr, "home_directory", &r->home_directory); + ndr_print_samr_Name(ndr, "home_drive", &r->home_drive); + ndr_print_samr_Name(ndr, "logon_script", &r->logon_script); + ndr_print_samr_Name(ndr, "profile", &r->profile); + ndr_print_samr_Name(ndr, "workstations", &r->workstations); + ndr_print_NTTIME(ndr, "last_logon", r->last_logon); + ndr_print_NTTIME(ndr, "last_logoff", r->last_logoff); + ndr_print_NTTIME(ndr, "last_pwd_change", r->last_pwd_change); + ndr_print_NTTIME(ndr, "allow_pwd_change", r->allow_pwd_change); + ndr_print_NTTIME(ndr, "max_storage", r->max_storage); + ndr_print_uint32(ndr, "units_per_week", r->units_per_week); + ndr_print_ptr(ndr, "logon_hours", r->logon_hours); + ndr->depth++; + if (r->logon_hours) { + ndr_print_array_uint8(ndr, "logon_hours", r->logon_hours, r->units_per_week/8); + } + ndr->depth--; + ndr_print_uint16(ndr, "bad_pwd_count", r->bad_pwd_count); + ndr_print_uint16(ndr, "num_logons", r->num_logons); + ndr_print_uint32(ndr, "acct_flags", r->acct_flags); + ndr->depth--; +} + void ndr_print_samr_UserInfo(struct ndr_print *ndr, const char *name, uint16 level, union samr_UserInfo *r) { ndr_print_union(ndr, name, level, "samr_UserInfo"); @@ -1667,6 +1800,14 @@ void ndr_print_samr_UserInfo(struct ndr_print *ndr, const char *name, uint16 lev ndr_print_samr_UserInfo1(ndr, "info1", &r->info1); break; + case 2: + ndr_print_samr_UserInfo2(ndr, "info2", &r->info2); + break; + + case 3: + ndr_print_samr_UserInfo3(ndr, "info3", &r->info3); + break; + default: ndr_print_bad_level(ndr, name, level); } diff --git a/source4/librpc/ndr/ndr_samr.h b/source4/librpc/ndr/ndr_samr.h index 79dcc861e1..49103078fe 100644 --- a/source4/librpc/ndr/ndr_samr.h +++ b/source4/librpc/ndr/ndr_samr.h @@ -522,8 +522,40 @@ struct samr_UserInfo1 { struct samr_Name comment; }; +struct samr_UserInfo2 { + struct samr_Name comment; + uint32 foo1; + uint32 foo2; + uint16 country_code; + uint16 code_page; +}; + +struct samr_UserInfo3 { + struct samr_Name username; + struct samr_Name full_name; + uint32 Rid; + uint32 primary_group_rid; + struct samr_Name home_directory; + struct samr_Name home_drive; + struct samr_Name logon_script; + struct samr_Name profile; + struct samr_Name workstations; + NTTIME last_logon; + NTTIME last_logoff; + NTTIME last_pwd_change; + NTTIME allow_pwd_change; + NTTIME max_storage; + uint32 units_per_week; + uint8 *logon_hours; + uint16 bad_pwd_count; + uint16 num_logons; + uint32 acct_flags; +}; + union samr_UserInfo { /* [case(1)] */ struct samr_UserInfo1 info1; +/* [case(2)] */ struct samr_UserInfo2 info2; +/* [case(3)] */ struct samr_UserInfo3 info3; }; struct samr_QueryUserInfo { |