diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/bin/.cvsignore | 4 | ||||
-rw-r--r-- | source3/include/passdb.h | 28 | ||||
-rw-r--r-- | source3/include/rpc_samr.h | 102 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 70 | ||||
-rw-r--r-- | source3/passdb/pdb_unix.c | 62 | ||||
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 45 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 23 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_util.c | 420 | ||||
-rw-r--r-- | source3/sam/interface.c | 5 | ||||
-rw-r--r-- | source3/torture/cmd_sam.c | 175 | ||||
-rw-r--r-- | source3/utils/smbgroupedit.c | 47 |
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); |