|
Lines 63-68
struct dlz_bind9_data {
Link Here
|
| 63 |
struct smb_krb5_context *smb_krb5_ctx; |
63 |
struct smb_krb5_context *smb_krb5_ctx; |
| 64 |
struct auth4_context *auth_context; |
64 |
struct auth4_context *auth_context; |
| 65 |
struct auth_session_info *session_info; |
65 |
struct auth_session_info *session_info; |
|
|
66 |
bool is_system_session; |
| 66 |
char *update_name; |
67 |
char *update_name; |
| 67 |
|
68 |
|
| 68 |
/* helper functions from the dlz_dlopen driver */ |
69 |
/* helper functions from the dlz_dlopen driver */ |
|
Lines 736-741
_PUBLIC_ void dlz_destroy(void *dbdata)
Link Here
|
| 736 |
dlz_bind9_state_ref_count--; |
737 |
dlz_bind9_state_ref_count--; |
| 737 |
if (dlz_bind9_state_ref_count == 0) { |
738 |
if (dlz_bind9_state_ref_count == 0) { |
| 738 |
talloc_unlink(state, state->samdb); |
739 |
talloc_unlink(state, state->samdb); |
|
|
740 |
if (state->is_system_session) { |
| 741 |
state->session_info = NULL; |
| 742 |
} |
| 739 |
talloc_free(state); |
743 |
talloc_free(state); |
| 740 |
dlz_bind9_state = NULL; |
744 |
dlz_bind9_state = NULL; |
| 741 |
} |
745 |
} |
|
Lines 1269-1274
static bool b9_is_tombstoned(struct ldb_result *res) {
Link Here
|
| 1269 |
} |
1273 |
} |
| 1270 |
|
1274 |
|
| 1271 |
/* |
1275 |
/* |
|
|
1276 |
* If `name` is a computer account (ends in $) and the records's field matches |
| 1277 |
* the account name (without the $), the account owns the record. |
| 1278 |
*/ |
| 1279 |
static bool b9_account_owns_record(const char *name, struct ldb_result *record) { |
| 1280 |
char *dc = NULL; |
| 1281 |
size_t len = strlen(name); |
| 1282 |
|
| 1283 |
struct ldb_message_element *el = ldb_msg_find_element(record->msgs[0], "dc"); |
| 1284 |
if (el != NULL && el->num_values > 0) { |
| 1285 |
dc = (char *) el->values[0].data; |
| 1286 |
} |
| 1287 |
|
| 1288 |
if (dc != NULL && len > 0 && name[len - 1] == '$') { |
| 1289 |
return strncmp(name, dc, len - 1) == 0; |
| 1290 |
} |
| 1291 |
return false; |
| 1292 |
} |
| 1293 |
|
| 1294 |
/* |
| 1272 |
authorize a zone update |
1295 |
authorize a zone update |
| 1273 |
*/ |
1296 |
*/ |
| 1274 |
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, |
1297 |
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const char *tcpaddr, |
|
Lines 1285-1300
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
Link Here
|
| 1285 |
NTSTATUS nt_status; |
1308 |
NTSTATUS nt_status; |
| 1286 |
struct gensec_security *gensec_ctx; |
1309 |
struct gensec_security *gensec_ctx; |
| 1287 |
struct auth_session_info *session_info; |
1310 |
struct auth_session_info *session_info; |
|
|
1311 |
bool is_system_session = false; |
| 1288 |
struct ldb_dn *dn; |
1312 |
struct ldb_dn *dn; |
| 1289 |
isc_result_t result; |
1313 |
isc_result_t result; |
| 1290 |
struct ldb_result *res; |
1314 |
struct ldb_result *res; |
| 1291 |
const char * attrs[] = { "dNSTombstoned", NULL }; |
1315 |
const char * attrs[] = { "dNSTombstoned", "dc", NULL }; |
| 1292 |
uint32_t access_mask; |
1316 |
uint32_t access_mask; |
| 1293 |
bool is_tombstoned = false; |
1317 |
bool is_tombstoned = false; |
|
|
1318 |
bool owns_record = false; |
| 1294 |
|
1319 |
|
| 1295 |
/* Remove cached credentials, if any */ |
1320 |
/* Remove cached credentials, if any */ |
| 1296 |
if (state->session_info) { |
1321 |
if (state->session_info) { |
| 1297 |
talloc_free(state->session_info); |
1322 |
if (!state->is_system_session) { |
|
|
1323 |
talloc_free(state->session_info); |
| 1324 |
} |
| 1325 |
state->is_system_session = false; |
| 1298 |
state->session_info = NULL; |
1326 |
state->session_info = NULL; |
| 1299 |
} |
1327 |
} |
| 1300 |
if (state->update_name) { |
1328 |
if (state->update_name) { |
|
Lines 1381-1386
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
Link Here
|
| 1381 |
} else if (ldb_ret == LDB_SUCCESS) { |
1409 |
} else if (ldb_ret == LDB_SUCCESS) { |
| 1382 |
access_mask = SEC_STD_REQUIRED | SEC_ADS_SELF_WRITE; |
1410 |
access_mask = SEC_STD_REQUIRED | SEC_ADS_SELF_WRITE; |
| 1383 |
is_tombstoned = b9_is_tombstoned(res); |
1411 |
is_tombstoned = b9_is_tombstoned(res); |
|
|
1412 |
owns_record = b9_account_owns_record(session_info->info->account_name, res); |
| 1384 |
talloc_free(res); |
1413 |
talloc_free(res); |
| 1385 |
} else { |
1414 |
} else { |
| 1386 |
talloc_free(tmp_ctx); |
1415 |
talloc_free(tmp_ctx); |
|
Lines 1412-1417
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
Link Here
|
| 1412 |
session_info->security_token, |
1441 |
session_info->security_token, |
| 1413 |
access_mask, NULL); |
1442 |
access_mask, NULL); |
| 1414 |
} |
1443 |
} |
|
|
1444 |
/* Univention Specific: If a machine tries to access a forward/zone |
| 1445 |
* without the proper access-rights, but the account of the requesting |
| 1446 |
* machine matches the `dc` attribute of the record, a modification is |
| 1447 |
* allowed and the privileges for this operation are escalated to |
| 1448 |
* `SYSTEM`. |
| 1449 |
*/ |
| 1450 |
if (ldb_ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS && owns_record) { |
| 1451 |
session_info = system_session(state->lp); |
| 1452 |
is_system_session = true; |
| 1453 |
ldb_ret = LDB_SUCCESS; |
| 1454 |
} |
| 1415 |
if (ldb_ret != LDB_SUCCESS) { |
1455 |
if (ldb_ret != LDB_SUCCESS) { |
| 1416 |
state->log(ISC_LOG_INFO, |
1456 |
state->log(ISC_LOG_INFO, |
| 1417 |
"samba_dlz: disallowing update of signer=%s name=%s type=%s error=%s", |
1457 |
"samba_dlz: disallowing update of signer=%s name=%s type=%s error=%s", |
|
Lines 1427-1433
_PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
Link Here
|
| 1427 |
talloc_free(tmp_ctx); |
1467 |
talloc_free(tmp_ctx); |
| 1428 |
return ISC_FALSE; |
1468 |
return ISC_FALSE; |
| 1429 |
} |
1469 |
} |
| 1430 |
state->session_info = talloc_steal(state, session_info); |
1470 |
state->is_system_session = is_system_session; |
|
|
1471 |
if (is_system_session) { |
| 1472 |
state->session_info = session_info; |
| 1473 |
} else { |
| 1474 |
state->session_info = talloc_steal(state, session_info); |
| 1475 |
} |
| 1431 |
|
1476 |
|
| 1432 |
state->log(ISC_LOG_INFO, "samba_dlz: allowing update of signer=%s name=%s tcpaddr=%s type=%s key=%s", |
1477 |
state->log(ISC_LOG_INFO, "samba_dlz: allowing update of signer=%s name=%s tcpaddr=%s type=%s key=%s", |
| 1433 |
signer, name, tcpaddr, type, key); |
1478 |
signer, name, tcpaddr, type, key); |
| 1434 |
- |
|
|