📄 smbk5pwd.c
字号:
nthash( &pwd, keys ); ml->sml_desc = ad_sambaNTPassword; ml->sml_op = LDAP_MOD_REPLACE;#ifdef SLAP_MOD_INTERNAL ml->sml_flags = SLAP_MOD_INTERNAL;#endif ml->sml_values = keys; ml->sml_nvalues = NULL; /* Truncate UCS2 to 8-bit ASCII */ c = pwd.bv_val+1; d = pwd.bv_val+2; for (j=1; j<l; j++) { *c++ = *d++; d++; } pwd.bv_len /= 2; pwd.bv_val[pwd.bv_len] = '\0'; ml = ch_malloc(sizeof(Modifications)); ml->sml_next = qpw->rs_mods; qpw->rs_mods = ml; keys = ch_malloc( 2 * sizeof(struct berval) ); BER_BVZERO( &keys[1] ); lmhash( &pwd, keys ); ml->sml_desc = ad_sambaLMPassword; ml->sml_op = LDAP_MOD_REPLACE;#ifdef SLAP_MOD_INTERNAL ml->sml_flags = SLAP_MOD_INTERNAL;#endif ml->sml_values = keys; ml->sml_nvalues = NULL; ch_free(wcs); ml = ch_malloc(sizeof(Modifications)); ml->sml_next = qpw->rs_mods; qpw->rs_mods = ml; keys = ch_malloc( 2 * sizeof(struct berval) ); keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 ); keys[0].bv_len = snprintf(keys[0].bv_val, STRLENOF( "9223372036854775807L" ) + 1, "%ld", slap_get_time()); BER_BVZERO( &keys[1] ); ml->sml_desc = ad_sambaPwdLastSet; ml->sml_op = LDAP_MOD_REPLACE;#ifdef SLAP_MOD_INTERNAL ml->sml_flags = SLAP_MOD_INTERNAL;#endif ml->sml_values = keys; ml->sml_nvalues = NULL; if (pi->smb_must_change) { ml = ch_malloc(sizeof(Modifications)); ml->sml_next = qpw->rs_mods; qpw->rs_mods = ml; keys = ch_malloc( 2 * sizeof(struct berval) ); keys[0].bv_val = ch_malloc( STRLENOF( "9223372036854775807L" ) + 1 ); keys[0].bv_len = snprintf(keys[0].bv_val, STRLENOF( "9223372036854775807L" ) + 1, "%ld", slap_get_time() + pi->smb_must_change); BER_BVZERO( &keys[1] ); ml->sml_desc = ad_sambaPwdMustChange; ml->sml_op = LDAP_MOD_REPLACE;#ifdef SLAP_MOD_INTERNAL ml->sml_flags = SLAP_MOD_INTERNAL;#endif ml->sml_values = keys; ml->sml_nvalues = NULL; } }#endif /* DO_SAMBA */ be_entry_release_r( op, e ); return SLAP_CB_CONTINUE;}static slap_overinst smbk5pwd;/* back-config stuff */enum { PC_SMB_MUST_CHANGE = 1, PC_SMB_ENABLE};static ConfigDriver smbk5pwd_cf_func;/* * NOTE: uses OID arcs OLcfgOvAt:6 and OLcfgOvOc:6 */static ConfigTable smbk5pwd_cfats[] = { { "smbk5pwd-enable", "arg", 2, 0, 0, ARG_MAGIC|PC_SMB_ENABLE, smbk5pwd_cf_func, "( OLcfgOvAt:6.1 NAME 'olcSmbK5PwdEnable' " "DESC 'Modules to be enabled' " "SYNTAX OMsDirectoryString )", NULL, NULL }, { "smbk5pwd-must-change", "time", 2, 2, 0, ARG_MAGIC|ARG_INT|PC_SMB_MUST_CHANGE, smbk5pwd_cf_func, "( OLcfgOvAt:6.2 NAME 'olcSmbK5PwdMustChange' " "DESC 'Credentials validity interval' " "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, { NULL, NULL, 0, 0, 0, ARG_IGNORED }};static ConfigOCs smbk5pwd_cfocs[] = { { "( OLcfgOvOc:6.1 " "NAME 'olcSmbK5PwdConfig' " "DESC 'smbk5pwd overlay configuration' " "SUP olcOverlayConfig " "MAY ( " "olcSmbK5PwdEnable " "$ olcSmbK5PwdMustChange " ") )", Cft_Overlay, smbk5pwd_cfats }, { NULL, 0, NULL }};/* * add here other functionalities; handle their initialization * as appropriate in smbk5pwd_modules_init(). */static slap_verbmasks smbk5pwd_modules[] = { { BER_BVC( "krb5" ), SMBK5PWD_F_KRB5 }, { BER_BVC( "samba" ), SMBK5PWD_F_SAMBA }, { BER_BVNULL, -1 }};static intsmbk5pwd_cf_func( ConfigArgs *c ){ slap_overinst *on = (slap_overinst *)c->bi; int rc = 0; smbk5pwd_t *pi = on->on_bi.bi_private; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case PC_SMB_MUST_CHANGE:#ifdef DO_SAMBA c->value_int = pi->smb_must_change;#else /* ! DO_SAMBA */ c->value_int = 0;#endif /* ! DO_SAMBA */ break; case PC_SMB_ENABLE: c->rvalue_vals = NULL; if ( pi->mode ) { mask_to_verbs( smbk5pwd_modules, pi->mode, &c->rvalue_vals ); if ( c->rvalue_vals == NULL ) { rc = 1; } } break; default: assert( 0 ); rc = 1; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case PC_SMB_MUST_CHANGE: break; case PC_SMB_ENABLE: if ( !c->line ) { pi->mode = 0; } else { slap_mask_t m; m = verb_to_mask( c->line, smbk5pwd_modules ); pi->mode &= ~m; } break; default: assert( 0 ); rc = 1; } return rc; } switch( c->type ) { case PC_SMB_MUST_CHANGE:#ifdef DO_SAMBA if ( c->value_int < 0 ) { Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " "<%s> invalid negative value \"%d\".", c->log, c->argv[ 0 ], 0 ); return 1; } pi->smb_must_change = c->value_int;#else /* ! DO_SAMBA */ Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " "<%s> only meaningful " "when compiled with -DDO_SAMBA.\n", c->log, c->argv[ 0 ], 0 ); return 1;#endif /* ! DO_SAMBA */ break; case PC_SMB_ENABLE: { slap_mask_t mode = pi->mode, m; rc = verbs_to_mask( c->argc, c->argv, smbk5pwd_modules, &m ); if ( rc > 0 ) { Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " "<%s> unknown module \"%s\".\n", c->log, c->argv[ 0 ], c->argv[ rc ] ); return 1; } /* we can hijack the smbk5pwd_t structure because * from within the configuration, this is the only * active thread. */ pi->mode |= m;#ifndef DO_KRB5 if ( SMBK5PWD_DO_KRB5( pi ) ) { Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " "<%s> module \"%s\" only allowed when compiled with -DDO_KRB5.\n", c->log, c->argv[ 0 ], c->argv[ rc ] ); pi->mode = mode; return 1; }#endif /* ! DO_KRB5 */#ifndef DO_SAMBA if ( SMBK5PWD_DO_SAMBA( pi ) ) { Debug( LDAP_DEBUG_ANY, "%s: smbk5pwd: " "<%s> module \"%s\" only allowed when compiled with -DDO_SAMBA.\n", c->log, c->argv[ 0 ], c->argv[ rc ] ); pi->mode = mode; return 1; }#endif /* ! DO_SAMBA */ { BackendDB db = *c->be; /* Re-initialize the module, because * the configuration might have changed */ db.bd_info = (BackendInfo *)on; rc = smbk5pwd_modules_init( pi ); if ( rc ) { pi->mode = mode; return 1; } } } break; default: assert( 0 ); return 1; } return rc;}static intsmbk5pwd_modules_init( smbk5pwd_t *pi ){ static struct { const char *name; AttributeDescription **adp; }#ifdef DO_KRB5 krb5_ad[] = { { "krb5Key", &ad_krb5Key }, { "krb5KeyVersionNumber", &ad_krb5KeyVersionNumber }, { "krb5PrincipalName", &ad_krb5PrincipalName }, { NULL } },#endif /* DO_KRB5 */#ifdef DO_SAMBA samba_ad[] = { { "sambaLMPassword", &ad_sambaLMPassword }, { "sambaNTPassword", &ad_sambaNTPassword }, { "sambaPwdLastSet", &ad_sambaPwdLastSet }, { "sambaPwdMustChange", &ad_sambaPwdMustChange }, { NULL } },#endif /* DO_SAMBA */ dummy_ad; /* this is to silence the unused var warning */ dummy_ad.name = NULL;#ifdef DO_KRB5 if ( SMBK5PWD_DO_KRB5( pi ) && oc_krb5KDCEntry == NULL ) { krb5_error_code ret; extern HDB *_kadm5_s_get_db(void *); int i, rc; /* Make sure all of our necessary schema items are loaded */ oc_krb5KDCEntry = oc_find( "krb5KDCEntry" ); if ( !oc_krb5KDCEntry ) { Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to find \"krb5KDCEntry\" objectClass.\n", 0, 0, 0 ); return -1; } for ( i = 0; krb5_ad[ i ].name != NULL; i++ ) { const char *text; *(krb5_ad[ i ].adp) = NULL; rc = slap_str2ad( krb5_ad[ i ].name, krb5_ad[ i ].adp, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to find \"%s\" attributeType: %s (%d).\n", krb5_ad[ i ].name, text, rc ); oc_krb5KDCEntry = NULL; return rc; } } /* Initialize Kerberos context */ ret = krb5_init_context(&context); if (ret) { Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to initialize krb5 context (%d).\n", ret, 0, 0 ); oc_krb5KDCEntry = NULL; return -1; } ret = kadm5_s_init_with_password_ctx( context, KADM5_ADMIN_SERVICE, NULL, KADM5_ADMIN_SERVICE, &conf, 0, 0, &kadm_context ); if (ret) { char *err_str, *err_msg = "<unknown error>"; err_str = krb5_get_error_string( context ); if (!err_str) err_msg = krb5_get_err_text( context, ret ); Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to initialize krb5 admin context: %s (%d).\n", err_str ? err_str : err_msg, ret, 0 ); if (err_str) krb5_free_error_string( context, err_str ); krb5_free_context( context ); oc_krb5KDCEntry = NULL; return -1; } db = _kadm5_s_get_db( kadm_context ); }#endif /* DO_KRB5 */#ifdef DO_SAMBA if ( SMBK5PWD_DO_SAMBA( pi ) && oc_sambaSamAccount == NULL ) { int i, rc; oc_sambaSamAccount = oc_find( "sambaSamAccount" ); if ( !oc_sambaSamAccount ) { Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to find \"sambaSamAccount\" objectClass.\n", 0, 0, 0 ); return -1; } for ( i = 0; samba_ad[ i ].name != NULL; i++ ) { const char *text; *(samba_ad[ i ].adp) = NULL; rc = slap_str2ad( samba_ad[ i ].name, samba_ad[ i ].adp, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "smbk5pwd: " "unable to find \"%s\" attributeType: %s (%d).\n", samba_ad[ i ].name, text, rc ); oc_sambaSamAccount = NULL; return rc; } } }#endif /* DO_SAMBA */ return 0;}static intsmbk5pwd_db_init(BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; smbk5pwd_t *pi; pi = ch_calloc( 1, sizeof( smbk5pwd_t ) ); if ( pi == NULL ) { return 1; } on->on_bi.bi_private = (void *)pi; return 0;}static intsmbk5pwd_db_open(BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private; int rc; if ( pi->mode == 0 ) { pi->mode = SMBK5PWD_F_ALL; } rc = smbk5pwd_modules_init( pi ); if ( rc ) { return rc; } return 0;}static intsmbk5pwd_db_destroy(BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; smbk5pwd_t *pi = (smbk5pwd_t *)on->on_bi.bi_private; if ( pi ) { ch_free( pi ); } return 0;}intsmbk5pwd_initialize(void){ int rc; smbk5pwd.on_bi.bi_type = "smbk5pwd"; smbk5pwd.on_bi.bi_db_init = smbk5pwd_db_init; smbk5pwd.on_bi.bi_db_open = smbk5pwd_db_open; smbk5pwd.on_bi.bi_db_destroy = smbk5pwd_db_destroy; smbk5pwd.on_bi.bi_extended = smbk5pwd_exop_passwd; #ifdef DO_KRB5 smbk5pwd.on_bi.bi_op_bind = smbk5pwd_op_bind; lutil_passwd_add( (struct berval *)&k5key_scheme, k5key_chk, k5key_hash );#endif smbk5pwd.on_bi.bi_cf_ocs = smbk5pwd_cfocs; rc = config_register_schema( smbk5pwd_cfats, smbk5pwd_cfocs ); if ( rc ) { return rc; } return overlay_register( &smbk5pwd );}#if SLAPD_OVER_SMBK5PWD == SLAPD_MOD_DYNAMICint init_module(int argc, char *argv[]) { return smbk5pwd_initialize();}#endif#endif /* defined(SLAPD_OVER_SMBK5PWD) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -