diff --git a/lib/param/param.h b/lib/param/param.h index 680c053a6cc..0a3bde6c5cb 100644 --- a/lib/param/param.h +++ b/lib/param/param.h @@ -289,7 +289,8 @@ const char *lpcfg_imessaging_path(TALLOC_CTX *mem_ctx, const char *lpcfg_sam_name(struct loadparm_context *lp_ctx); const char *lpcfg_sam_dnsname(struct loadparm_context *lp_ctx); -void lpcfg_default_kdc_policy(struct loadparm_context *lp_ctx, +void lpcfg_default_kdc_policy(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, time_t *svc_tkt_lifetime, time_t *usr_tkt_lifetime, time_t *renewal_lifetime); diff --git a/lib/param/util.c b/lib/param/util.c index 52796562ec5..cd8e74b9d8f 100644 --- a/lib/param/util.c +++ b/lib/param/util.c @@ -29,6 +29,7 @@ #include "system/dir.h" #include "param/param.h" #include "libds/common/roles.h" +#include "tdb.h" /** * @file @@ -270,22 +271,56 @@ const char *lpcfg_sam_dnsname(struct loadparm_context *lp_ctx) } } -void lpcfg_default_kdc_policy(struct loadparm_context *lp_ctx, +static long tdb_fetch_lifetime(TALLOC_CTX *mem_ctx, struct tdb_context *tdb, const char *keystr) +{ + TDB_DATA key; + TDB_DATA ret; + char *tmp = NULL; + long result; + + key.dptr = discard_const_p(unsigned char, keystr); + key.dsize = strlen(keystr); + + if (!key.dptr) + return -1; + + ret = tdb_fetch(tdb, key); + if (ret.dsize == 0) + return -1; + + tmp = talloc_realloc(mem_ctx, tmp, char, ret.dsize+1); + memset(tmp, 0, ret.dsize+1); + memcpy(tmp, ret.dptr, ret.dsize); + free(ret.dptr); + + result = atol(tmp); + talloc_free(tmp); + return result; +} + +void lpcfg_default_kdc_policy(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, time_t *svc_tkt_lifetime, time_t *usr_tkt_lifetime, time_t *renewal_lifetime) { long val; + TDB_CONTEXT *ctx = NULL; + const char *kdc_tdb = NULL; - val = lpcfg_parm_long(lp_ctx, NULL, - "kdc", "service ticket lifetime", 10); + kdc_tdb = lpcfg_cache_path(mem_ctx, lp_ctx, "gpo.tdb"); + if (kdc_tdb) + ctx = tdb_open(kdc_tdb, 0, TDB_DEFAULT, O_RDWR, 0600); + + if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:service_ticket_lifetime") ) == -1 ) + val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "service ticket lifetime", 10); *svc_tkt_lifetime = val * 60 * 60; - val = lpcfg_parm_long(lp_ctx, NULL, - "kdc", "user ticket lifetime", 10); + if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:user_ticket_lifetime") ) == -1 ) + val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "user ticket lifetime", 10); *usr_tkt_lifetime = val * 60 * 60; - val = lpcfg_parm_long(lp_ctx, NULL, - "kdc", "renewal lifetime", 24 * 7); + if (!ctx || ( val = tdb_fetch_lifetime(mem_ctx, ctx, "kdc:renewal_lifetime") ) == -1 ) + val = lpcfg_parm_long(lp_ctx, NULL, "kdc", "renewal lifetime", 24 * 7); *renewal_lifetime = val * 60 * 60; } diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py index a73cde4c379..b13c117dd2d 100644 --- a/python/samba/gpclass.py +++ b/python/samba/gpclass.py @@ -304,6 +304,32 @@ class inf_to(): def __str__(self): pass +class inf_to_kdc_tdb(inf_to): + def mins_to_hours(self): + return '%d' % (int(self.val)/60) + + def days_to_hours(self): + return '%d' % (int(self.val)*24) + + def set_kdc_tdb(self, val): + old_val = self.gp_db.gpostore.get(self.attribute) + self.logger.info('%s was changed from %s to %s' % (self.attribute, old_val, val)) + if val is not None: + self.gp_db.gpostore.store(self.attribute, val) + self.gp_db.store(str(self), self.attribute, old_val) + else: + self.gp_db.gpostore.delete(self.attribute) + self.gp_db.delete(str(self), self.attribute) + + def mapper(self): + return { 'kdc:user_ticket_lifetime': (self.set_kdc_tdb, self.explicit), + 'kdc:service_ticket_lifetime': (self.set_kdc_tdb, self.mins_to_hours), + 'kdc:renewal_lifetime': (self.set_kdc_tdb, self.days_to_hours), + } + + def __str__(self): + return 'Kerberos Policy' + class inf_to_ldb(inf_to): '''This class takes the .inf file parameter (essentially a GPO file mapped to a GUID), hashmaps it to the Samba parameter, which then uses an ldb object to update the @@ -385,7 +411,11 @@ class gp_sec_ext(gp_ext): "MaximumPasswordAge": ("maxPwdAge", inf_to_ldb), "MinimumPasswordLength": ("minPwdLength", inf_to_ldb), "PasswordComplexity": ("pwdProperties", inf_to_ldb), - } + }, + "Kerberos Policy": {"MaxTicketAge": ("kdc:user_ticket_lifetime", inf_to_kdc_tdb), + "MaxServiceAge": ("kdc:service_ticket_lifetime", inf_to_kdc_tdb), + "MaxRenewAge": ("kdc:renewal_lifetime", inf_to_kdc_tdb), + } } def read_inf(self, path, conn): diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index 9ac5a1d38f0..69c54b00c5b 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -2730,7 +2730,8 @@ NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_conte kdc_db_ctx->msg_ctx = base_ctx->msg_ctx; /* get default kdc policy */ - lpcfg_default_kdc_policy(base_ctx->lp_ctx, + lpcfg_default_kdc_policy(mem_ctx, + base_ctx->lp_ctx, &kdc_db_ctx->policy.svc_tkt_lifetime, &kdc_db_ctx->policy.usr_tkt_lifetime, &kdc_db_ctx->policy.renewal_lifetime); diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 3cccd57e793..8b212222bc9 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -4041,7 +4041,8 @@ static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call, DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); } -static void kdc_get_policy(struct loadparm_context *lp_ctx, +static void kdc_get_policy(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, struct smb_krb5_context *smb_krb5_context, struct lsa_DomainInfoKerberos *k) { @@ -4049,12 +4050,10 @@ static void kdc_get_policy(struct loadparm_context *lp_ctx, time_t usr_tkt_lifetime; time_t renewal_lifetime; - /* These should be set and stored via Group Policy, but until then, some defaults are in order */ - /* Our KDC always re-validates the client */ k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT; - lpcfg_default_kdc_policy(lp_ctx, &svc_tkt_lifetime, + lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime, &usr_tkt_lifetime, &renewal_lifetime); unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime); @@ -4103,7 +4102,7 @@ static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *r->out.info = NULL; return NT_STATUS_INTERNAL_ERROR; } - kdc_get_policy(dce_call->conn->dce_ctx->lp_ctx, + kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, smb_krb5_context, k); talloc_free(smb_krb5_context);