diff options
-rw-r--r-- | source3/include/passdb.h | 10 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 67 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 79 | ||||
-rw-r--r-- | source3/utils/pdbedit.c | 146 |
4 files changed, 280 insertions, 22 deletions
diff --git a/source3/include/passdb.h b/source3/include/passdb.h index 65e342080e..df7c969633 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -262,7 +262,7 @@ typedef struct sam_trust_passwd { * this SAMBA will load. Increment this if *ANY* changes are made to the interface. */ -#define PASSDB_INTERFACE_VERSION 5 +#define PASSDB_INTERFACE_VERSION 6 typedef struct pdb_context { @@ -352,9 +352,13 @@ typedef struct pdb_context NTSTATUS (*pdb_get_group_uids)(struct pdb_context *context, const DOM_SID *group, uid_t **members, int *num_members); /* trust password functions */ + + NTSTATUS (*pdb_settrustpwent)(struct pdb_context *context); NTSTATUS (*pdb_gettrustpwent)(struct pdb_context *context, SAM_TRUST_PASSWD *trust); + NTSTATUS (*pdb_gettrustpwnam)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const char *dom_name); + NTSTATUS (*pdb_gettrustpwsid)(struct pdb_context *context, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); NTSTATUS (*pdb_add_trust_passwd)(struct pdb_context *context, SAM_TRUST_PASSWD* trust); @@ -467,8 +471,12 @@ typedef struct pdb_methods /* trust password functions */ + NTSTATUS (*settrustpwent)(struct pdb_methods *methods); + NTSTATUS (*gettrustpwent)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust); + NTSTATUS (*gettrustpwnam)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const char *name); + NTSTATUS (*gettrustpwsid)(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid); NTSTATUS (*add_trust_passwd)(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 8307919d10..5679d4a5e8 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -487,6 +487,30 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, num); } +static NTSTATUS context_settrustpwent(struct pdb_context *context) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->settrustpwent(cur_methods); + if (NT_STATUS_IS_OK(ret)) { + context->pdb_methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + static NTSTATUS context_gettrustpwent(struct pdb_context *context, SAM_TRUST_PASSWD *trust) { @@ -502,6 +526,34 @@ static NTSTATUS context_gettrustpwent(struct pdb_context *context, while (cur_methods) { ret = cur_methods->gettrustpwent(cur_methods, trust); + if (!NT_STATUS_IS_ERR(ret)) { + /* prevent from segfaulting when gettrustpwent + was called just to rewind enumeration */ + if (trust) trust->methods = cur_methods; + return ret; + } + cur_methods = cur_methods->next; + } + + return ret; +} + +static NTSTATUS context_gettrustpwnam(struct pdb_context *context, + SAM_TRUST_PASSWD *trust, + const char *name) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + struct pdb_methods *cur_methods; + + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + cur_methods = context->pdb_methods; + + while (cur_methods) { + ret = cur_methods->gettrustpwnam(cur_methods, trust, name); if (NT_STATUS_IS_OK(ret)) { trust->methods = cur_methods; return ret; @@ -786,7 +838,9 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_del_aliasmem = context_del_aliasmem; (*context)->pdb_enum_aliasmem = context_enum_aliasmem; (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships; + (*context)->pdb_settrustpwent = context_settrustpwent; (*context)->pdb_gettrustpwent = context_gettrustpwent; + (*context)->pdb_gettrustpwnam = context_gettrustpwnam; (*context)->pdb_gettrustpwsid = context_gettrustpwsid; (*context)->pdb_add_trust_passwd = context_add_trust_passwd; (*context)->pdb_update_trust_passwd = context_update_trust_passwd; @@ -1261,11 +1315,22 @@ static void pdb_default_endsampwent(struct pdb_methods *methods) return; /* NT_STATUS_NOT_IMPLEMENTED; */ } +static NTSTATUS pdb_default_settrustpwent(struct pdb_methods *methods) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS pdb_default_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust) { return NT_STATUS_NOT_IMPLEMENTED; } +static NTSTATUS pdb_default_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust, + const char* name) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS pdb_default_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust, const DOM_SID* sid) { @@ -1341,7 +1406,9 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->enum_aliasmem = pdb_default_enum_aliasmem; (*methods)->enum_alias_memberships = pdb_default_alias_memberships; + (*methods)->settrustpwent = pdb_default_settrustpwent; (*methods)->gettrustpwent = pdb_default_gettrustpwent; + (*methods)->gettrustpwnam = pdb_default_gettrustpwnam; (*methods)->gettrustpwsid = pdb_default_gettrustpwsid; (*methods)->add_trust_passwd = pdb_default_add_trust_passwd; (*methods)->update_trust_passwd = pdb_default_update_trust_passwd; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 39de791b07..aef088c124 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -699,8 +699,22 @@ static void free_private_data(void **vp) } /** - * Start enumerating through trust passwords (machine and - * interdomain nt/ads) + * Start trust passwords enumeration. This function is a simple + * wrapper for calling gettrustpwent with null pointer passed. + * + * @param methods methods belonging in pdb context (module) + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_settrustpwent(struct pdb_methods *methods) +{ + /* rewind enumeration from beginning */ + return methods->gettrustpwent(methods, NULL); +} + + +/** + * Enumerate across trust passwords (machine and interdomain nt/ads) * * @param methods methods belonging in pdb context (module) * @param trust trust password structure @@ -782,7 +796,7 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS talloc_destroy(mem_ctx); trust->private = t; - return NT_STATUS_OK; + return NT_STATUS_NO_MORE_ENTRIES; } secrets_lock_trust_account_password(lp_workgroup(), False); } else { @@ -793,11 +807,55 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS /* * ADS machine trust password (TODO) */ + + + /* + * if nothing is to be returned then reset domain name + * and return "no more entries" + */ + nt_status = NT_STATUS_NO_MORE_ENTRIES; + trust->private.uni_name_len = 0; + trust->private.uni_name[t.uni_name_len] = 0; talloc_destroy(mem_ctx); return nt_status; } + +/** + * Get trust password by trusted party name + * + * @param methods methods belonging to pdb context (module) + * @param trust trust password structure + * @param sid trusted party name + * + * @return nt status of performed operation + **/ + +static NTSTATUS tdbsam_gettrustpwnam(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, + const char *name) +{ + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + char domain_name[32]; + + if (!methods || !trust || !name) return nt_status; + + do { + /* get trust password (next in turn) */ + nt_status = tdbsam_gettrustpwent(methods, trust); + + /* convert unicode name and do case insensitive compare */ + pull_ucs2(NULL, domain_name, trust->private.uni_name, sizeof(domain_name), + trust->private.uni_name_len, STR_TERMINATE); + if (!StrnCaseCmp(domain_name, name, sizeof(domain_name))) + return NT_STATUS_OK; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + + return nt_status; +} + + /** * Get trust password by trusted party sid * @@ -811,7 +869,18 @@ static NTSTATUS tdbsam_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASS static NTSTATUS tdbsam_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD *trust, const DOM_SID *sid) { - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + + if (!methods || !trust || !sid) return nt_status; + + do { + nt_status = tdbsam_gettrustpwent(methods, trust); + + if (sid_equal(&trust->private.domain_sid, sid)) + return NT_STATUS_OK; + + } while (NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES)); + return nt_status; } @@ -1263,7 +1332,9 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth (*pdb_method)->add_sam_account = tdbsam_add_sam_account; (*pdb_method)->update_sam_account = tdbsam_update_sam_account; (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; + (*pdb_method)->settrustpwent = tdbsam_settrustpwent; (*pdb_method)->gettrustpwent = tdbsam_gettrustpwent; + (*pdb_method)->gettrustpwnam = tdbsam_gettrustpwnam; (*pdb_method)->gettrustpwsid = tdbsam_gettrustpwsid; (*pdb_method)->add_trust_passwd = tdbsam_add_trust_passwd; (*pdb_method)->update_trust_passwd = tdbsam_update_trust_passwd; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index 4178afdaf8..e744f359d3 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -228,6 +228,88 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v return ret; } + + +static int trustpw_flag(const char* flag_name) +{ + const int flag_num = 5; + typedef struct { const char *name; int val; } flag_conv; + flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, + { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, + { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, + { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, + { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; + int i; + + for (i = 0; i < flag_num; i++) { + if (!StrCaseCmp(flags[i].name, flag_name)) { + return flags[i].val; + } + } + + return 0; +} + + +static char* trustpw_flag_name(const int val) +{ + const int flag_num = 5; + typedef struct { const char *name; int val; } flag_conv; + flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, + { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, + { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, + { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, + { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; + int i; + + for (i = 0; i < flag_num; i++) { + if (flags[i].val == val) { + return strdup(flags[i].name); + } + } + + return strdup("unknown flag"); +} + + +static int print_trustpw_info(TALLOC_CTX *mem_ctx, SAM_TRUST_PASSWD *trust, BOOL verbose) +{ + char *dom_name; + if (!mem_ctx || !trust) return -1; + + /* convert unicode domain name to char* */ + if (!pull_ucs2_talloc(mem_ctx, &dom_name, trust->private.uni_name)) return -1; + dom_name[trust->private.uni_name_len] = 0; + + /* different output depending on level of verbosity */ + if (verbose) { + printf("Domain name: %s\n", dom_name); + printf("Domain SID: %s\n", sid_string_static(&trust->private.domain_sid)); + printf("Trust password %s\n", trust->private.pass); + printf("Trust type: %s\n", trustpw_flag_name(trust->private.flags)); + printf("Last modified %s\n", trust->private.mod_time ? http_timestring(trust->private.mod_time) : "0"); + + } else { + printf("%s:%s\n", dom_name, sid_string_static(&trust->private.domain_sid)); + } + + return 0; +} + + +static int print_trust_info(struct pdb_context *in, const char *name, BOOL verbose, BOOL smbpwdstyle) +{ + SAM_TRUST_PASSWD trust; + TALLOC_CTX *mem_ctx = NULL; + + mem_ctx = talloc_init("pdbedit: trust passwords listing"); + + if (NT_STATUS_IS_OK(in->pdb_gettrustpwnam(in, &trust, name))) { + return print_trustpw_info(mem_ctx, &trust, verbose); + } + + return -1; +} /********************************************************* List Users @@ -258,6 +340,46 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd return 0; } +/** + * List trust passwords + * + * @param in initialised pdb context + * @param verbose turn on/off verbose mode + * @param smbpwdstyle ignored here (there was no trust passwords in smbpasswd file) + * @return 0 on success, otherwise failure + **/ + +static int print_trustpw_list(struct pdb_context *in, BOOL verbose, BOOL smbpwdstyle) +{ + SAM_TRUST_PASSWD trust; + TALLOC_CTX *mem_ctx = NULL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + + /* start enumeration and initialise memory context */ + status = in->pdb_settrustpwent(in); + if (NT_STATUS_IS_ERR(status)) return -1; + mem_ctx = talloc_init("pdbedit: trust passwords listing"); + + /* small separation to make it clear these are not regular accounts */ + if (!verbose) printf("---\n"); + + do { + /* fetch next trust password */ + status = in->pdb_gettrustpwent(in, &trust); + + if (trust.private.uni_name_len) { + /* print trust password info */ + if (verbose) printf ("---------------\n"); + print_trustpw_info(mem_ctx, &trust, verbose); + } + + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(status, NT_STATUS_OK)); + + talloc_destroy(mem_ctx); + return 0; +} + + /********************************************************* Fix a list of Users for uninitialised passwords **********************************************************/ @@ -573,14 +695,6 @@ static int new_trustdom(struct pdb_context *in, const char *dom_name) static int new_trustpw(struct pdb_context *in, const char *dom_name, const char *dom_sid, const char* flag) { - const int flag_num = 5; - typedef struct { const char *name; int val; } flag_conv; - flag_conv flags[] = {{ "PASS_MACHINE_TRUST_NT", PASS_MACHINE_TRUST_NT }, - { "PASS_SERVER_TRUST_NT", PASS_SERVER_TRUST_NT }, - { "PASS_DOMAIN_TRUST_NT", PASS_DOMAIN_TRUST_NT }, - { "PASS_MACHINE_TRUST_ADS",PASS_MACHINE_TRUST_ADS }, - { "PASS_DOMAIN_TRUST_ADS", PASS_DOMAIN_TRUST_ADS }}; - TALLOC_CTX *mem_ctx = NULL; SAM_TRUST_PASSWD trust; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; @@ -591,7 +705,6 @@ static int new_trustpw(struct pdb_context *in, const char *dom_name, struct in_addr srv_ip; fstring srv_name, myname; struct cli_state *cli; - int i; time_t lct; if (!dom_name) return -1; @@ -604,12 +717,7 @@ static int new_trustpw(struct pdb_context *in, const char *dom_name, strncpy_w(trust.private.uni_name, uni_name, 32); /* flags */ - for (i = 0; i < flag_num; i++) { - if (!StrCaseCmp(flags[i].name, flag)) { - trust.private.flags = flags[i].val; - i = flag_num; /* stop comparing */ - } - } + trust.private.flags = trustpw_flag(flag); /* trusting SID */ if (!dom_sid) { @@ -952,10 +1060,14 @@ int main (int argc, char **argv) /* list users operations */ if (checkparms & BIT_LIST) { if (!(checkparms & ~BIT_LIST)) { - return print_users_list (bdef, verbose, spstyle); + print_users_list (bdef, verbose, spstyle); + return print_trustpw_list(bdef, verbose, spstyle); } if (!(checkparms & ~(BIT_USER + BIT_LIST))) { return print_user_info (bdef, user_name, verbose, spstyle); + + } else if (!(checkparms & ~(BIT_TRUSTPW + BIT_LIST))) { + return print_trust_info(bdef, trustpw, verbose, spstyle); } } @@ -1019,7 +1131,7 @@ int main (int argc, char **argv) /* trust password creation */ if (!(checkparms & ~(BIT_CREATE + BIT_TRUSTPW + BIT_TRUSTSID + BIT_TRUSTFLAGS))) { return new_trustpw(bdef, trustpw, trustsid, trustflags); - } + } } |