diff options
author | cvs2svn Import User <samba-bugs@samba.org> | 2003-04-13 13:50:46 +0000 |
---|---|---|
committer | cvs2svn Import User <samba-bugs@samba.org> | 2003-04-13 13:50:46 +0000 |
commit | a47d06a2c2c67cdc0b1dfc2d32df65f2b1bbeeda (patch) | |
tree | 94fc3e2c3166e1fa14849e50468b7b529f9e3385 /source3 | |
parent | 74b163a83a7c516abe8192e3965832efa2fa64a4 (diff) | |
parent | e2996e29c7fb4697b9d95fe17d316bd2dded9d17 (diff) | |
download | samba-a47d06a2c2c67cdc0b1dfc2d32df65f2b1bbeeda.tar.gz samba-a47d06a2c2c67cdc0b1dfc2d32df65f2b1bbeeda.tar.xz samba-a47d06a2c2c67cdc0b1dfc2d32df65f2b1bbeeda.zip |
This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to be commit 381649916ecbaddefbb6ee0e6137b7cc73eb54b1)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/groupdb/.cvsignore | 2 | ||||
-rw-r--r-- | source3/include/authdata.h | 152 | ||||
-rw-r--r-- | source3/include/fake_file.h | 46 | ||||
-rw-r--r-- | source3/include/ntquotas.h | 97 | ||||
-rw-r--r-- | source3/include/rpc_echo.h | 74 | ||||
-rw-r--r-- | source3/libads/authdata.c | 614 | ||||
-rw-r--r-- | source3/libsmb/clifsinfo.c | 76 | ||||
-rw-r--r-- | source3/rpc_client/cli_echo.c | 187 | ||||
-rw-r--r-- | source3/rpc_parse/parse_echo.c | 166 | ||||
-rw-r--r-- | source3/rpc_server/srv_echo.c | 137 | ||||
-rw-r--r-- | source3/rpc_server/srv_echo_nt.c | 78 | ||||
-rw-r--r-- | source3/rpcclient/cmd_echo.c | 157 | ||||
-rwxr-xr-x | source3/stf/smbcontrol.py | 238 | ||||
-rw-r--r-- | source3/stf/unicodenames.py | 33 | ||||
-rw-r--r-- | source3/torture/t_push_ucs2.c | 54 | ||||
-rw-r--r-- | source3/torture/t_strcmp.c | 32 | ||||
-rw-r--r-- | source3/utils/smbcquotas.c | 545 |
17 files changed, 2688 insertions, 0 deletions
diff --git a/source3/groupdb/.cvsignore b/source3/groupdb/.cvsignore new file mode 100644 index 0000000000..22beab949c --- /dev/null +++ b/source3/groupdb/.cvsignore @@ -0,0 +1,2 @@ +.po +.po32 diff --git a/source3/include/authdata.h b/source3/include/authdata.h new file mode 100644 index 0000000000..0798b72bdf --- /dev/null +++ b/source3/include/authdata.h @@ -0,0 +1,152 @@ +/* + Unix SMB/CIFS implementation. + Kerberos authorization data + Copyright (C) Jim McDonough 2003 + + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _AUTHDATA_H +#define _AUTHDATA_H + +#include "rpc_misc.h" + +#define PAC_TYPE_LOGON_INFO 1 +#define PAC_TYPE_SERVER_CHECKSUM 6 +#define PAC_TYPE_PRIVSVR_CHECKSUM 7 +#define PAC_TYPE_UNKNOWN_10 10 + +typedef struct unknown_type_10 { + NTTIME unknown_time; + uint16 len; + uint16 *username; /* might not be null terminated, so not UNISTR */ +} UNKNOWN_TYPE_10; + +typedef struct pac_signature_data { + uint32 type; + uint8 *signature; +} PAC_SIGNATURE_DATA; + +typedef struct group_membership { + uint32 rid; + uint32 attrs; +} GROUP_MEMBERSHIP; + +typedef struct group_membership_array { + uint32 count; + GROUP_MEMBERSHIP *group_membership; +} GROUP_MEMBERSHIP_ARRAY; + +typedef struct krb_sid_and_attrs { + uint32 sid_ptr; + uint32 attrs; + DOM_SID2 *sid; +} KRB_SID_AND_ATTRS; + +typedef struct krb_sid_and_attr_array { + uint32 count; + KRB_SID_AND_ATTRS *krb_sid_and_attrs; +} KRB_SID_AND_ATTR_ARRAY; + + +/* This is awfully similar to a samr_user_info_23, but not identical. + Many of the field names have been swiped from there, because it is + so similar that they are likely the same, but many have been verified. + Some are in a different order, though... */ +typedef struct pac_logon_info { + NTTIME logon_time; /* logon time */ + NTTIME logoff_time; /* logoff time */ + NTTIME kickoff_time; /* kickoff time */ + NTTIME pass_last_set_time; /* password last set time */ + NTTIME pass_can_change_time; /* password can change time */ + NTTIME pass_must_change_time; /* password must change time */ + + UNIHDR hdr_user_name; /* user name unicode string header */ + UNIHDR hdr_full_name; /* user's full name unicode string header */ + UNIHDR hdr_logon_script; /* these last 4 appear to be in a different */ + UNIHDR hdr_profile_path; /* order than in the info23 */ + UNIHDR hdr_home_dir; + UNIHDR hdr_dir_drive; + + uint16 logon_count; /* number of times user has logged onto domain */ + uint16 reserved12; + + uint32 user_rid; + uint32 group_rid; + uint32 group_count; + uint32 group_membership_ptr; + uint32 user_flags; + + uint32 reserved13[4]; + UNIHDR hdr_dom_controller; + UNIHDR hdr_dom_name; + + uint32 ptr_dom_sid; + + uint32 reserved16[2]; + uint32 reserved17; /* looks like it may be acb_info */ + uint32 reserved18[7]; + + uint32 sid_count; + uint32 ptr_extra_sids; + + uint32 ptr_res_group_dom_sid; + uint32 res_group_count; + uint32 ptr_res_groups; + + UNISTR2 uni_user_name; /* user name unicode string header */ + UNISTR2 uni_full_name; /* user's full name unicode string header */ + UNISTR2 uni_logon_script; /* these last 4 appear to be in a different*/ + UNISTR2 uni_profile_path; /* order than in the info23 */ + UNISTR2 uni_home_dir; + UNISTR2 uni_dir_drive; + UNISTR2 uni_dom_controller; + UNISTR2 uni_dom_name; + DOM_SID2 dom_sid; + GROUP_MEMBERSHIP_ARRAY groups; + KRB_SID_AND_ATTR_ARRAY extra_sids; + DOM_SID2 res_group_dom_sid; + GROUP_MEMBERSHIP_ARRAY res_groups; + +} PAC_LOGON_INFO; + +typedef struct pac_info_ctr +{ + union + { + PAC_LOGON_INFO *logon_info; + PAC_SIGNATURE_DATA *srv_cksum; + PAC_SIGNATURE_DATA *privsrv_cksum; + UNKNOWN_TYPE_10 *type_10; + } pac; +} PAC_INFO_CTR; + +typedef struct pac_info_hdr { + uint32 type; + uint32 size; + uint32 offset; + uint32 offsethi; + PAC_INFO_CTR *ctr; +} PAC_INFO_HDR; + +typedef struct pac_data { + uint32 num_buffers; + uint32 version; + PAC_INFO_HDR *pac_info_hdr_ptr; +} PAC_DATA; + + +#endif diff --git a/source3/include/fake_file.h b/source3/include/fake_file.h new file mode 100644 index 0000000000..3fe60072e9 --- /dev/null +++ b/source3/include/fake_file.h @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + FAKE FILE suppport, for faking up special files windows want access to + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _FAKE_FILE_H +#define _FAKE_FILE_H + +enum FAKE_FILE_TYPE { + FAKE_FILE_TYPE_NONE = 0, + FAKE_FILE_TYPE_QUOTA +}; + +#define FAKE_FILE_NAME_QUOTA "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION" + +typedef struct _FAKE_FILE_HANDLE { + enum FAKE_FILE_TYPE type; + TALLOC_CTX *mem_ctx; + void *pd; /* for private data */ + void (*free_pd)(void **pd); /* free private_data */ +} FAKE_FILE_HANDLE; + +typedef struct _FAKE_FILE { + const char *name; + enum FAKE_FILE_TYPE type; + void *(*init_pd)(TALLOC_CTX *men_ctx); + void (*free_pd)(void **pd); +} FAKE_FILE; + + +#endif /* _FAKE_FILE_H */ diff --git a/source3/include/ntquotas.h b/source3/include/ntquotas.h new file mode 100644 index 0000000000..1425e59bb8 --- /dev/null +++ b/source3/include/ntquotas.h @@ -0,0 +1,97 @@ +/* + Unix SMB/CIFS implementation. + NT QUOTA code constants + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _NTQUOTAS_H +#define _NTQUOTAS_H + +/* + * details for Quota Flags: + * + * 0x20 Log Limit: log if the user exceeds his Hard Quota + * 0x10 Log Warn: log if the user exceeds his Soft Quota + * 0x02 Deny Disk: deny disk access when the user exceeds his Hard Quota + * 0x01 Enable Quotas: enable quota for this fs + * + */ + +#define QUOTAS_ENABLED 0x0001 +#define QUOTAS_DENY_DISK 0x0002 +#define QUOTAS_LOG_VIOLATIONS 0x0004 +#define CONTENT_INDEX_DISABLED 0x0008 +#define QUOTAS_LOG_THRESHOLD 0x0010 +#define QUOTAS_LOG_LIMIT 0x0020 +#define LOG_VOLUME_THRESHOLD 0x0040 +#define LOG_VOLUME_LIMIT 0x0080 +#define QUOTAS_INCOMPLETE 0x0100 +#define QUOTAS_REBUILDING 0x0200 +#define QUOTAS_0400 0x0400 +#define QUOTAS_0800 0x0800 +#define QUOTAS_1000 0x1000 +#define QUOTAS_2000 0x2000 +#define QUOTAS_4000 0x4000 +#define QUOTAS_8000 0x8000 + +#define SMB_NTQUOTAS_NO_LIMIT ((SMB_BIG_UINT)(-1)) +#define SMB_NTQUOTAS_NO_ENTRY ((SMB_BIG_UINT)(-2)) +#define SMB_NTQUOTAS_NO_SPACE ((SMB_BIG_UINT)(0)) +#define SMB_NTQUOTAS_1_B (SMB_BIG_UINT)0x0000000000000001 +#define SMB_NTQUOTAS_1KB (SMB_BIG_UINT)0x0000000000000400 +#define SMB_NTQUOTAS_1MB (SMB_BIG_UINT)0x0000000000100000 +#define SMB_NTQUOTAS_1GB (SMB_BIG_UINT)0x0000000040000000 +#define SMB_NTQUOTAS_1TB (SMB_BIG_UINT)0x0000010000000000 +#define SMB_NTQUOTAS_1PB (SMB_BIG_UINT)0x0004000000000000 +#define SMB_NTQUOTAS_1EB (SMB_BIG_UINT)0x1000000000000000 + +enum SMB_QUOTA_TYPE { + SMB_INVALID_QUOTA_TYPE = -1, + SMB_USER_FS_QUOTA_TYPE = 1, + SMB_USER_QUOTA_TYPE = 2, + SMB_GROUP_FS_QUOTA_TYPE = 3,/* not used yet */ + SMB_GROUP_QUOTA_TYPE = 4 /* not in use yet, maybe for disk_free queries */ +}; + +typedef struct _SMB_NTQUOTA_STRUCT { + enum SMB_QUOTA_TYPE qtype; + SMB_BIG_UINT usedspace; + SMB_BIG_UINT softlim; + SMB_BIG_UINT hardlim; + enum SMB_QUOTA_TYPE qflags; + DOM_SID sid; +} SMB_NTQUOTA_STRUCT; + +typedef struct _SMB_NTQUOTA_LIST { + struct _SMB_NTQUOTA_LIST *prev,*next; + TALLOC_CTX *mem_ctx; + uid_t uid; + SMB_NTQUOTA_STRUCT *quotas; +} SMB_NTQUOTA_LIST; + +typedef struct _SMB_NTQUOTA_HANDLE { + BOOL valid; + SMB_NTQUOTA_LIST *quota_list; + SMB_NTQUOTA_LIST *tmp_list; +} SMB_NTQUOTA_HANDLE; + +#define CHECK_NTQUOTA_HANDLE_OK(fsp,conn) (FNUM_OK(fsp,conn) &&\ + (fsp)->fake_file_handle &&\ + ((fsp)->fake_file_handle->type == FAKE_FILE_TYPE_QUOTA) &&\ + (fsp)->fake_file_handle->pd) + +#endif /*_NTQUOTAS_H */ diff --git a/source3/include/rpc_echo.h b/source3/include/rpc_echo.h new file mode 100644 index 0000000000..8fa389cf56 --- /dev/null +++ b/source3/include/rpc_echo.h @@ -0,0 +1,74 @@ +/* + Unix SMB/CIFS implementation. + + Samba rpcecho definitions. + + Copyright (C) Tim Potter 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _RPC_ECHO_H +#define _RPC_ECHO_H + +#define ECHO_ADD_ONE 0x00 +#define ECHO_DATA 0x01 +#define ECHO_SINK_DATA 0x02 +#define ECHO_SOURCE_DATA 0x03 + +typedef struct echo_q_add_one +{ + uint32 request; +} ECHO_Q_ADD_ONE; + +typedef struct echo_r_add_one +{ + uint32 response; +} ECHO_R_ADD_ONE; + +typedef struct echo_q_echo_data +{ + uint32 size; + char *data; +} ECHO_Q_ECHO_DATA; + +typedef struct echo_r_echo_data +{ + uint32 size; + char *data; +} ECHO_R_ECHO_DATA; + +typedef struct echo_q_source_data +{ + uint32 size; +} ECHO_Q_SOURCE_DATA; + +typedef struct echo_r_source_data +{ + uint32 size; + char *data; +} ECHO_R_SOURCE_DATA; + +typedef struct echo_q_sink_data +{ + uint32 size; + char *data; +} ECHO_Q_SINK_DATA; + +typedef struct echo_r_sink_data +{ +} ECHO_R_SINK_DATA; + +#endif diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c new file mode 100644 index 0000000000..c554a02e90 --- /dev/null +++ b/source3/libads/authdata.c @@ -0,0 +1,614 @@ +/* + Unix SMB/CIFS implementation. + kerberos authorization data (PAC) utility library + Copyright (C) Jim McDonough 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#ifdef HAVE_KRB5 + +static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data) +{ + DATA_BLOB pac_contents; + ASN1_DATA data; + int data_type; + + asn1_load(&data, *auth_data); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_Integer(&data, &data_type); + asn1_end_tag(&data); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_OctetString(&data, &pac_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + return pac_contents; +} + +static BOOL pac_io_unknown_type_10(const char *desc, UNKNOWN_TYPE_10 *type_10, + prs_struct *ps, int depth) +{ + if (NULL == type_10) + return False; + + prs_debug(ps, depth, desc, "pac_io_unknown_type_10"); + depth++; + + if (!smb_io_time("unknown_time", &type_10->unknown_time, ps, depth)) + return False; + + if (!prs_uint16("len", ps, depth, &type_10->len)) + return False; + + if (UNMARSHALLING(ps) && type_10->len) { + type_10->username = (uint16 *) prs_alloc_mem(ps, type_10->len); + if (!type_10->username) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if (!prs_uint16s(True, "name", ps, depth, type_10->username, + (type_10->len / sizeof(uint16)))) + return False; + + return True; + +} + + +static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sids"); + depth++; + + if (UNMARSHALLING(ps)) { + sid_and_attr->sid = + (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2)); + if (!sid_and_attr->sid) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) + return False; + + return True; +} + + +static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, + prs_struct *ps, int depth) +{ + if (NULL == sid_and_attr) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_attrs"); + depth++; + + if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) + return False; + if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) + return False; + + return True; +} + +static BOOL pac_io_krb_sid_and_attr_array(const char *desc, + KRB_SID_AND_ATTR_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *) + prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num); + if (!array->krb_sid_and_attrs) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; i<num; i++) { + if (!pac_io_krb_attrs(desc, + &array->krb_sid_and_attrs[i], + ps, depth)) + return False; + + } + for (i=0; i<num; i++) { + if (!pac_io_krb_sids(desc, + &array->krb_sid_and_attrs[i], + ps, depth)) + return False; + + } + + return True; + +} + +static BOOL pac_io_group_membership(const char *desc, + GROUP_MEMBERSHIP *membership, + prs_struct *ps, int depth) +{ + if (NULL == membership) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership"); + depth++; + + if (!prs_uint32("rid", ps, depth, &membership->rid)) + return False; + if (!prs_uint32("attrs", ps, depth, &membership->attrs)) + return False; + + return True; +} + + +static BOOL pac_io_group_membership_array(const char *desc, + GROUP_MEMBERSHIP_ARRAY *array, + uint32 num, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == array) + return False; + + prs_debug(ps, depth, desc, "pac_io_group_membership_array"); + depth++; + + + if (!prs_uint32("count", ps, depth, &array->count)) + return False; + + if (UNMARSHALLING(ps)) { + array->group_membership = (GROUP_MEMBERSHIP *) + prs_alloc_mem(ps, sizeof(GROUP_MEMBERSHIP) * num); + if (!array->group_membership) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + for (i=0; i<num; i++) { + if (!pac_io_group_membership(desc, + &array->group_membership[i], + ps, depth)) + return False; + + } + + return True; + +} + +static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, + prs_struct *ps, int depth) +{ + uint32 garbage; + if (NULL == info) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); + depth++; + + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("unknown", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlen", ps, depth, &garbage)) + return False; + if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) + return False; + if (!prs_uint32("pointer", ps, depth, &garbage)) + return False; + + if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) + return False; + if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) + return False; + if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) + return False; + if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, + ps, depth)) + return False; + if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, + ps, depth)) + return False; + if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, + ps, depth)) + return False; + + if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, + ps, depth)) + return False; + if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) + return False; + + if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) + return False; + if (!prs_uint16("reserved12", ps, depth, &info->reserved12)) + return False; + if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) + return False; + if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) + return False; + if (!prs_uint32("group_count", ps, depth, &info->group_count)) + return False; + /* I haven't seen this contain anything yet, but when it does + we will have to make sure we decode the contents in the middle + all the unistr2s ... */ + if (!prs_uint32("group_mem_ptr", ps, depth, + &info->group_membership_ptr)) + return False; + if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) + return False; + + if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0])) + return False; + if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1])) + return False; + if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2])) + return False; + if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3])) + return False; + + if (!smb_io_unihdr("hdr_dom_controller", + &info->hdr_dom_controller, ps, depth)) + return False; + if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) + return False; + + /* this should be followed, but just get ptr for now */ + if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) + return False; + + if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0])) + return False; + if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1])) + return False; + + /* might be acb_info */ + if (!prs_uint32("reserved17", ps, depth, &info->reserved17)) + return False; + + + if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0])) + return False; + if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1])) + return False; + if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2])) + return False; + if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3])) + return False; + if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4])) + return False; + if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5])) + return False; + if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6])) + return False; + + if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) + return False; + if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) + return False; + if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, + &info->ptr_res_group_dom_sid)) + return False; + if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) + return False; + if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) + return False; + + if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, + info->hdr_user_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, + info->hdr_full_name.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, + info->hdr_logon_script.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, + info->hdr_profile_path.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, + info->hdr_home_dir.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, + info->hdr_dir_drive.buffer, ps, depth)) + return False; + + if (info->group_membership_ptr) { + if (!pac_io_group_membership_array("group membership", + &info->groups, + info->group_count, + ps, depth)) + return False; + } + + + if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, + info->hdr_dom_controller.buffer, ps, depth)) + return False; + if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, + info->hdr_dom_name.buffer, ps, depth)) + return False; + + if(info->ptr_dom_sid) + if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) + return False; + + + if (info->sid_count && info->ptr_extra_sids) + if (!pac_io_krb_sid_and_attr_array("extra_sids", + &info->extra_sids, + info->sid_count, + ps, depth)) + return False; + + if (info->ptr_res_group_dom_sid) + if (!smb_io_dom_sid2("res_group_dom_sid", + &info->res_group_dom_sid, ps, depth)) + return False; + + if (info->ptr_res_groups) + if (!pac_io_group_membership_array("res group membership", + &info->res_groups, + info->res_group_count, + ps, depth)) + return False; + + return True; +} + + +static BOOL pac_io_pac_signature_data(const char *desc, + PAC_SIGNATURE_DATA *data, uint32 length, + prs_struct *ps, int depth) +{ + uint32 siglen = length - sizeof(uint32); + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); + depth++; + + if (!prs_uint32("type", ps, depth, &data->type)) + return False; + if (UNMARSHALLING(ps)) { + data->signature = prs_alloc_mem(ps, siglen); + if (!data->signature) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen)) + return False; + + return True; +} + +static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); + depth++; + + if (!prs_align(ps)) + return False; + + if (hdr->offset != prs_offset(ps)) { + DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n", + hdr->offset, prs_offset(ps))); + prs_set_offset(ps, hdr->offset); + } + + if (UNMARSHALLING(ps) && hdr->size > 0) { + hdr->ctr = (PAC_INFO_CTR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_CTR)); + if (!hdr->ctr) { + DEBUG(3, ("No memory available\n")); + return False; + } + } + + switch(hdr->type) { + case PAC_TYPE_LOGON_INFO: + DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *) + prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO)); + if (!hdr->ctr->pac.logon_info) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, + ps, depth)) + return False; + break; + + case PAC_TYPE_SERVER_CHECKSUM: + DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.srv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, + hdr->size, ps, depth)) + return False; + break; + + case PAC_TYPE_PRIVSVR_CHECKSUM: + DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *) + prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA)); + if (!hdr->ctr->pac.privsrv_cksum) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_pac_signature_data(desc, + hdr->ctr->pac.privsrv_cksum, + hdr->size, ps, depth)) + return False; + break; + + case PAC_TYPE_UNKNOWN_10: + DEBUG(5, ("PAC_TYPE_UNKNOWN_10\n")); + if (UNMARSHALLING(ps)) + hdr->ctr->pac.type_10 = (UNKNOWN_TYPE_10 *) + prs_alloc_mem(ps, sizeof(UNKNOWN_TYPE_10)); + if (!hdr->ctr->pac.type_10) { + DEBUG(3, ("No memory available\n")); + return False; + } + if (!pac_io_unknown_type_10(desc, hdr->ctr->pac.type_10, + ps, depth)) + return False; + break; + + default: + /* dont' know, so we need to skip it */ + DEBUG(3, ("unknown PAC type %d\n", hdr->type)); + prs_set_offset(ps, prs_offset(ps) + hdr->size); + } + + return True; +} + +static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr, + prs_struct *ps, int depth) +{ + if (NULL == hdr) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("type", ps, depth, &hdr->type)) + return False; + if (!prs_uint32("size", ps, depth, &hdr->size)) + return False; + if (!prs_uint32("offset", ps, depth, &hdr->offset)) + return False; + if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) + return False; + + return True; +} + +static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data, + prs_struct *ps, int depth) +{ + int i; + + if (NULL == data) + return False; + + prs_debug(ps, depth, desc, "pac_io_pac_data"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) + return False; + if (!prs_uint32("version", ps, depth, &data->version)) + return False; + + if (UNMARSHALLING(ps) && data->num_buffers > 0) { + if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *) + prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) * + data->num_buffers)) == NULL) { + return False; + } + } + + for (i=0; i<data->num_buffers; i++) { + if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps, + depth)) + return False; + } + + for (i=0; i<data->num_buffers; i++) { + if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i], + ps, depth)) + return False; + } + + return True; +} + +PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx) +{ + DATA_BLOB pac_data_blob = unwrap_pac(auth_data); + prs_struct ps; + PAC_DATA *pac_data; + + DEBUG(5,("dump_pac_data\n")); + prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL); + prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length); + prs_set_offset(&ps, 0); + + pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA)); + pac_io_pac_data("pac data", pac_data, &ps, 0); + + prs_mem_free(&ps); + + return pac_data; +} + +#endif diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c new file mode 100644 index 0000000000..00fe189e9a --- /dev/null +++ b/source3/libsmb/clifsinfo.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS implementation. + FS info functions + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + + if (!cli||!fs_attr) + smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 12) { + goto cleanup; + } + + *fs_attr = IVAL(rdata,0); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} diff --git a/source3/rpc_client/cli_echo.c b/source3/rpc_client/cli_echo.c new file mode 100644 index 0000000000..03a4ab36ee --- /dev/null +++ b/source3/rpc_client/cli_echo.c @@ -0,0 +1,187 @@ +/* + Unix SMB/CIFS implementation. + + RPC pipe client + + Copyright (C) Tim Potter 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 request, uint32 *response) +{ + prs_struct qbuf, rbuf; + ECHO_Q_ADD_ONE q; + ECHO_R_ADD_ONE r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_add_one(&q, request); + + if (!echo_io_q_add_one("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_ADD_ONE, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!echo_io_r_add_one("", &r, &rbuf, 0)) + goto done; + + if (response) + *response = r.response; + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char *in_data, char **out_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_ECHO_DATA q; + ECHO_R_ECHO_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_echo_data(&q, size, in_data); + + if (!echo_io_q_echo_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_DATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!echo_io_r_echo_data("", &r, &rbuf, 0)) + goto done; + + result = True; + + if (out_data) { + *out_data = talloc(mem_ctx, size); + memcpy(*out_data, r.data, size); + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char *in_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_SINK_DATA q; + ECHO_R_SINK_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_sink_data(&q, size, in_data); + + if (!echo_io_q_sink_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_SINK_DATA, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!echo_io_r_sink_data("", &r, &rbuf, 0)) { + goto done; + } + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 size, char **out_data) +{ + prs_struct qbuf, rbuf; + ECHO_Q_SOURCE_DATA q; + ECHO_R_SOURCE_DATA r; + BOOL result = False; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_echo_q_source_data(&q, size); + + if (!echo_io_q_source_data("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, ECHO_SOURCE_DATA, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!echo_io_r_source_data("", &r, &rbuf, 0)) { + goto done; + } + + result = True; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} diff --git a/source3/rpc_parse/parse_echo.c b/source3/rpc_parse/parse_echo.c new file mode 100644 index 0000000000..67f9ad772e --- /dev/null +++ b/source3/rpc_parse/parse_echo.c @@ -0,0 +1,166 @@ +/* + * Unix SMB/CIFS implementation. + * + * RPC Pipe client / server routines + * + * Copyright (C) Tim Potter 2003 + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" +#include "nterr.h" +#include "rpc_parse.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_PARSE + +void init_echo_q_add_one(ECHO_Q_ADD_ONE *q_d, uint32 request) +{ + q_d->request = request; +} + +BOOL echo_io_q_add_one(const char *desc, ECHO_Q_ADD_ONE *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("request", ps, 0, &q_d->request)) + return False; + + return True; +} + +BOOL echo_io_r_add_one(const char *desc, ECHO_R_ADD_ONE *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("response", ps, 0, &q_d->response)) + return False; + + return True; +} + + +void init_echo_q_echo_data(ECHO_Q_ECHO_DATA *q_d, uint32 size, char *data) +{ + q_d->size = size; + q_d->data = data; +} + +BOOL echo_io_q_echo_data(const char *desc, ECHO_Q_ECHO_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_echo_data(const char *desc, ECHO_R_ECHO_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, 0, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +void init_echo_q_sink_data(ECHO_Q_SINK_DATA *q_d, uint32 size, char *data) +{ + q_d->size = size; + q_d->data = data; +} + +BOOL echo_io_q_sink_data(const char *desc, ECHO_Q_SINK_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_sink_data(const char *desc, ECHO_R_SINK_DATA *q_d, + prs_struct *ps, int depth) +{ + return True; +} + +void init_echo_q_source_data(ECHO_Q_SOURCE_DATA *q_d, uint32 size) +{ + q_d->size = size; +} + +BOOL echo_io_q_source_data(const char *desc, ECHO_Q_SOURCE_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, depth, &q_d->size)) + return False; + + return True; +} + +BOOL echo_io_r_source_data(const char *desc, ECHO_R_SOURCE_DATA *q_d, + prs_struct *ps, int depth) +{ + if (!prs_uint32("size", ps, 0, &q_d->size)) + return False; + + if (UNMARSHALLING(ps)) { + q_d->data = prs_alloc_mem(ps, q_d->size); + + if (!q_d->data) + return False; + } + + if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size)) + return False; + + return True; +} diff --git a/source3/rpc_server/srv_echo.c b/source3/rpc_server/srv_echo.c new file mode 100644 index 0000000000..dcd8dd0c53 --- /dev/null +++ b/source3/rpc_server/srv_echo.c @@ -0,0 +1,137 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines for rpcecho + * Copyright (C) Tim Potter 2003. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* This is the interface to the rpcecho pipe. */ + +#include "includes.h" +#include "nterr.h" + +#ifdef DEVELOPER + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +static BOOL api_add_one(pipes_struct *p) +{ + ECHO_Q_ADD_ONE q_u; + ECHO_R_ADD_ONE r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_add_one("", &q_u, data, 0)) + return False; + + _echo_add_one(p, &q_u, &r_u); + + if(!echo_io_r_add_one("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_echo_data(pipes_struct *p) +{ + ECHO_Q_ECHO_DATA q_u; + ECHO_R_ECHO_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_echo_data("", &q_u, data, 0)) + return False; + + _echo_data(p, &q_u, &r_u); + + if(!echo_io_r_echo_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_source_data(pipes_struct *p) +{ + ECHO_Q_SOURCE_DATA q_u; + ECHO_R_SOURCE_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_source_data("", &q_u, data, 0)) + return False; + + _source_data(p, &q_u, &r_u); + + if(!echo_io_r_source_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +static BOOL api_sink_data(pipes_struct *p) +{ + ECHO_Q_SINK_DATA q_u; + ECHO_R_SINK_DATA r_u; + + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!echo_io_q_sink_data("", &q_u, data, 0)) + return False; + + _sink_data(p, &q_u, &r_u); + + if(!echo_io_r_sink_data("", &r_u, rdata, 0)) + return False; + + return True; +} + +/******************************************************************* +\pipe\rpcecho commands +********************************************************************/ + +int rpc_echo_init(void) +{ + struct api_struct api_echo_cmds[] = { + {"ADD_ONE", ECHO_ADD_ONE, api_add_one }, + {"ECHO_DATA", ECHO_DATA, api_echo_data }, + {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data }, + {"SINK_DATA", ECHO_SINK_DATA, api_sink_data }, + }; + + return rpc_pipe_register_commands( + "rpcecho", "rpcecho", api_echo_cmds, + sizeof(api_echo_cmds) / sizeof(struct api_struct)); +} + +#endif /* DEVELOPER */ diff --git a/source3/rpc_server/srv_echo_nt.c b/source3/rpc_server/srv_echo_nt.c new file mode 100644 index 0000000000..ddb76b3a21 --- /dev/null +++ b/source3/rpc_server/srv_echo_nt.c @@ -0,0 +1,78 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines for rpcecho + * Copyright (C) Tim Potter 2003. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* This is the interface to the rpcecho pipe. */ + +#include "includes.h" +#include "nterr.h" + +#ifdef DEVELOPER + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + +/* Add one to the input and return it */ + +void _echo_add_one(pipes_struct *p, ECHO_Q_ADD_ONE *q_u, ECHO_R_ADD_ONE *r_u) +{ + DEBUG(10, ("_echo_add_one\n")); + + r_u->response = q_u->request + 1; +} + +/* Echo back an array of data */ + +void _echo_data(pipes_struct *p, ECHO_Q_ECHO_DATA *q_u, + ECHO_R_ECHO_DATA *r_u) +{ + DEBUG(10, ("_echo_data\n")); + + r_u->data = talloc(p->mem_ctx, q_u->size); + r_u->size = q_u->size; + memcpy(r_u->data, q_u->data, q_u->size); +} + +/* Sink an array of data */ + +void _sink_data(pipes_struct *p, ECHO_Q_SINK_DATA *q_u, + ECHO_R_SINK_DATA *r_u) +{ + DEBUG(10, ("_sink_data\n")); + + /* My that was some yummy data! */ +} + +/* Source an array of data */ + +void _source_data(pipes_struct *p, ECHO_Q_SOURCE_DATA *q_u, + ECHO_R_SOURCE_DATA *r_u) +{ + uint32 i; + + DEBUG(10, ("_source_data\n")); + + r_u->data = talloc(p->mem_ctx, q_u->size); + r_u->size = q_u->size; + + for (i = 0; i < r_u->size; i++) + r_u->data[i] = i & 0xff; +} + +#endif /* DEVELOPER */ diff --git a/source3/rpcclient/cmd_echo.c b/source3/rpcclient/cmd_echo.c new file mode 100644 index 0000000000..79ba744a55 --- /dev/null +++ b/source3/rpcclient/cmd_echo.c @@ -0,0 +1,157 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Tim Potter 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "rpcclient.h" + +static NTSTATUS cmd_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 request = 1, response; + NTSTATUS result; + + if (argc > 2) { + printf("Usage: %s [num]\n", argv[0]); + return NT_STATUS_OK; + } + + if (argc == 2) + request = atoi(argv[1]); + + result = cli_echo_add_one(cli, mem_ctx, request, &response); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + printf("%d + 1 = %d\n", request, response); + +done: + return result; +} + +static NTSTATUS cmd_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *in_data = NULL, *out_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + in_data = malloc(size); + + for (i = 0; i < size; i++) + in_data[i] = i & 0xff; + + result = cli_echo_data(cli, mem_ctx, size, in_data, &out_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < size; i++) { + if (in_data[i] != out_data[i]) { + printf("mismatch at offset %d, %d != %d\n", + i, in_data[i], out_data[i]); + } + } + +done: + SAFE_FREE(in_data); + + return result; +} + +static NTSTATUS cmd_echo_source_data(struct cli_state *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *out_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + + result = cli_echo_source_data(cli, mem_ctx, size, &out_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + for (i = 0; i < size; i++) { + if (out_data && out_data[i] != (i & 0xff)) { + printf("mismatch at offset %d, %d != %d\n", + i, out_data[i], i & 0xff); + } + } + +done: + return result; +} + +static NTSTATUS cmd_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx, + int argc, const char **argv) +{ + uint32 size, i; + NTSTATUS result; + char *in_data = NULL; + + if (argc != 2) { + printf("Usage: %s num\n", argv[0]); + return NT_STATUS_OK; + } + + size = atoi(argv[1]); + in_data = malloc(size); + + for (i = 0; i < size; i++) + in_data[i] = i & 0xff; + + result = cli_echo_sink_data(cli, mem_ctx, size, in_data); + + if (!NT_STATUS_IS_OK(result)) + goto done; + +done: + SAFE_FREE(in_data); + + return result; +} + +/* List of commands exported by this module */ + +struct cmd_set echo_commands[] = { + + { "ECHO" }, + + { "echoaddone", RPC_RTYPE_NTSTATUS, cmd_echo_add_one, NULL, PI_ECHO, "Add one to a number", "" }, + { "echodata", RPC_RTYPE_NTSTATUS, cmd_echo_data, NULL, PI_ECHO, "Echo data", "" }, + { "sinkdata", RPC_RTYPE_NTSTATUS, cmd_echo_sink_data, NULL, PI_ECHO, "Sink data", "" }, + { "sourcedata", RPC_RTYPE_NTSTATUS, cmd_echo_source_data, NULL, PI_ECHO, "Source data", "" }, + { NULL } +}; diff --git a/source3/stf/smbcontrol.py b/source3/stf/smbcontrol.py new file mode 100755 index 0000000000..30c331819c --- /dev/null +++ b/source3/stf/smbcontrol.py @@ -0,0 +1,238 @@ +#!/usr/bin/python +# +# Test for smbcontrol command line argument handling. +# + +import comfychair + +class NoArgs(comfychair.TestCase): + """Test no arguments produces usage message.""" + def runtest(self): + out = self.runcmd("smbcontrol", expectedResult = 1) + self.assert_re_match("Usage: smbcontrol", out[1]) + +class OneArg(comfychair.TestCase): + """Test single argument produces usage message.""" + def runtest(self): + out = self.runcmd("smbcontrol foo", expectedResult = 1) + self.assert_re_match("Usage: smbcontrol", out[1]) + +class SmbdDest(comfychair.TestCase): + """Test the broadcast destination 'smbd'.""" + def runtest(self): + out = self.runcmd("smbcontrol smbd noop") + +class NmbdDest(comfychair.TestCase): + """Test the destination 'nmbd'.""" + def runtest(self): + # We need a way to start/stop/whatever nmbd + raise comfychair.NotRunError, "not implemented" + +class PidDest(comfychair.TestCase): + """Test a pid number destination'.""" + def runtest(self): + out = self.runcmd("smbcontrol 1234 noop") + +class SelfDest(comfychair.TestCase): + """Test the destination 'self'.""" + def runtest(self): + out = self.runcmd("smbcontrol self noop") + +class WinbinddDest(comfychair.TestCase): + """Test the destination 'winbindd'.""" + def runtest(self): + # We need a way to start/stop/whatever winbindd + raise comfychair.NotRunError, "not implemented" + +class BadDest(comfychair.TestCase): + """Test a bad destination.""" + def runtest(self): + out = self.runcmd("smbcontrol foo noop", expectedResult = 1) + +class BadCmd(comfychair.TestCase): + """Test a bad command.""" + def runtest(self): + out = self.runcmd("smbcontrol self spottyfoot", expectedResult = 1) + self.assert_re_match("smbcontrol: unknown command", out[1]); + +class NoArgCmdTest(comfychair.TestCase): + """A test class that tests a command with no argument.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self %s" % self.cmd) + out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd, + expectedResult = 1) + +class ForceElection(NoArgCmdTest): + """Test a force-election message.""" + def setup(self): + self.cmd = "force-election" + +class SamSync(NoArgCmdTest): + """Test a samsync message.""" + def setup(self): + self.cmd = "samsync" + +class SamRepl(NoArgCmdTest): + """Test a samrepl message.""" + def setup(self): + self.cmd = "samrepl" + +class DmallocChanged(NoArgCmdTest): + """Test a dmalloc-changed message.""" + def setup(self): + self.cmd = "dmalloc-log-changed" + +class DmallocMark(NoArgCmdTest): + """Test a dmalloc-mark message.""" + def setup(self): + self.cmd = "dmalloc-mark" + +class Shutdown(NoArgCmdTest): + """Test a shutdown message.""" + def setup(self): + self.cmd = "shutdown" + +class Ping(NoArgCmdTest): + """Test a ping message.""" + def setup(self): + self.cmd = "ping" + +class Debuglevel(NoArgCmdTest): + """Test a debuglevel message.""" + def setup(self): + self.cmd = "debuglevel" + +class OneArgCmdTest(comfychair.TestCase): + """A test class that tests a command with one argument.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self %s spottyfoot" % self.cmd) + out = self.runcmd("smbcontrol self %s" % self.cmd, expectedResult = 1) + +class DrvUpgrade(OneArgCmdTest): + """Test driver upgrade message.""" + def setup(self): + self.cmd = "drvupgrade" + +class CloseShare(OneArgCmdTest): + """Test close share message.""" + def setup(self): + self.cmd = "close-share" + +class Debug(OneArgCmdTest): + """Test a debug message.""" + def setup(self): + self.cmd = "debug" + +class PrintNotify(comfychair.TestCase): + """Test print notification commands.""" + def runtest(self): + + # No subcommand + + out = self.runcmd("smbcontrol self printnotify", expectedResult = 1) + self.assert_re_match("Must specify subcommand", out[1]); + + # Invalid subcommand name + + out = self.runcmd("smbcontrol self printnotify spottyfoot", + expectedResult = 1) + self.assert_re_match("Invalid subcommand", out[1]); + + # Queue commands + + for cmd in ["queuepause", "queueresume"]: + + out = self.runcmd("smbcontrol self printnotify %s" % cmd, + expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot" + % cmd) + + # Job commands + + for cmd in ["jobpause", "jobresume", "jobdelete"]: + + out = self.runcmd("smbcontrol self printnotify %s" % cmd, + expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot" + % cmd, expectedResult = 1) + self.assert_re_match("Usage:", out[1]) + + out = self.runcmd("smbcontrol self printnotify %s spottyfoot 123" + % cmd) + + # Printer properties + + out = self.runcmd("smbcontrol self printnotify printer", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + for cmd in ["comment", "port", "driver"]: + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot " + "%s" % cmd, expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self printnotify printer spottyfoot " + "%s value" % cmd) + +class Profile(comfychair.TestCase): + """Test setting the profiling level.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self profile", expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self profile spottyfoot", + expectedResult = 1) + self.assert_re_match("Unknown", out[1]) + + for cmd in ["off", "count", "on", "flush"]: + out = self.runcmd("smbcontrol self profile %s" % cmd) + +class ProfileLevel(comfychair.TestCase): + """Test requesting the current profiling level.""" + def runtest(self): + self.require_root() + out = self.runcmd("smbcontrol self profilelevel spottyfoot", + expectedResult = 1) + self.assert_re_match("Usage", out[1]) + + out = self.runcmd("smbcontrol self profilelevel") + +class TimeoutArg(comfychair.TestCase): + """Test the --timeout argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --timeout 5 self noop") + out = self.runcmd("smbcontrol --timeout spottyfoot self noop", + expectedResult = 1) + +class ConfigFileArg(comfychair.TestCase): + """Test the --configfile argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --configfile /dev/null self noop") + +class BogusArg(comfychair.TestCase): + """Test a bogus command line argument.""" + def runtest(self): + out = self.runcmd("smbcontrol --bogus self noop", expectedResult = 1) + +tests = [NoArgs, OneArg, SmbdDest, NmbdDest, WinbinddDest, PidDest, + SelfDest, BadDest, BadCmd, Debug, ForceElection, SamSync, + SamRepl, DmallocMark, DmallocChanged, Shutdown, DrvUpgrade, + CloseShare, Ping, Debuglevel, PrintNotify, Profile, ProfileLevel, + TimeoutArg, ConfigFileArg, BogusArg] + +# Handle execution of this file as a main program + +if __name__ == '__main__': + comfychair.main(tests) diff --git a/source3/stf/unicodenames.py b/source3/stf/unicodenames.py new file mode 100644 index 0000000000..d4100cb7f9 --- /dev/null +++ b/source3/stf/unicodenames.py @@ -0,0 +1,33 @@ +#! /usr/bin/python + +# Copyright (C) 2003 by Martin Pool <mbp@samba.org> +# +# 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 the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA + + +""" +Defines symbolic names for a few UNICODE characters, to make test +source code more readable on machines that don't have all the +necessary fonts. + +You can do "import *" on this file safely. +""" + +LATIN_CAPITAL_LETTER_N_WITH_TILDE = u'\u004e' +LATIN_CAPITAL_LETTER_O_WITH_DIARESIS = u'\u00d6' +LATIN_SMALL_LETTER_O_WITH_DIARESIS = u'\u00f6' + +KATAKANA_LETTER_A = u'\u30a2' diff --git a/source3/torture/t_push_ucs2.c b/source3/torture/t_push_ucs2.c new file mode 100644 index 0000000000..8bfc6f7ad9 --- /dev/null +++ b/source3/torture/t_push_ucs2.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2003 by Martin Pool + * Copyright (C) 2003 by Andrew Bartlett + * + * Test harness for push_ucs2 + */ + +#include "includes.h" + +static int check_push_ucs2(const char *orig) +{ + smb_ucs2_t *dest = NULL; + char *orig2 = NULL; + int ret; + + push_ucs2_allocate(&dest, orig); + pull_ucs2_allocate(&orig2, dest); + ret = strcmp(orig, orig2); + if (ret) { + fprintf(stderr, "orig: %s\n", orig); + fprintf(stderr, "orig (UNIX -> UCS2 -> UNIX): %s\n", orig2); + } + + SAFE_FREE(dest); + SAFE_FREE(orig2); + + return ret; +} + +int main(int argc, char *argv[]) +{ + int i, ret = 0; + int count = 1; + + /* Needed to initialize character set */ + lp_load("/dev/null", True, False, False); + + if (argc < 2) { + fprintf(stderr, "usage: %s STRING1 [COUNT]\n" + "Checks that a string translated UNIX->UCS2->UNIX is unchanged\n" + "Should be always 0\n", + argv[0]); + return 2; + } + if (argc >= 3) + count = atoi(argv[2]); + + for (i = 0; ((i < count) && (!ret)); i++) + ret = check_push_ucs2(argv[1]); + + printf("%d\n", ret); + + return 0; +} diff --git a/source3/torture/t_strcmp.c b/source3/torture/t_strcmp.c new file mode 100644 index 0000000000..bc8640ee55 --- /dev/null +++ b/source3/torture/t_strcmp.c @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2003 by Martin Pool + * + * Test harness for StrCaseCmp + */ + +#include "includes.h" + +int main(int argc, char *argv[]) +{ + int i, ret; + int iters = 1; + + /* Needed to initialize character set */ + lp_load("/dev/null", True, False, False); + + if (argc < 3) { + fprintf(stderr, "usage: %s STRING1 STRING2 [ITERS]\n" + "Compares two strings, prints the results of StrCaseCmp\n", + argv[0]); + return 2; + } + if (argc >= 4) + iters = atoi(argv[3]); + + for (i = 0; i < iters; i++) + ret = StrCaseCmp(argv[1], argv[2]); + + printf("%d\n", ret); + + return 0; +} diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c new file mode 100644 index 0000000000..c5d0aa869b --- /dev/null +++ b/source3/utils/smbcquotas.c @@ -0,0 +1,545 @@ +/* + Unix SMB/CIFS implementation. + QUOTA get/set utility + + Copyright (C) Andrew Tridgell 2000 + Copyright (C) Tim Potter 2000 + Copyright (C) Jeremy Allison 2000 + Copyright (C) Stefan (metze) Metzmacher 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static pstring server; + +/* numeric is set when the user wants numeric SIDs and ACEs rather + than going via LSA calls to resolve them */ +static BOOL numeric; +static BOOL verbose; + +enum todo_values {NOOP_QUOTA=0,FS_QUOTA,USER_QUOTA,LIST_QUOTA,SET_QUOTA}; +enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR}; + +static struct cli_state *cli_ipc = NULL; +static POLICY_HND pol; +static BOOL got_policy_hnd; + +static struct cli_state *connect_one(const char *share); + +/* Open cli connection and policy handle */ + +static BOOL cli_open_policy_hnd(void) +{ + /* Initialise cli LSA connection */ + + if (!cli_ipc) { + cli_ipc = connect_one("IPC$"); + if (!cli_nt_session_open (cli_ipc, PI_LSARPC)) { + return False; + } + } + + /* Open policy handle */ + + if (!got_policy_hnd) { + + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ + + if (!NT_STATUS_IS_OK(cli_lsa_open_policy(cli_ipc, cli_ipc->mem_ctx, True, + GENERIC_EXECUTE_ACCESS, &pol))) { + return False; + } + + got_policy_hnd = True; + } + + return True; +} + +/* convert a SID to a string, either numeric or username/group */ +static void SidToString(fstring str, DOM_SID *sid, BOOL _numeric) +{ + char **domains = NULL; + char **names = NULL; + uint32 *types = NULL; + + sid_to_string(str, sid); + + if (_numeric) return; + + /* Ask LSA to convert the sid to a name */ + + if (!cli_open_policy_hnd() || + !NT_STATUS_IS_OK(cli_lsa_lookup_sids(cli_ipc, cli_ipc->mem_ctx, + &pol, 1, sid, &domains, + &names, &types)) || + !domains || !domains[0] || !names || !names[0]) { + return; + } + + /* Converted OK */ + + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); + +} + +/* convert a string to a SID, either numeric or username/group */ +static BOOL StringToSid(DOM_SID *sid, const char *str) +{ + uint32 *types = NULL; + DOM_SID *sids = NULL; + BOOL result = True; + + if (strncmp(str, "S-", 2) == 0) { + return string_to_sid(sid, str); + } + + if (!cli_open_policy_hnd() || + !NT_STATUS_IS_OK(cli_lsa_lookup_names(cli_ipc, cli_ipc->mem_ctx, + &pol, 1, &str, &sids, + &types))) { + result = False; + goto done; + } + + sid_copy(sid, &sids[0]); + done: + + return result; +} + +#define QUOTA_GET 1 +#define QUOTA_SETLIM 2 +#define QUOTA_SETFLAGS 3 +#define QUOTA_LIST 4 + +enum {PARSE_FLAGS,PARSE_LIM}; + +static int parse_quota_set(pstring set_str, pstring username_str, enum SMB_QUOTA_TYPE *qtype, int *cmd, SMB_NTQUOTA_STRUCT *pqt) +{ + char *p = set_str,*p2; + int todo; + BOOL stop = False; + BOOL enable = False; + BOOL deny = False; + + if (strncasecmp(set_str,"UQLIM:",6)==0) { + p += 6; + *qtype = SMB_USER_QUOTA_TYPE; + *cmd = QUOTA_SETLIM; + todo = PARSE_LIM; + if ((p2=strstr(p,":"))==NULL) { + return -1; + } + + *p2 = '\0'; + p2++; + + fstrcpy(username_str,p); + p = p2; + } else if (strncasecmp(set_str,"FSQLIM:",7)==0) { + p +=7; + *qtype = SMB_USER_FS_QUOTA_TYPE; + *cmd = QUOTA_SETLIM; + todo = PARSE_LIM; + } else if (strncasecmp(set_str,"FSQFLAGS:",9)==0) { + p +=9; + todo = PARSE_FLAGS; + *qtype = SMB_USER_FS_QUOTA_TYPE; + *cmd = QUOTA_SETFLAGS; + } else { + return -1; + } + + switch (todo) { + case PARSE_LIM: +#if defined(HAVE_LONGLONG) + if (sscanf(p,"%llu/%llu",&pqt->softlim,&pqt->hardlim)!=2) { +#else + if (sscanf(p,"%lu/%lu",&pqt->softlim,&pqt->hardlim)!=2) { +#endif + return -1; + } + + break; + case PARSE_FLAGS: + while (!stop) { + + if ((p2=strstr(p,"/"))==NULL) { + stop = True; + } else { + *p2 = '\0'; + p2++; + } + + if (strncasecmp(p,"QUOTA_ENABLED",13)==0) { + enable = True; + } else if (strncasecmp(p,"DENY_DISK",9)==0) { + deny = True; + } else if (strncasecmp(p,"LOG_SOFTLIMIT",13)==0) { + pqt->qflags |= QUOTAS_LOG_THRESHOLD; + } else if (strncasecmp(p,"LOG_HARDLIMIT",13)==0) { + pqt->qflags |= QUOTAS_LOG_LIMIT; + } else { + return -1; + } + + p=p2; + } + + if (deny) { + pqt->qflags |= QUOTAS_DENY_DISK; + } else if (enable) { + pqt->qflags |= QUOTAS_ENABLED; + } + + break; + } + + return 0; +} + +static int do_quota(struct cli_state *cli, enum SMB_QUOTA_TYPE qtype, uint16 cmd, pstring username_str, SMB_NTQUOTA_STRUCT *pqt) +{ + uint32 fs_attrs = 0; + int quota_fnum = 0; + SMB_NTQUOTA_LIST *qtl = NULL; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + + if (!cli_get_fs_attr_info(cli, &fs_attrs)) { + d_printf("Failed to get the filesystem attributes %s.\n", + cli_errstr(cli)); + return -1; + } + + if (!(fs_attrs & FILE_VOLUME_QUOTAS)) { + d_printf("Quotas are not supported by the server.\n"); + return 0; + } + + if (!cli_get_quota_handle(cli, "a_fnum)) { + d_printf("Failed to open \\%s %s.\n", + FAKE_FILE_NAME_QUOTA,cli_errstr(cli)); + return -1; + } + + switch(qtype) { + case SMB_USER_QUOTA_TYPE: + if (!StringToSid(&qt.sid, username_str)) { + d_printf("StringToSid() failed for [%s]\n",username_str); + return -1; + } + + switch(cmd) { + case QUOTA_GET: + if (!cli_get_user_quota(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota(&qt,verbose,numeric,SidToString); + break; + case QUOTA_SETLIM: + pqt->sid = qt.sid; + if (!cli_set_user_quota(cli, quota_fnum, pqt)) { + d_printf("%s cli_set_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + if (!cli_get_user_quota(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota(&qt,verbose,numeric,SidToString); + break; + case QUOTA_LIST: + if (!cli_list_user_quota(cli, quota_fnum, &qtl)) { + d_printf("%s cli_set_user_quota %s\n", + cli_errstr(cli),username_str); + return -1; + } + dump_ntquota_list(&qtl,verbose,numeric,SidToString); + free_ntquota_list(&qtl); + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + break; + case SMB_USER_FS_QUOTA_TYPE: + switch(cmd) { + case QUOTA_GET: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + case QUOTA_SETLIM: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + qt.softlim = pqt->softlim; + qt.hardlim = pqt->hardlim; + if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_set_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + case QUOTA_SETFLAGS: + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + qt.qflags = pqt->qflags; + if (!cli_set_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_set_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + if (!cli_get_fs_quota_info(cli, quota_fnum, &qt)) { + d_printf("%s cli_get_fs_quota_info\n", + cli_errstr(cli)); + return -1; + } + dump_ntquota(&qt,True,numeric,NULL); + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + break; + default: + d_printf("Unknown Error\n"); + return -1; + } + + cli_close(cli, quota_fnum); + + return 0; +} + +/***************************************************** +return a connection to a server +*******************************************************/ +static struct cli_state *connect_one(const char *share) +{ + struct cli_state *c; + struct in_addr ip; + NTSTATUS nt_status; + zero_ip(&ip); + + if (!cmdline_auth_info.got_pass) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(cmdline_auth_info.password, pass); + cmdline_auth_info.got_pass = True; + } + } + + if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname(), server, + &ip, 0, + share, "?????", + cmdline_auth_info.username, lp_workgroup(), + cmdline_auth_info.password, 0, NULL))) { + return c; + } else { + DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); + return NULL; + } +} + +/**************************************************************************** + main program +****************************************************************************/ + int main(int argc, const char *argv[]) +{ + char *share; + int opt; + int result; + int todo = 0; + pstring username_str = {0}; + pstring path = {0}; + pstring set_str = {0}; + enum SMB_QUOTA_TYPE qtype; + int cmd = 0; + BOOL test_args = False; + struct cli_state *cli; + BOOL fix_user = False; + SMB_NTQUOTA_STRUCT qt; + poptContext pc; + struct poptOption long_options[] = { + POPT_AUTOHELP + { "user", 'u', POPT_ARG_STRING, NULL, 'u', "Show quotas for user", "user" }, + { "list", 'L', POPT_ARG_NONE, NULL, 'L', "List user quotas" }, + { "fs", 'F', POPT_ARG_NONE, NULL, 'F', "Show filesystem quotas" }, + { "set", 'S', POPT_ARG_STRING, NULL, 'S', "Set acls\n\ +SETSTRING:\n\ +UQLIM:<username>/<softlimit>/<hardlimit> for user quotas\n\ +FSQLIM:<softlimit>/<hardlimit> for filesystem defaults\n\ +FSQFLAGS:QUOTA_ENABLED/DENY_DISK/LOG_SOFTLIMIT/LOG_HARD_LIMIT", "SETSTRING" }, + { "numeric", 'n', POPT_ARG_NONE, &numeric, True, "Don't resolve sids or limits to names" }, + { "verbose", 'v', POPT_ARG_NONE, &verbose, True, "be verbose" }, + { "test-args", 't', POPT_ARG_NONE, &test_args, True, "Test arguments"}, + POPT_COMMON_SAMBA + POPT_COMMON_CREDENTIALS + { NULL } + }; + + ZERO_STRUCT(qt); + + setlinebuf(stdout); + + dbf = x_stderr; + + fault_setup(NULL); + + setup_logging(argv[0],True); + + + lp_load(dyn_CONFIGFILE,True,False,False); + load_interfaces(); + + pc = poptGetContext("smbcquotas", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "//server1/share1"); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 'L': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + todo = LIST_QUOTA; + break; + + case 'F': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + todo = FS_QUOTA; + break; + + case 'u': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + pstrcpy(username_str,poptGetOptArg(pc)); + todo = USER_QUOTA; + fix_user = True; + break; + + case 'S': + if (todo != 0) { + d_printf("Please specify only one option of <-L|-F|-S|-u>\n"); + exit(EXIT_PARSE_ERROR); + } + pstrcpy(set_str,poptGetOptArg(pc)); + todo = SET_QUOTA; + break; + } + } + + if (todo == 0) + todo = USER_QUOTA; + + if (!fix_user) + pstrcpy(username_str,cmdline_auth_info.username); + + /* Make connection to server */ + if(!poptPeekArg(pc)) { + poptPrintUsage(pc, stderr, 0); + exit(EXIT_PARSE_ERROR); + } + + pstrcpy(path, poptGetArg(pc)); + + all_string_sub(path,"/","\\",0); + + pstrcpy(server,path+2); + share = strchr_m(server,'\\'); + if (!share) { + share = strchr_m(server,'/'); + if (!share) { + printf("Invalid argument: %s\n", share); + exit(EXIT_PARSE_ERROR); + } + } + + *share = 0; + share++; + + if (todo == SET_QUOTA) { + if (parse_quota_set(set_str, username_str, &qtype, &cmd, &qt)) { + printf("Invalid argument: -S %s\n", set_str); + exit(EXIT_PARSE_ERROR); + } + } + + if (!test_args) { + cli = connect_one(share); + if (!cli) { + exit(EXIT_FAILED); + } + } else { + exit(EXIT_OK); + } + + + /* Perform requested action */ + + switch (todo) { + case FS_QUOTA: + result = do_quota(cli,SMB_USER_FS_QUOTA_TYPE, QUOTA_GET, username_str, NULL); + break; + case LIST_QUOTA: + result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_LIST, username_str, NULL); + break; + case USER_QUOTA: + result = do_quota(cli,SMB_USER_QUOTA_TYPE, QUOTA_GET, username_str, NULL); + break; + case SET_QUOTA: + result = do_quota(cli, qtype, cmd, username_str, &qt); + break; + default: + + result = EXIT_FAILED; + break; + } + + return result; +} + |