summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/bin/.cvsignore4
-rw-r--r--source3/include/passdb.h28
-rw-r--r--source3/include/rpc_samr.h102
-rw-r--r--source3/passdb/pdb_tdb.c70
-rw-r--r--source3/passdb/pdb_unix.c62
-rw-r--r--source3/rpc_parse/parse_samr.c45
-rw-r--r--source3/rpc_server/srv_samr_nt.c23
-rw-r--r--source3/rpc_server/srv_samr_util.c420
-rw-r--r--source3/sam/interface.c5
-rw-r--r--source3/torture/cmd_sam.c175
-rw-r--r--source3/utils/smbgroupedit.c47
11 files changed, 761 insertions, 220 deletions
diff --git a/source3/bin/.cvsignore b/source3/bin/.cvsignore
index c152d8918a..de6085d526 100644
--- a/source3/bin/.cvsignore
+++ b/source3/bin/.cvsignore
@@ -10,6 +10,7 @@ msgtest
net
nmbd
nmblookup
+nsstest
pdbedit
rpcclient
samsync
@@ -18,6 +19,7 @@ smbcacls
smbclient
smbcontrol
smbd
+smbfilter
smbgroupedit
smbmnt
smbmount
@@ -36,3 +38,5 @@ testprns
wbinfo
winbindd
wrepld
+vfstest
+samtest
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 7a791ddac4..0c694987fe 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -49,21 +49,21 @@ typedef struct pdb_context
/* These functions are wrappers for the functions listed above.
They may do extra things like re-reading a SAM_ACCOUNT on update */
- BOOL (*pdb_setsampwent)(struct pdb_context *, BOOL update);
+ NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update);
void (*pdb_endsampwent)(struct pdb_context *);
- BOOL (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
+ NTSTATUS (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
- BOOL (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
+ NTSTATUS (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
- BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
+ NTSTATUS (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
- BOOL (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
+ NTSTATUS (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
- BOOL (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
+ NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
- BOOL (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
+ NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
void (*free_fn)(struct pdb_context **);
@@ -80,21 +80,21 @@ typedef struct pdb_methods
struct pdb_methods *next;
struct pdb_methods *prev;
- BOOL (*setsampwent)(struct pdb_methods *, BOOL update);
+ NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update);
void (*endsampwent)(struct pdb_methods *);
- BOOL (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user);
+ NTSTATUS (*getsampwent)(struct pdb_methods *, SAM_ACCOUNT *user);
- BOOL (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
+ NTSTATUS (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
- BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid);
+ NTSTATUS (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid);
- BOOL (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
+ NTSTATUS (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
- BOOL (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
+ NTSTATUS (*update_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
- BOOL (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username);
+ NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username);
void *private_data; /* Private data of some kind */
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index 11438ae067..6b537715b8 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -177,49 +177,49 @@ SamrTestPrivateFunctionsUser
SAMR_ACCESS_UNKNOWN_1 )
/* Access bits to Domain-objects */
-
-#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x00000001
-#define DOMAIN_ACCESS_SET_INFO_1 0x00000002
-#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x00000004
-#define DOMAIN_ACCESS_SET_INFO_2 0x00000008
-#define DOMAIN_ACCESS_CREATE_USER 0x00000010
-#define DOMAIN_ACCESS_CREATE_GROUP 0x00000020
-#define DOMAIN_ACCESS_CREATE_ALIAS 0x00000040
-#define DOMAIN_ACCESS_UNKNOWN_80 0x00000080
-#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x00000100
-#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x00000200
-#define DOMAIN_ACCESS_SET_INFO_3 0x00000400
-
-#define DOMAIN_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
- DOMAIN_ACCESS_SET_INFO_3 | \
- DOMAIN_ACCESS_OPEN_ACCOUNT | \
- DOMAIN_ACCESS_ENUM_ACCOUNTS | \
- DOMAIN_ACCESS_UNKNOWN_80 | \
- DOMAIN_ACCESS_CREATE_ALIAS | \
- DOMAIN_ACCESS_CREATE_GROUP | \
- DOMAIN_ACCESS_CREATE_USER | \
- DOMAIN_ACCESS_SET_INFO_2 | \
- DOMAIN_ACCESS_LOOKUP_INFO_2 | \
- DOMAIN_ACCESS_SET_INFO_1 | \
- DOMAIN_ACCESS_LOOKUP_INFO_1 )
-
-#define DOMAIN_READ ( STANDARD_RIGHTS_READ_ACCESS | \
- DOMAIN_ACCESS_UNKNOWN_80 | \
- DOMAIN_ACCESS_LOOKUP_INFO_2 )
-
-#define DOMAIN_WRITE ( STANDARD_RIGHTS_WRITE_ACCESS | \
- DOMAIN_ACCESS_SET_INFO_3 | \
- DOMAIN_ACCESS_CREATE_ALIAS | \
- DOMAIN_ACCESS_CREATE_GROUP | \
- DOMAIN_ACCESS_CREATE_USER | \
- DOMAIN_ACCESS_SET_INFO_2 | \
- DOMAIN_ACCESS_SET_INFO_1 )
-
-#define DOMAIN_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS | \
- DOMAIN_ACCESS_OPEN_ACCOUNT | \
- DOMAIN_ACCESS_ENUM_ACCOUNTS | \
- DOMAIN_ACCESS_LOOKUP_INFO_1 )
-
+
+#define DOMAIN_ACCESS_LOOKUP_INFO_1 0x000000001
+#define DOMAIN_ACCESS_SET_INFO_1 0x000000002
+#define DOMAIN_ACCESS_LOOKUP_INFO_2 0x000000004
+#define DOMAIN_ACCESS_SET_INFO_2 0x000000008
+#define DOMAIN_ACCESS_CREATE_USER 0x000000010
+#define DOMAIN_ACCESS_CREATE_GROUP 0x000000020
+#define DOMAIN_ACCESS_CREATE_ALIAS 0x000000040
+#define DOMAIN_ACCESS_LOOKUP_ALIAS_BY_MEM 0x000000080
+#define DOMAIN_ACCESS_ENUM_ACCOUNTS 0x000000100
+#define DOMAIN_ACCESS_OPEN_ACCOUNT 0x000000200
+#define DOMAIN_ACCESS_SET_INFO_3 0x000000400
+
+#define DOMAIN_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
+ DOMAIN_ACCESS_SET_INFO_3 | \
+ DOMAIN_ACCESS_OPEN_ACCOUNT | \
+ DOMAIN_ACCESS_ENUM_ACCOUNTS | \
+ DOMAIN_ACCESS_LOOKUP_ALIAS_BY_MEM | \
+ DOMAIN_ACCESS_CREATE_ALIAS | \
+ DOMAIN_ACCESS_CREATE_GROUP | \
+ DOMAIN_ACCESS_CREATE_USER | \
+ DOMAIN_ACCESS_SET_INFO_2 | \
+ DOMAIN_ACCESS_LOOKUP_INFO_2 | \
+ DOMAIN_ACCESS_SET_INFO_1 | \
+ DOMAIN_ACCESS_LOOKUP_INFO_1 )
+
+#define DOMAIN_READ ( STANDARD_RIGHTS_READ_ACCESS | \
+ DOMAIN_ACCESS_LOOKUP_ALIAS_BY_MEM | \
+ DOMAIN_ACCESS_LOOKUP_INFO_2 )
+
+#define DOMAIN_WRITE ( STANDARD_RIGHTS_WRITE_ACCESS | \
+ DOMAIN_ACCESS_SET_INFO_3 | \
+ DOMAIN_ACCESS_CREATE_ALIAS | \
+ DOMAIN_ACCESS_CREATE_GROUP | \
+ DOMAIN_ACCESS_CREATE_USER | \
+ DOMAIN_ACCESS_SET_INFO_2 | \
+ DOMAIN_ACCESS_SET_INFO_1 )
+
+#define DOMAIN_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS | \
+ DOMAIN_ACCESS_OPEN_ACCOUNT | \
+ DOMAIN_ACCESS_ENUM_ACCOUNTS | \
+ DOMAIN_ACCESS_LOOKUP_INFO_1 )
+
/* Access bits to User-objects */
#define USER_ACCESS_GET_NAME_ETC 0x00000001
@@ -366,10 +366,14 @@ typedef struct sam_user_info_23
/* uint8 pad[2] */
uint32 ptr_logon_hrs; /* pointer to logon hours */
- uint8 padding1[8];
-
uint32 unknown_5; /* 0x0001 0000 */
+ uint8 padding1[6];
+
+ uint8 passmustchange; /* 0x00 must change = 0x01 */
+
+ uint8 padding2;
+
uint8 pass[516];
UNISTR2 uni_user_name; /* NULL - username unicode string */
@@ -487,7 +491,11 @@ typedef struct sam_user_info_21
uint32 unknown_5; /* 0x0002 0000 */
- uint8 padding1[8];
+ uint8 padding1[6];
+
+ uint8 passmustchange; /* 0x00 must change = 0x01 */
+
+ uint8 padding2;
UNISTR2 uni_user_name; /* username unicode string */
UNISTR2 uni_full_name; /* user's full name unicode string */
@@ -507,6 +515,8 @@ typedef struct sam_user_info_21
} SAM_USER_INFO_21;
+#define PASS_MUST_CHANGE_AT_NEXT_LOGON 0x01
+#define PASS_DONT_CHANGE_AT_NEXT_LOGON 0x00
/* SAM_USER_INFO_20 */
typedef struct sam_user_info_20
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 27453fc1af..241b3298b0 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -484,7 +484,7 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
Open the TDB passwd database for SAM account enumeration.
****************************************************************/
-static BOOL tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
{
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
@@ -492,12 +492,12 @@ static BOOL tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
{
DEBUG(0, ("Unable to open/create TDB passwd\n"));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb);
- return True;
+ return NT_STATUS_OK;
}
static void close_tdb(struct tdbsam_privates *tdb_state)
@@ -524,8 +524,9 @@ static void tdbsam_endsampwent(struct pdb_methods *my_methods)
Get one SAM_ACCOUNT from the TDB (next in line)
*****************************************************************/
-static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
+static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_DATA data;
char *prefix = USERPREFIX;
@@ -534,7 +535,7 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user
if (user==NULL) {
DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n"));
- return False;
+ return nt_status;
}
/* skip all non-USER entries (eg. RIDs) */
@@ -545,35 +546,36 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user
/* do we have an valid iteration pointer? */
if(tdb_state->passwd_tdb == NULL) {
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
- return False;
+ return nt_status;
}
data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key);
if (!data.dptr) {
DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
- return False;
+ return nt_status;
}
/* unpack the buffer */
if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
- return False;
+ return nt_status;
}
SAFE_FREE(data.dptr);
/* increment to next in line */
tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
- return True;
+ return NT_STATUS_OK;
}
/******************************************************************
Lookup a name in the SAM TDB
******************************************************************/
-static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
+static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
@@ -582,7 +584,7 @@ static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *use
if (user==NULL) {
DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
- return False;
+ return nt_status;
}
/* Data is stored in all lower-case */
@@ -596,7 +598,7 @@ static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *use
/* open the accounts TDB */
if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
- return False;
+ return nt_status;
}
/* get the record */
@@ -606,7 +608,7 @@ static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *use
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
DEBUGADD(5, (" Key: %s\n", keystr));
tdb_close(pwd_tdb);
- return False;
+ return nt_status;
}
/* unpack the buffer */
@@ -614,22 +616,23 @@ static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *use
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
tdb_close(pwd_tdb);
- return False;
+ return nt_status;
}
SAFE_FREE(data.dptr);
/* no further use for database, close it now */
tdb_close(pwd_tdb);
- return True;
+ return NT_STATUS_OK;
}
/***************************************************************************
Search by rid
**************************************************************************/
-static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
+static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
@@ -638,7 +641,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
if (user==NULL) {
DEBUG(0,("pdb_getsampwrid: SAM_ACCOUNT is NULL.\n"));
- return False;
+ return nt_status;
}
/* set search key */
@@ -649,7 +652,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
/* open the accounts TDB */
if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
- return False;
+ return nt_status;
}
/* get the record */
@@ -658,7 +661,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
DEBUG(5,("pdb_getsampwrid (TDB): error looking up RID %d by key %s.\n", rid, keystr));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (pwd_tdb);
- return False;
+ return nt_status;
}
fstrcpy (name, data.dptr);
@@ -669,11 +672,11 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
return tdbsam_getsampwnam (my_methods, user, name);
}
-static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
return tdbsam_getsampwrid(my_methods, user, rid);
}
@@ -681,8 +684,9 @@ static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * use
Delete a SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass)
+static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass)
{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA key;
@@ -695,7 +699,7 @@ static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUN
/* open the TDB */
if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR, 0600))) {
DEBUG(0, ("Unable to open TDB passwd!"));
- return False;
+ return nt_status;
}
/* set the search key */
@@ -710,7 +714,7 @@ static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUN
DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
- return False;
+ return nt_status;
}
/* delete also the RID key */
@@ -725,12 +729,12 @@ static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUN
DEBUG(5, ("Error deleting entry from tdb rid database!\n"));
DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close(pwd_tdb);
- return False;
+ return nt_status;
}
tdb_close(pwd_tdb);
- return True;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -872,18 +876,24 @@ done:
Modifies an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
{
- return (tdb_update_sam(my_methods, newpwd, TDB_MODIFY));
+ if (tdb_update_sam(my_methods, newpwd, TDB_MODIFY))
+ return NT_STATUS_OK;
+ else
+ return NT_STATUS_UNSUCCESSFUL;
}
/***************************************************************************
Adds an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
{
- return (tdb_update_sam(my_methods, newpwd, TDB_INSERT));
+ if (tdb_update_sam(my_methods, newpwd, TDB_INSERT))
+ return NT_STATUS_OK;
+ else
+ return NT_STATUS_UNSUCCESSFUL;
}
static void free_private_data(void **vp)
diff --git a/source3/passdb/pdb_unix.c b/source3/passdb/pdb_unix.c
index 06f12164eb..ba5ed0abdf 100644
--- a/source3/passdb/pdb_unix.c
+++ b/source3/passdb/pdb_unix.c
@@ -23,20 +23,20 @@
Lookup a name in the SAM database
******************************************************************/
-static BOOL unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
+static NTSTATUS unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
{
struct passwd *pass;
if (!methods) {
DEBUG(0,("invalid methods\n"));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
if (!sname) {
DEBUG(0,("invalid name specified"));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
pass = Get_Pwnam(sname);
- return NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+ return pdb_fill_sam_pw(user, pass);
}
@@ -44,45 +44,45 @@ static BOOL unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user,
Search by rid
**************************************************************************/
-static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
+static NTSTATUS unixsam_getsampwrid (struct pdb_methods *methods,
SAM_ACCOUNT *user, uint32 rid)
{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct passwd *pass;
- BOOL ret = False;
const char *guest_account = lp_guestaccount();
if (!(guest_account && *guest_account)) {
DEBUG(1, ("NULL guest account!?!?\n"));
- return False;
+ return nt_status;
}
if (!methods) {
DEBUG(0,("invalid methods\n"));
- return False;
+ return nt_status;
}
if (rid == DOMAIN_USER_RID_GUEST) {
pass = getpwnam_alloc(guest_account);
if (!pass) {
DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account));
- return False;
+ return nt_status;
}
} else if (pdb_rid_is_user(rid)) {
pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
} else {
- return False;
+ return nt_status;
}
- ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+ nt_status = pdb_fill_sam_pw(user, pass);
passwd_free(&pass);
- return ret;
+ return nt_status;
}
-static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
+static NTSTATUS unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
{
uint32 rid;
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
return unixsam_getsampwrid(my_methods, user, rid);
}
@@ -90,10 +90,10 @@ static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
Adds an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL unixsam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS unixsam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
{
DEBUG(0,("pdb_unix should not be listed as the first passdb backend! You can't add users to it.\n"));
- return False;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/***************************************************************************
@@ -106,11 +106,31 @@ static BOOL unixsam_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *n
as if the pdb_unix version was modified, but its actually stored somehwere.
****************************************************************************/
-static BOOL unixsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
+static NTSTATUS unixsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
{
return methods->parent->pdb_add_sam_account(methods->parent, newpwd);
}
+static NTSTATUS unixsam_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS unixsam_setsampwent(struct pdb_methods *methods, BOOL update)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static NTSTATUS unixsam_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+static void unixsam_endsampwent(struct pdb_methods *methods)
+{
+ return; /* NT_STATUS_NOT_IMPLEMENTED; */
+}
+
NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
NTSTATUS nt_status;
@@ -126,14 +146,14 @@ NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co
(*pdb_method)->name = "unixsam";
- (*pdb_method)->setsampwent = NULL;
- (*pdb_method)->endsampwent = NULL;
- (*pdb_method)->getsampwent = NULL;
+ (*pdb_method)->setsampwent = unixsam_setsampwent;
+ (*pdb_method)->endsampwent = unixsam_endsampwent;
+ (*pdb_method)->getsampwent = unixsam_getsampwent;
(*pdb_method)->getsampwnam = unixsam_getsampwnam;
(*pdb_method)->getsampwsid = unixsam_getsampwsid;
(*pdb_method)->add_sam_account = unixsam_add_sam_account;
(*pdb_method)->update_sam_account = unixsam_update_sam_account;
- (*pdb_method)->delete_sam_account = NULL;
+ (*pdb_method)->delete_sam_account = unixsam_delete_sam_account;
/* There's not very much to initialise here */
return NT_STATUS_OK;
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 1137993bb6..ddf51fcf0b 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -5470,7 +5470,15 @@ void init_sam_user_info23W(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
+ if (nt_time_is_zero(pass_must_change_time)) {
+ usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
+ } else {
+ usr->passmustchange=0;
+ }
+
+
ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
usr->unknown_5 = unknown_5; /* 0x0001 0000 */
@@ -5558,7 +5566,14 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
usr->ptr_logon_hrs = hrs ? 1 : 0;
+ if (nt_time_is_zero(pass_must_change_time)) {
+ usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
+ } else {
+ usr->passmustchange=0;
+ }
+
ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
usr->unknown_5 = unknown_5; /* 0x0001 0000 */
@@ -5651,11 +5666,18 @@ static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 * usr,
return False;
if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
return False;
+
+ if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
+ return False;
+
if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
return False;
- if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
+ if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
+ return False;
+ if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
return False;
+
if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
return False;
@@ -5905,7 +5927,15 @@ void init_sam_user_info21W(SAM_USER_INFO_21 * usr,
usr->ptr_logon_hrs = hrs ? 1 : 0;
usr->unknown_5 = unknown_5; /* 0x0002 0000 */
+ if (nt_time_is_zero(pass_must_change_time)) {
+ usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
+ } else {
+ usr->passmustchange=0;
+ }
+
+
ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
copy_unistr2(&usr->uni_user_name, user_name);
copy_unistr2(&usr->uni_full_name, full_name);
@@ -6037,7 +6067,15 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
usr->ptr_logon_hrs = pdb_get_hours(pw) ? 1 : 0;
usr->unknown_5 = pdb_get_unknown5(pw); /* 0x0002 0000 */
+ if (pdb_get_pass_must_change_time(pw) == 0) {
+ usr->passmustchange=PASS_MUST_CHANGE_AT_NEXT_LOGON;
+ } else {
+ usr->passmustchange=0;
+ }
+
+
ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
init_unistr2(&usr->uni_user_name, user_name, len_user_name);
init_unistr2(&usr->uni_full_name, full_name, len_full_name);
@@ -6132,11 +6170,16 @@ static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 * usr,
return False;
if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
return False;
+
if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
return False;
if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
return False;
+ if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
+ return False;
+ if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
+ return False;
/* here begins pointed-to data */
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index ea631838da..c5a2c54511 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -2802,8 +2802,6 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
acct_ctrl = pdb_get_acct_ctrl(pwd);
- copy_id23_to_sam_passwd(pwd, id23);
-
if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len)) {
pdb_free_sam(&pwd);
return False;
@@ -2814,6 +2812,8 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
return False;
}
+ copy_id23_to_sam_passwd(pwd, id23);
+
/* if it's a trust account, don't update /etc/passwd */
if ( (!IS_SAM_UNIX_USER(pwd)) ||
( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
@@ -3059,6 +3059,10 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
struct samr_info *info = NULL;
int i,j;
+
+ NTSTATUS ntstatus1;
+ NTSTATUS ntstatus2;
+
/* until i see a real useraliases query, we fack one up */
/* I have seen one, JFM 2/12/2001 */
@@ -3084,9 +3088,15 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, USER_ACCESS_GET_GROUPS, "_samr_query_useraliases"))) {
- return r_u->status;
- }
+ ntstatus1 = access_check_samr_function(info->acc_granted, DOMAIN_ACCESS_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
+ ntstatus2 = access_check_samr_function(info->acc_granted, DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_query_useraliases");
+
+ if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
+ if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
+ !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
+ return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
+ }
+ }
if (!sid_check_is_domain(&info->sid) &&
!sid_check_is_builtin(&info->sid))
@@ -3157,7 +3167,8 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_
if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, ALIAS_ACCESS_GET_MEMBERS, "_samr_query_aliasmem"))) {
+ if (!NT_STATUS_IS_OK(r_u->status =
+ access_check_samr_function(acc_granted, ALIAS_ACCESS_GET_MEMBERS, "_samr_query_aliasmem"))) {
return r_u->status;
}
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 7a5b1e5f46..18297056d6 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -1,10 +1,11 @@
/*
Unix SMB/CIFS implementation.
SAMR Pipe utility functions.
- Copyright (C) Jeremy Allison 1996-2001
+
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
Copyright (C) Andrew Bartlett 2001-2002
+ Copyright (C) Stefan (metze) Metzmacher 2002
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
@@ -26,118 +27,385 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+#define STRING_CHANGED (old_string && !new_string) ||\
+ (!old_string && new_string) ||\
+ (old_string && new_string && (strcmp(old_string, new_string) != 0))
+
/*************************************************************
- Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
- **************************************************************/
+ Copies a SAM_USER_INFO_21 to a SAM_ACCOUNT
+**************************************************************/
-void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
+void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
{
+ time_t unix_time, stored_time;
+ const char *old_string, *new_string;
if (from == NULL || to == NULL)
return;
+ if (!nt_time_is_zero(&from->logon_time)) {
+ unix_time=nt_time_to_unix(&from->logon_time);
+ stored_time = pdb_get_logon_time(to);
+ DEBUG(10,("INFO_21 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_logon_time(to, unix_time, True);
+ }
+ if (!nt_time_is_zero(&from->logoff_time)) {
+ unix_time=nt_time_to_unix(&from->logoff_time);
+ stored_time = pdb_get_logoff_time(to);
+ DEBUG(10,("INFO_21 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_logoff_time(to, unix_time, True);
+ }
+
+ if (!nt_time_is_zero(&from->kickoff_time)) {
+ unix_time=nt_time_to_unix(&from->kickoff_time);
+ stored_time = pdb_get_kickoff_time(to);
+ DEBUG(10,("INFO_21 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_kickoff_time(to, unix_time , True);
+ }
- pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
- pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
- pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
- pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
- pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
- pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
-
- if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
- if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
- if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
- if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
- if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
- if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
- if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
- if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
- if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
- if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
-
- if (from->user_rid)
- pdb_set_user_sid_from_rid(to, from->user_rid);
- if (from->group_rid)
- pdb_set_group_sid_from_rid(to, from->group_rid);
+ if (!nt_time_is_zero(&from->pass_can_change_time)) {
+ unix_time=nt_time_to_unix(&from->pass_can_change_time);
+ stored_time = pdb_get_pass_can_change_time(to);
+ DEBUG(10,("INFO_21 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_can_change_time(to, unix_time, True);
+ }
+ if (!nt_time_is_zero(&from->pass_last_set_time)) {
+ unix_time=nt_time_to_unix(&from->pass_last_set_time);
+ stored_time = pdb_get_pass_last_set_time(to);
+ DEBUG(10,("INFO_21 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_last_set_time(to, unix_time);
+ }
+
+ if (!nt_time_is_zero(&from->pass_must_change_time)) {
+ unix_time=nt_time_to_unix(&from->pass_must_change_time);
+ stored_time=pdb_get_pass_must_change_time(to);
+ DEBUG(10,("INFO_21 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_must_change_time(to, unix_time, True);
+ }
+
+ /* Backend should check this for sainity */
+ if (from->hdr_user_name.buffer) {
+ old_string = pdb_get_username(to);
+ new_string = pdb_unistr2_convert(&from->uni_user_name);
+ DEBUG(10,("INFO_21 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_username(to , new_string);
+ }
+
+ if (from->hdr_full_name.buffer) {
+ old_string = pdb_get_fullname(to);
+ new_string = pdb_unistr2_convert(&from->uni_user_name);
+ DEBUG(10,("INFO_21 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_fullname(to , new_string);
+ }
+
+ if (from->hdr_home_dir.buffer) {
+ old_string = pdb_get_homedir(to);
+ new_string = pdb_unistr2_convert(&from->uni_home_dir);
+ DEBUG(10,("INFO_21 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_homedir(to , new_string, True);
+ }
+
+ if (from->hdr_dir_drive.buffer) {
+ old_string = pdb_get_dir_drive(to);
+ new_string = pdb_unistr2_convert(&from->uni_dir_drive);
+ DEBUG(10,("INFO_21 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_dir_drive(to , new_string, True);
+ }
+ if (from->hdr_logon_script.buffer) {
+ old_string = pdb_get_logon_script(to);
+ new_string = pdb_unistr2_convert(&from->uni_logon_script);
+ DEBUG(10,("INFO_21 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_logon_script(to , new_string, True);
+ }
+
+ if (from->hdr_profile_path.buffer) {
+ old_string = pdb_get_profile_path(to);
+ new_string = pdb_unistr2_convert(&from->uni_profile_path);
+ DEBUG(10,("INFO_21 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_profile_path(to , new_string, True);
+ }
+
+ if (from->hdr_acct_desc.buffer) {
+ old_string = pdb_get_acct_desc(to);
+ new_string = pdb_unistr2_convert(&from->uni_acct_desc);
+ DEBUG(10,("INFO_21 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_acct_desc(to , new_string);
+ }
+
+ if (from->hdr_workstations.buffer) {
+ old_string = pdb_get_workstations(to);
+ new_string = pdb_unistr2_convert(&from->uni_workstations);
+ DEBUG(10,("INFO_21 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_workstations(to , new_string);
+ }
+
+ if (from->hdr_unknown_str.buffer) {
+ old_string = pdb_get_unknown_str(to);
+ new_string = pdb_unistr2_convert(&from->uni_unknown_str);
+ DEBUG(10,("INFO_21 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_unknown_str(to , new_string);
+ }
+
+ if (from->hdr_munged_dial.buffer) {
+ old_string = pdb_get_munged_dial(to);
+ new_string = pdb_unistr2_convert(&from->uni_munged_dial);
+ DEBUG(10,("INFO_21 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_munged_dial(to , new_string);
+ }
+
+ if (from->user_rid) {
+ DEBUG(10,("INFO_21 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
+ /* we really allow this ??? metze */
+ /* pdb_set_user_sid_from_rid(to, from->user_rid);*/
+ }
+
+ if (from->group_rid) {
+ DEBUG(10,("INFO_21 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
+ pdb_set_group_sid_from_rid(to, from->group_rid);
+ }
+
+ DEBUG(10,("INFO_21 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
pdb_set_acct_ctrl(to, from->acb_info);
+
+ DEBUG(10,("INFO_21 UNKOWN_3: %08X -> %08X\n",pdb_get_unknown3(to),from->unknown_3));
pdb_set_unknown_3(to, from->unknown_3);
+
+ DEBUG(15,("INFO_21 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
pdb_set_logon_divs(to, from->logon_divs);
+
+ DEBUG(15,("INFO_21 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
pdb_set_hours_len(to, from->logon_hrs.len);
+ DEBUG(15,("INFO_21 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
pdb_set_hours(to, from->logon_hrs.hours);
+ DEBUG(10,("INFO_21 UNKOWN_5: %08X -> %08X\n",pdb_get_unknown5(to),from->unknown_5));
pdb_set_unknown_5(to, from->unknown_5);
+
+ DEBUG(10,("INFO_21 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown6(to),from->unknown_6));
pdb_set_unknown_6(to, from->unknown_6);
+
+ DEBUG(10,("INFO_21 PADDING1 %02X %02X %02X %02X %02X %02X\n",
+ from->padding1[0],
+ from->padding1[1],
+ from->padding1[2],
+ from->padding1[3],
+ from->padding1[4],
+ from->padding1[5]));
+
+ DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_must_change_time(to,0, True);
+ }
+
+ DEBUG(10,("INFO_21 PADDING_2: %02X\n",from->padding2));
+
+ DEBUG(10,("INFO_21 PADDING_4: %08X\n",from->padding4));
}
/*************************************************************
- Copies a sam passwd.
- **************************************************************/
+ Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
+**************************************************************/
-void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
+void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
{
+ time_t unix_time, stored_time;
+ const char *old_string, *new_string;
+
if (from == NULL || to == NULL)
return;
+ if (!nt_time_is_zero(&from->logon_time)) {
+ unix_time=nt_time_to_unix(&from->logon_time);
+ stored_time = pdb_get_logon_time(to);
+ DEBUG(10,("INFO_23 LOGON_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_logon_time(to, unix_time, True);
+ }
+ if (!nt_time_is_zero(&from->logoff_time)) {
+ unix_time=nt_time_to_unix(&from->logoff_time);
+ stored_time = pdb_get_logoff_time(to);
+ DEBUG(10,("INFO_23 LOGOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_logoff_time(to, unix_time, True);
+ }
+
+ if (!nt_time_is_zero(&from->kickoff_time)) {
+ unix_time=nt_time_to_unix(&from->kickoff_time);
+ stored_time = pdb_get_kickoff_time(to);
+ DEBUG(10,("INFO_23 KICKOFF_TIME: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_kickoff_time(to, unix_time , True);
+ }
- pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
- pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
- pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
- pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
- pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
- pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
-
- if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
- if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
- if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
- if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
- if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
- if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
- if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
- if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
- if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
- if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
-
- if (from->user_rid)
- pdb_set_user_sid_from_rid(to, from->user_rid);
- if (from->group_rid)
- pdb_set_group_sid_from_rid(to, from->group_rid);
+ if (!nt_time_is_zero(&from->pass_can_change_time)) {
+ unix_time=nt_time_to_unix(&from->pass_can_change_time);
+ stored_time = pdb_get_pass_can_change_time(to);
+ DEBUG(10,("INFO_23 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_can_change_time(to, unix_time, True);
+ }
+ if (!nt_time_is_zero(&from->pass_last_set_time)) {
+ unix_time=nt_time_to_unix(&from->pass_last_set_time);
+ stored_time = pdb_get_pass_last_set_time(to);
+ DEBUG(10,("INFO_23 PASS_LAST_SET: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_last_set_time(to, unix_time);
+ }
+
+ if (!nt_time_is_zero(&from->pass_must_change_time)) {
+ unix_time=nt_time_to_unix(&from->pass_must_change_time);
+ stored_time=pdb_get_pass_must_change_time(to);
+ DEBUG(10,("INFO_23 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_must_change_time(to, unix_time, True);
+ }
+
+ /* Backend should check this for sainity */
+ if (from->hdr_user_name.buffer) {
+ old_string = pdb_get_username(to);
+ new_string = pdb_unistr2_convert(&from->uni_user_name);
+ DEBUG(10,("INFO_23 UNI_USER_NAME: %s -> %s\n", old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_username(to , new_string);
+ }
+
+ if (from->hdr_full_name.buffer) {
+ old_string = pdb_get_fullname(to);
+ new_string = pdb_unistr2_convert(&from->uni_user_name);
+ DEBUG(10,("INFO_23 UNI_FULL_NAME: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_fullname(to , new_string);
+ }
+
+ if (from->hdr_home_dir.buffer) {
+ old_string = pdb_get_homedir(to);
+ new_string = pdb_unistr2_convert(&from->uni_home_dir);
+ DEBUG(10,("INFO_23 UNI_HOME_DIR: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_homedir(to , new_string, True);
+ }
+
+ if (from->hdr_dir_drive.buffer) {
+ old_string = pdb_get_dir_drive(to);
+ new_string = pdb_unistr2_convert(&from->uni_dir_drive);
+ DEBUG(10,("INFO_23 UNI_DIR_DRIVE: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_dir_drive(to , new_string, True);
+ }
- /* FIXME!! Do we need to copy the passwords here as well?
- I don't know. Need to figure this out --jerry */
+ if (from->hdr_logon_script.buffer) {
+ old_string = pdb_get_logon_script(to);
+ new_string = pdb_unistr2_convert(&from->uni_logon_script);
+ DEBUG(10,("INFO_23 UNI_LOGON_SCRIPT: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_logon_script(to , new_string, True);
+ }
- /* Passwords dealt with in caller --abartlet */
+ if (from->hdr_profile_path.buffer) {
+ old_string = pdb_get_profile_path(to);
+ new_string = pdb_unistr2_convert(&from->uni_profile_path);
+ DEBUG(10,("INFO_23 UNI_PROFILE_PATH: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_profile_path(to , new_string, True);
+ }
+
+ if (from->hdr_acct_desc.buffer) {
+ old_string = pdb_get_acct_desc(to);
+ new_string = pdb_unistr2_convert(&from->uni_acct_desc);
+ DEBUG(10,("INFO_23 UNI_ACCT_DESC: %s -> %s\n",old_string,new_string));
+ if (STRING_CHANGED)
+ pdb_set_acct_desc(to , new_string);
+ }
+
+ if (from->hdr_workstations.buffer) {
+ old_string = pdb_get_workstations(to);
+ new_string = pdb_unistr2_convert(&from->uni_workstations);
+ DEBUG(10,("INFO_23 UNI_WORKSTATIONS: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_workstations(to , new_string);
+ }
+ if (from->hdr_unknown_str.buffer) {
+ old_string = pdb_get_unknown_str(to);
+ new_string = pdb_unistr2_convert(&from->uni_unknown_str);
+ DEBUG(10,("INFO_23 UNI_UNKNOWN_STR: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_unknown_str(to , new_string);
+ }
+
+ if (from->hdr_munged_dial.buffer) {
+ old_string = pdb_get_munged_dial(to);
+ new_string = pdb_unistr2_convert(&from->uni_munged_dial);
+ DEBUG(10,("INFO_23 UNI_MUNGED_DIAL: %s -> %s\n",old_string, new_string));
+ if (STRING_CHANGED)
+ pdb_set_munged_dial(to , new_string);
+ }
+
+ if (from->user_rid) {
+ DEBUG(10,("INFO_23 USER_RID: %u -> %u NOT UPDATED!\n",pdb_get_user_rid(to),from->user_rid));
+ /* we really allow this ??? metze */
+ /* pdb_set_user_sid_from_rid(to, from->user_rid);*/
+ }
+
+ if (from->group_rid) {
+ DEBUG(10,("INFO_23 GROUP_RID: %u -> %u\n",pdb_get_group_rid(to),from->group_rid));
+ pdb_set_group_sid_from_rid(to, from->group_rid);
+ }
+
+ DEBUG(10,("INFO_23 ACCT_CTRL: %08X -> %08X\n",pdb_get_acct_ctrl(to),from->acb_info));
pdb_set_acct_ctrl(to, from->acb_info);
+
+ DEBUG(10,("INFO_23 UNKOWN_3: %08X -> %08X\n",pdb_get_unknown3(to),from->unknown_3));
pdb_set_unknown_3(to, from->unknown_3);
+
+ DEBUG(15,("INFO_23 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
pdb_set_logon_divs(to, from->logon_divs);
+
+ DEBUG(15,("INFO_23 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
pdb_set_hours_len(to, from->logon_hrs.len);
+ DEBUG(15,("INFO_23 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
pdb_set_hours(to, from->logon_hrs.hours);
+ DEBUG(10,("INFO_23 UNKOWN_5: %08X -> %08X\n",pdb_get_unknown5(to),from->unknown_5));
pdb_set_unknown_5(to, from->unknown_5);
+
+ DEBUG(10,("INFO_23 UNKOWN_6: %08X -> %08X\n",pdb_get_unknown6(to),from->unknown_6));
pdb_set_unknown_6(to, from->unknown_6);
+
+ DEBUG(10,("INFO_23 PADDING1 %02X %02X %02X %02X %02X %02X\n",
+ from->padding1[0],
+ from->padding1[1],
+ from->padding1[2],
+ from->padding1[3],
+ from->padding1[4],
+ from->padding1[5]));
+
+ DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_must_change_time(to,0, True);
+ }
+
+ DEBUG(10,("INFO_23 PADDING_2: %02X\n",from->padding2));
+
+ DEBUG(10,("INFO_23 PADDING_4: %08X\n",from->padding4));
}
+
diff --git a/source3/sam/interface.c b/source3/sam/interface.c
index bb7b88b240..0943a0e8f1 100644
--- a/source3/sam/interface.c
+++ b/source3/sam/interface.c
@@ -317,6 +317,7 @@ NTSTATUS context_sam_lookup_domain(const SAM_CONTEXT *context, const NT_USER_TOK
while (tmp_methods) {
if (strcmp(domain, tmp_methods->domain_name) == 0) {
+ (*domainsid) = (DOM_SID *)malloc(sizeof(DOM_SID));
sid_copy((*domainsid), &tmp_methods->domain_sid);
return NT_STATUS_OK;
}
@@ -904,7 +905,7 @@ void free_sam_context(SAM_CONTEXT **context)
}
/******************************************************************
- Make a sam_methods from scratch
+ Make a backend_entry from scratch
*******************************************************************/
static NTSTATUS make_backend_entry(SAM_BACKEND_ENTRY *backend_entry, char *sam_backend_string)
@@ -1175,8 +1176,6 @@ NTSTATUS make_sam_context(SAM_CONTEXT **context)
(*context)->mem_ctx = mem_ctx;
- /* FIXME */
-
(*context)->free_fn = free_sam_context;
return NT_STATUS_OK;
diff --git a/source3/torture/cmd_sam.c b/source3/torture/cmd_sam.c
index 3ebf91434e..3d4725c8a8 100644
--- a/source3/torture/cmd_sam.c
+++ b/source3/torture/cmd_sam.c
@@ -22,6 +22,30 @@
#include "includes.h"
#include "samtest.h"
+static NTSTATUS cmd_context(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
+{
+ NTSTATUS status;
+ char **plugins;
+ int i;
+
+ plugins = malloc(argc * sizeof(char *));
+
+ for(i = 1; i < argc; i++)
+ plugins[i-1] = argv[i];
+
+ plugins[argc-1] = NULL;
+
+ if(!NT_STATUS_IS_OK(status = make_sam_context_list(&st->context, plugins))) {
+ printf("make_sam_context_list failed: %s\n", nt_errstr(status));
+ SAFE_FREE(plugins);
+ return status;
+ }
+
+ SAFE_FREE(plugins);
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS cmd_load_module(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
char *plugin_arg[2];
@@ -148,6 +172,11 @@ static NTSTATUS cmd_enum_domains(struct samtest_state *st, TALLOC_CTX *mem_ctx,
return status;
}
+ if (domain_count == 0) {
+ printf("No domains found!\n");
+ return NT_STATUS_OK;
+ }
+
for (i = 0; i < domain_count; i++) {
printf("%s %s\n", domain_names[i], sid_string_static(&domain_sids[i]));
}
@@ -165,7 +194,115 @@ static NTSTATUS cmd_update_domain(struct samtest_state *st, TALLOC_CTX *mem_ctx,
static NTSTATUS cmd_show_domain(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ NTSTATUS status;
+ DOM_SID sid;
+ SAM_DOMAIN_HANDLE *domain;
+ uint32 tmp_uint32;
+ uint16 tmp_uint16;
+ NTTIME tmp_nttime;
+ BOOL tmp_bool;
+ const char *tmp_string;
+
+ if (argc != 2) {
+ printf("Usage: show_domain <sid>\n");
+ return status;
+ }
+
+ if (!string_to_sid(&sid, argv[1])){
+ printf("Unparseable SID specified!\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!NT_STATUS_IS_OK(status = context_sam_get_domain_by_sid(st->context, st->token, DOMAIN_ALL_ACCESS, &sid, &domain))) {
+ printf("context_sam_get_domain_by_sid failed\n");
+ return status;
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_num_accounts(domain, &tmp_uint32))) {
+ printf("sam_get_domain_num_accounts failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Number of accounts: %d\n", tmp_uint32);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_num_groups(domain, &tmp_uint32))) {
+ printf("sam_get_domain_num_groups failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Number of groups: %d\n", tmp_uint32);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_num_aliases(domain, &tmp_uint32))) {
+ printf("sam_get_domain_num_aliases failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Number of aliases: %d\n", tmp_uint32);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_name(domain, &tmp_string))) {
+ printf("sam_get_domain_name failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Domain Name: %s\n", tmp_string);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_lockout_count(domain, &tmp_uint16))) {
+ printf("sam_get_domain_lockout_count failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Lockout Count: %d\n", tmp_uint16);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_force_logoff(domain, &tmp_bool))) {
+ printf("sam_get_domain_force_logoff failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Force Logoff: %s\n", (tmp_bool?"Yes":"No"));
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_lockout_duration(domain, &tmp_nttime))) {
+ printf("sam_get_domain_lockout_duration failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Lockout duration: %d\n", tmp_nttime.low);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_login_pwdchange(domain, &tmp_bool))) {
+ printf("sam_get_domain_login_pwdchange failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Password changing allowed: %s\n", (tmp_bool?"Yes":"No"));
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_max_pwdage(domain, &tmp_nttime))) {
+ printf("sam_get_domain_max_pwdage failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Maximum password age: %d\n", tmp_nttime.low);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_min_pwdage(domain, &tmp_nttime))) {
+ printf("sam_get_domain_min_pwdage failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Minimal password age: %d\n", tmp_nttime.low);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_min_pwdlength(domain, &tmp_uint16))) {
+ printf("sam_get_domain_min_pwdlength: %s\n", nt_errstr(status));
+ } else {
+ printf("Minimal Password Length: %d\n", tmp_uint16);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_pwd_history(domain, &tmp_uint16))) {
+ printf("sam_get_domain_pwd_history failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Password history: %d\n", tmp_uint16);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_reset_count(domain, &tmp_nttime))) {
+ printf("sam_get_domain_reset_count failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Reset count: %d\n", tmp_nttime.low);
+ }
+
+ if (!NT_STATUS_IS_OK(status = sam_get_domain_server(domain, &tmp_string))) {
+ printf("sam_get_domain_server failed: %s\n", nt_errstr(status));
+ } else {
+ printf("Server: %s\n", tmp_string);
+ }
+
+ return NT_STATUS_OK;
}
static NTSTATUS cmd_create_account(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
@@ -185,7 +322,40 @@ static NTSTATUS cmd_delete_account(struct samtest_state *st, TALLOC_CTX *mem_ctx
static NTSTATUS cmd_enum_accounts(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ NTSTATUS status;
+ DOM_SID sid;
+ int32 account_count, i;
+ SAM_ACCOUNT_ENUM *accounts;
+
+ if (argc != 2) {
+ printf("Usage: enum_accounts <domain-sid>\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!string_to_sid(&sid, argv[1])){
+ printf("Unparseable SID specified!\n");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!NT_STATUS_IS_OK(status = context_sam_enum_accounts(st->context, st->token, &sid, 0, &account_count, &accounts))) {
+ printf("context_sam_enum_accounts failed: %s\n", nt_errstr(status));
+ return status;
+ }
+
+ if (account_count == 0) {
+ printf("No accounts found!\n");
+ return NT_STATUS_OK;
+ }
+
+ for (i = 0; i < account_count; i++)
+ printf("%s\t%s\t%s\t%s\t%d\n",
+ sid_string_static(&accounts[i].sid), accounts[i].account_name,
+ accounts[i].full_name, accounts[i].account_desc,
+ accounts[i].acct_ctrl);
+
+ SAFE_FREE(accounts);
+
+ return NT_STATUS_OK;
}
static NTSTATUS cmd_lookup_account_sid(struct samtest_state *st, TALLOC_CTX *mem_ctx, int argc, char **argv)
@@ -255,6 +425,7 @@ struct cmd_set sam_general_commands[] = {
{ "General SAM Commands" },
{ "load", cmd_load_module, "Load a module", "load <module.so> [domain-sid]" },
+ { "context", cmd_context, "Load specified context", "context [DOMAIN|]backend1[:options] [DOMAIN|]backend2[:options]" },
{ "get_sec_desc", cmd_get_sec_desc, "Get security descriptor info", "get_sec_desc <access-token> <sid>" },
{ "set_sec_desc", cmd_set_sec_desc, "Set security descriptor info", "set_sec_desc <access-token> <sid>" },
{ "lookup_sid", cmd_lookup_sid, "Lookup type of specified SID", "lookup_sid <sid>" },
diff --git a/source3/utils/smbgroupedit.c b/source3/utils/smbgroupedit.c
index 4358e6f08c..cf5ac1f025 100644
--- a/source3/utils/smbgroupedit.c
+++ b/source3/utils/smbgroupedit.c
@@ -86,28 +86,17 @@ static BOOL get_sid_from_input(DOM_SID *sid, char *input)
/*********************************************************
add a group.
**********************************************************/
-static int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege)
+static int addgroup(gid_t gid, enum SID_NAME_USE sid_type, char *ntgroup, char *ntcomment, char *privilege, uint32 rid)
{
PRIVILEGE_SET se_priv;
- gid_t gid;
DOM_SID sid;
fstring string_sid;
- fstring name, comment;
-
- gid=nametogid(group);
- if (gid==-1) {
- printf("unix group %s doesn't exist!\n", group);
- return -1;
- }
+ fstring comment;
- local_gid_to_sid(&sid, gid);
-
- sid_to_string(string_sid, &sid);
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
- if (ntgroup==NULL)
- fstrcpy(name, group);
- else
- fstrcpy(name, ntgroup);
+ sid_to_string(string_sid, &sid);
if (ntcomment==NULL)
fstrcpy(comment, "Local Unix group");
@@ -118,8 +107,9 @@ static int addgroup(char *group, enum SID_NAME_USE sid_type, char *ntgroup, char
if (privilege!=NULL)
convert_priv_from_text(&se_priv, privilege);
- if(!add_initial_entry(gid, string_sid, sid_type, name, comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
- printf("adding entry for group %s failed!\n", group);
+ if(!add_initial_entry(gid, string_sid, sid_type, ntgroup,
+ comment, se_priv, PR_ACCESS_FROM_NETWORK)) {
+ printf("adding entry for group %s failed!\n", ntgroup);
free_privilege(&se_priv);
return -1;
}
@@ -276,6 +266,7 @@ int main (int argc, char **argv)
char *group_desc = NULL;
enum SID_NAME_USE sid_type;
+ uint32 rid = -1;
setup_logging("groupedit", True);
@@ -312,7 +303,7 @@ int main (int argc, char **argv)
return 0;
}
- while ((ch = getopt(argc, argv, "a:c:d:ln:p:st:u:vx:")) != EOF) {
+ while ((ch = getopt(argc, argv, "a:c:d:ln:p:r:st:u:vx:")) != EOF) {
switch(ch) {
case 'a':
add_group = True;
@@ -336,6 +327,9 @@ int main (int argc, char **argv)
priv = True;
privilege=optarg;
break;
+ case 'r':
+ rid = atoi(optarg);
+ break;
case 's':
long_list = False;
break;
@@ -392,8 +386,19 @@ int main (int argc, char **argv)
}
}
- if (add_group)
- return addgroup(group, sid_type, ntgroup, group_desc, privilege);
+ if (add_group) {
+ gid_t gid=nametogid(group);
+ if (gid==-1) {
+ printf("unix group %s doesn't exist!\n", group);
+ return -1;
+ }
+
+ if (rid == -1) {
+ rid = pdb_gid_to_group_rid(gid);
+ }
+ return addgroup(gid, sid_type, ntgroup?ntgroup:group,
+ group_desc, privilege, rid);
+ }
if (view_group)
return listgroup(sid_type, long_list);