Ignore:
Timestamp:
Mar 11, 2009, 9:14:55 AM (16 years ago)
Author:
Paul Smedley
Message:

Add 'missing' 3.0.34 diffs

Location:
branches/samba-3.0/source/nsswitch
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.0/source/nsswitch/pam_winbind.c

    r140 r165  
    18941894        }
    18951895
     1896        /*
     1897         * Delete the krb5 ccname variable from the PAM environment
     1898         * if it was set by winbind.
     1899         */
     1900        if (ctrl & WINBIND_KRB5_AUTH) {
     1901                pam_putenv(pamh, "KRB5CCNAME");
     1902        }
     1903
    18961904        _PAM_LOG_FUNCTION_LEAVE("pam_sm_close_session", pamh, ctrl, retval);
    18971905       
  • branches/samba-3.0/source/nsswitch/winbind_nss_solaris.c

    r1 r165  
    361361        int len = 0;
    362362        struct in_addr *addrp;
     363#if defined(AF_INET6)
    363364        struct in6_addr *addrp6;
     365#endif
    364366        int i;
    365367
     
    393395                he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
    394396                he->h_addr_list -= addrcount+1;
    395         } else {
     397        }
     398#if defined(AF_INET6)
     399        else {
    396400                he->h_length = sizeof(struct in6_addr);
    397401                addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
     
    401405                he->h_addr_list -= addrcount+1;
    402406        }
     407#endif
    403408
    404409        /* buffer too small?! */
     
    420425                    return NSS_STR_PARSE_ERANGE;
    421426                  }
    422                 } else {
     427                }
     428#if defined(AF_INET6)
     429                else {
    423430                  he->h_addr_list[i] = (char *)&addrp6[i];
    424431                  if (strchr(data, ':') != 0) {
     
    436443                  }
    437444                }
     445#endif
    438446                data = p+1;
    439447        }
     
    483491           IPv4 to IPv6.
    484492         */
     493#if defined(AF_INET6)
    485494#ifdef HAVE_NSS_XBYY_KEY_IPNODE
    486495        af = argp->key.ipnode.af_family;
     
    493502        af = AF_INET6;
    494503#endif
     504#endif
    495505
    496506        strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
     
    541551        ZERO_STRUCT(request);
    542552
     553#if defined(AF_INET6)
    543554        /* winbindd currently does not resolve IPv6 */
    544555        if(argp->key.hostaddr.type == AF_INET6) {
     
    548559
    549560        p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
    550                         request.data.winsreq, INET6_ADDRSTRLEN);
     561                        request.data.winsreq, sizeof request.data.winsreq);
     562#else
     563        snprintf(request.data.winsreq, sizeof request.data.winsreq,
     564                "%u.%u.%u.%u",
     565                ((unsigned char *)argp->key.hostaddr.addr)[0],
     566                ((unsigned char *)argp->key.hostaddr.addr)[1],
     567                ((unsigned char *)argp->key.hostaddr.addr)[2],
     568                ((unsigned char *)argp->key.hostaddr.addr)[3]);
     569#endif
    551570
    552571        ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);
  • branches/samba-3.0/source/nsswitch/winbindd.c

    r158 r165  
    478478        }
    479479
    480         SAFE_FREE(state->request.extra_data.data);
    481480        SAFE_FREE(state->response.extra_data.data);
    482481
     
    513512static void request_finished(struct winbindd_cli_state *state)
    514513{
     514        /* Make sure request.extra_data is freed when finish processing a request */
     515        SAFE_FREE(state->request.extra_data.data);
    515516        setup_async_write(&state->fd_event, &state->response,
    516517                          sizeof(state->response), response_main_sent, state);
     
    669670static void remove_client(struct winbindd_cli_state *state)
    670671{
     672        char c = 0;
     673
    671674        /* It's a dead client - hold a funeral */
    672675       
     
    674677                return;
    675678        }
    676                
     679
     680        /* tell client, we are closing ... */
     681        write(state->sock, &c, sizeof(c));
     682
    677683        /* Close socket */
    678684               
  • branches/samba-3.0/source/nsswitch/winbindd_ads.c

    r39 r165  
    391391}
    392392
     393/* convert a single name to a sid in a domain - use rpc methods */
     394static NTSTATUS name_to_sid(struct winbindd_domain *domain,
     395                            TALLOC_CTX *mem_ctx,
     396                            const char *domain_name,
     397                            const char *name,
     398                            DOM_SID *sid,
     399                            enum lsa_SidType *type)
     400{
     401        return reconnect_methods.name_to_sid(domain, mem_ctx,
     402                                             domain_name, name,
     403                                             sid, type);
     404}
     405
     406/* convert a domain SID to a user or group name - use rpc methods */
     407static NTSTATUS sid_to_name(struct winbindd_domain *domain,
     408                            TALLOC_CTX *mem_ctx,
     409                            const DOM_SID *sid,
     410                            char **domain_name,
     411                            char **name,
     412                            enum lsa_SidType *type)
     413{
     414        return reconnect_methods.sid_to_name(domain, mem_ctx, sid,
     415                                             domain_name, name, type);
     416}
     417
     418/* convert a list of rids to names - use rpc methods */
     419static NTSTATUS rids_to_names(struct winbindd_domain *domain,
     420                              TALLOC_CTX *mem_ctx,
     421                              const DOM_SID *sid,
     422                              uint32 *rids,
     423                              size_t num_rids,
     424                              char **domain_name,
     425                              char ***names,
     426                              enum lsa_SidType **types)
     427{
     428        return reconnect_methods.rids_to_names(domain, mem_ctx, sid,
     429                                               rids, num_rids,
     430                                               domain_name, names, types);
     431}
     432
    393433/* convert a DN to a name, SID and name type
    394434   this might become a major speed bottleneck if groups have
     
    830870        ads_msgfree(ads, msg);
    831871        return status;
     872}
     873
     874/* Lookup aliases a user is member of - use rpc methods */
     875static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
     876                                   TALLOC_CTX *mem_ctx,
     877                                   uint32 num_sids, const DOM_SID *sids,
     878                                   uint32 *num_aliases, uint32 **alias_rids)
     879{
     880        return reconnect_methods.lookup_useraliases(domain, mem_ctx,
     881                                                    num_sids, sids,
     882                                                    num_aliases,
     883                                                    alias_rids);
    832884}
    833885
     
    10361088}
    10371089
     1090/* find the lockout policy of a domain - use rpc methods */
     1091static NTSTATUS lockout_policy(struct winbindd_domain *domain,
     1092                               TALLOC_CTX *mem_ctx,
     1093                               SAM_UNK_INFO_12 *policy)
     1094{
     1095        return reconnect_methods.lockout_policy(domain, mem_ctx, policy);
     1096}
     1097
     1098/* find the password policy of a domain - use rpc methods */
     1099static NTSTATUS password_policy(struct winbindd_domain *domain,
     1100                                TALLOC_CTX *mem_ctx,
     1101                                SAM_UNK_INFO_1 *policy)
     1102{
     1103        return reconnect_methods.password_policy(domain, mem_ctx, policy);
     1104}
     1105
    10381106/* get a list of trusted domains */
    10391107static NTSTATUS trusted_domains(struct winbindd_domain *domain,
     
    11141182        enum_dom_groups,
    11151183        enum_local_groups,
    1116         msrpc_name_to_sid,
    1117         msrpc_sid_to_name,
    1118         msrpc_rids_to_names,
     1184        name_to_sid,
     1185        sid_to_name,
     1186        rids_to_names,
    11191187        query_user,
    11201188        lookup_usergroups,
    1121         msrpc_lookup_useraliases,
     1189        lookup_useraliases,
    11221190        lookup_groupmem,
    11231191        sequence_number,
    1124         msrpc_lockout_policy,
    1125         msrpc_password_policy,
     1192        lockout_policy,
     1193        password_policy,
    11261194        trusted_domains,
    11271195};
  • branches/samba-3.0/source/nsswitch/winbindd_cm.c

    r140 r165  
    162162****************************************************************/
    163163
     164bool winbindd_reinit_after_fork(const char *logfile);
     165
    164166static BOOL fork_child_dc_connect(struct winbindd_domain *domain)
    165167{
     
    169171        pid_t child_pid;
    170172        pid_t parent_pid = sys_getpid();
     173        pstring logfile;
    171174
    172175        /* Stop zombies */
     
    198201
    199202        /* tdb needs special fork handling */
    200         if (tdb_reopen_all(1) == -1) {
    201                 DEBUG(0,("tdb_reopen_all failed.\n"));
     203        if (!override_logfile) {
     204                pstr_sprintf(logfile, "%s/log.winbindd-dc-connect", dyn_LOGFILEBASE);
     205        }
     206        if (!winbindd_reinit_after_fork(logfile)) {
     207                DEBUG(0,("winbindd_reinit_after_fork failed.\n"));
     208                message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_FAILED_TO_GO_ONLINE,
     209                                domain->name,
     210                                strlen(domain->name)+1, False);
    202211                _exit(0);
    203         }
    204 
    205         close_conns_after_fork();
    206 
    207         if (!override_logfile) {
    208                 pstring logfile;
    209                 pstr_sprintf(logfile, "%s/log.winbindd-dc-connect", dyn_LOGFILEBASE);
    210                 lp_set_logfile(logfile);
    211                 reopen_logs();
    212212        }
    213213
     
    352352****************************************************************/
    353353
     354void ccache_regain_all_now(void);
     355
    354356static void set_domain_online(struct winbindd_domain *domain)
    355357{
    356         struct timeval now;
    357 
    358358        DEBUG(10,("set_domain_online: called for domain %s\n",
    359359                domain->name ));
     
    372372
    373373        /* If we are waiting to get a krb5 ticket, trigger immediately. */
    374         GetTimeOfDay(&now);
    375         set_event_dispatch_time(winbind_event_context(),
    376                                 "krb5_ticket_gain_handler", now);
     374        ccache_regain_all_now();
    377375
    378376        /* Ok, we're out of any startup mode now... */
     
    427425           because network manager seems to lie.
    428426           Wait at least 5 seconds. Heuristics suck... */
     427        GetTimeOfDay(&tev);
     428
     429        /* Go into "startup" mode again. */
     430        domain->startup_time = tev.tv_sec;
     431        domain->startup = True;
     432
     433        tev.tv_sec += 5;
    429434
    430435        if (!domain->check_online_event) {
     
    437442                        domain->name ));
    438443
    439                 domain->check_online_event = event_add_timed(winbind_event_context(),
    440                                                                 NULL,
    441                                                                 timeval_current_ofs(5, 0),
    442                                                                 "check_domain_online_handler",
    443                                                                 check_domain_online_handler,
    444                                                                 domain);
    445 
    446                 /* The above *has* to succeed for winbindd to work. */
    447                 if (!domain->check_online_event) {
    448                         smb_panic("set_domain_online_request: failed to add online handler.\n");
    449                 }
    450         }
    451 
    452         GetTimeOfDay(&tev);
    453 
    454         /* Go into "startup" mode again. */
    455         domain->startup_time = tev.tv_sec;
    456         domain->startup = True;
    457 
    458         tev.tv_sec += 5;
    459 
    460         set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev);
     444        }
     445        TALLOC_FREE(domain->check_online_event);
     446       
     447        domain->check_online_event = event_add_timed(winbind_event_context(),
     448                                                        NULL,
     449                                                        tev,
     450                                                        "check_domain_online_handler",
     451                                                        check_domain_online_handler,
     452                                                        domain);
     453
     454        /* The above *has* to succeed for winbindd to work. */
     455        if (!domain->check_online_event) {
     456                smb_panic("set_domain_online_request: failed to add online handler.\n");
     457        }
    461458}
    462459
  • branches/samba-3.0/source/nsswitch/winbindd_cred_cache.c

    r124 r165  
    3636
    3737static struct WINBINDD_CCACHE_ENTRY *ccache_list;
     38static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry,
     39                                                struct timeval t);
    3840
    3941/* The Krb5 ticket refresh handler should be scheduled
     
    7173        }
    7274        return i;
     75}
     76
     77void ccache_remove_all_after_fork(void)
     78{
     79        struct WINBINDD_CCACHE_ENTRY *cur;
     80        cur = ccache_list;
     81        while (cur) {
     82                DLIST_REMOVE(ccache_list, cur);
     83                TALLOC_FREE(cur->event);
     84                TALLOC_FREE(cur);
     85                cur = ccache_list;
     86        }
     87}
     88
     89static void krb5_ticket_gain_handler(struct event_context *event_ctx,
     90                                     struct timed_event *te,
     91                                     const struct timeval *now,
     92                                     void *private_data);
     93static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
     94                                        struct timed_event *te,
     95                                        const struct timeval *now,
     96                                        void *private_data);
     97
     98void ccache_regain_all_now(void)
     99{
     100        struct WINBINDD_CCACHE_ENTRY *cur;
     101        struct timeval t = timeval_current();
     102
     103        for (cur = ccache_list; cur; cur = cur->next) {
     104                struct timed_event *new_event;
     105
     106                /*
     107                 * if refresh_time is 0, we know that the
     108                 * the event has the krb5_ticket_gain_handler
     109                 */
     110                if (cur->refresh_time == 0) {
     111                        new_event = event_add_timed(winbind_event_context(),
     112                                                cur, t,
     113                                                "krb5_ticket_gain_handler",
     114                                                krb5_ticket_gain_handler,
     115                                                cur);
     116                } else {
     117                        new_event = event_add_timed(winbind_event_context(),
     118                                                cur, t,
     119                                                "krb5_ticket_refresh_handler",
     120                                                krb5_ticket_refresh_handler,
     121                                                cur);
     122                }
     123                if (!new_event) {
     124                        continue;
     125                }
     126
     127                TALLOC_FREE(cur->event);
     128                cur->event = new_event;
     129        }
     130        return;
     131}
     132
     133/****************************************************************
     134 The gain initial ticket is recognized as entry->refresh_time is
     135 always zero.
     136****************************************************************/
     137
     138static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry,
     139                                                struct timeval t)
     140{
     141        entry->refresh_time = 0;
     142        entry->event = event_add_timed(winbind_event_context(), entry,
     143                                        t,
     144                                        "krb5_ticket_gain_handler",
     145                                        krb5_ticket_gain_handler,
     146                                        entry);
    73147}
    74148
     
    87161        int ret;
    88162        time_t new_start;
     163        time_t expire_time = 0;
    89164        struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr;
    90165#endif
     
    98173
    99174        /* Kinit again if we have the user password and we can't renew the old
    100          * tgt anymore */
    101 
    102         if ((entry->renew_until < time(NULL)) && cred_ptr && cred_ptr->pass) {
    103              
    104                 set_effective_uid(entry->uid);
    105 
    106                 ret = kerberos_kinit_password_ext(entry->principal_name,
    107                                                   cred_ptr->pass,
    108                                                   0, /* hm, can we do time correction here ? */
    109                                                   &entry->refresh_time,
    110                                                   &entry->renew_until,
    111                                                   entry->ccname,
    112                                                   False, /* no PAC required anymore */
    113                                                   True,
    114                                                   WINBINDD_PAM_AUTH_KRB5_RENEW_TIME);
    115                 gain_root_privilege();
    116 
    117                 if (ret) {
    118                         DEBUG(3,("krb5_ticket_refresh_handler: could not re-kinit: %s\n",
    119                                 error_message(ret)));
    120                         TALLOC_FREE(entry->event);
    121                         return;
    122                 }
    123 
    124                 DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit "
    125                         "for: %s in ccache: %s\n",
    126                         entry->principal_name, entry->ccname));
    127 
     175         * tgt anymore
     176         * NB
     177         * This happens when machine are put to sleep for a very long time. */
     178
     179        if (entry->renew_until < time(NULL)) {
     180rekinit:
     181                if (cred_ptr && cred_ptr->pass) {
     182
     183                        set_effective_uid(entry->uid);
     184
     185                        ret = kerberos_kinit_password_ext(entry->principal_name,
     186                                                          cred_ptr->pass,
     187                                                          0, /* hm, can we do time correction here ? */
     188                                                          &entry->refresh_time,
     189                                                          &entry->renew_until,
     190                                                          entry->ccname,
     191                                                          False, /* no PAC required anymore */
     192                                                          True,
     193                                                          WINBINDD_PAM_AUTH_KRB5_RENEW_TIME);
     194                        gain_root_privilege();
     195
     196                        if (ret) {
     197                                DEBUG(3,("krb5_ticket_refresh_handler: "
     198                                        "could not re-kinit: %s\n",
     199                                        error_message(ret)));
     200                                /* destroy the ticket because we cannot rekinit
     201                                 * it, ignore error here */
     202                                ads_kdestroy(entry->ccname);
     203
     204                                /* Don't break the ticket refresh chain: retry
     205                                 * refreshing ticket sometime later when KDC is
     206                                 * unreachable -- BoYang.
     207                                 * More error handling here? KRB5_CC_IO,
     208                                 * KRB5KRB_AP_ERR_SKEW.
     209                                 * */
     210
     211                                if ((ret == KRB5_KDC_UNREACH)
     212                                    || (ret == KRB5_REALM_CANT_RESOLVE)) {
    128213#if defined(DEBUG_KRB5_TKT_RENEWAL)
    129                 new_start = time(NULL) + 30;           
    130 #else
    131                 /* The tkt should be refreshed at one-half the period
    132                    from now to the expiration time */
    133                 new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
    134 #endif
    135 
    136                 goto done;
    137         }
     214                                        new_start = time(NULL) + 30;
     215#else
     216                                        new_start = time(NULL) +
     217                                                    MAX(30, lp_winbind_cache_time());
     218#endif
     219                                        /* try to regain ticket here */
     220                                        add_krb5_ticket_gain_handler_event(entry,
     221                                                                        timeval_set(new_start, 0));
     222                                        return;
     223                                }
     224                                TALLOC_FREE(entry->event);
     225                                return;
     226                        }
     227
     228                        DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit "
     229                                "for: %s in ccache: %s\n",
     230                                entry->principal_name, entry->ccname));
     231 
     232#if defined(DEBUG_KRB5_TKT_RENEWAL)
     233                        new_start = time(NULL) + 30;
     234#else
     235                        /* The tkt should be refreshed at one-half the period
     236                           from now to the expiration time */
     237                        expire_time = entry->refresh_time;
     238                        new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);
     239#endif
     240                        goto done;
     241                } else {
     242                                /* can this happen?
     243                                 * No cached credentials
     244                                 * destroy ticket and refresh chain
     245                                 * */
     246                                ads_kdestroy(entry->ccname);
     247                                TALLOC_FREE(entry->event);
     248                                return;
     249                }
     250        }
    138251
    139252        set_effective_uid(entry->uid);
     
    146259        new_start = time(NULL) + 30;
    147260#else
     261        expire_time = new_start;
    148262        new_start = KRB5_EVENT_REFRESH_TIME(new_start);
    149263#endif
     
    156270                /* maybe we are beyond the renewing window */
    157271
     272                /* evil rises here, we refresh ticket failed,
     273                 * but the ticket might be expired. Therefore,
     274                 * When we refresh ticket failed, destory the
     275                 * ticket */
     276 
     277                ads_kdestroy(entry->ccname);
     278 
    158279                /* avoid breaking the renewal chain: retry in lp_winbind_cache_time()
    159                  * seconds when the KDC was not available right now. */
    160 
    161                 if (ret == KRB5_KDC_UNREACH) {
    162                         new_start = time(NULL) + MAX(30, lp_winbind_cache_time());
    163                         goto done;
    164                 }
     280                 * seconds when the KDC was not available right now.
     281                 * the return code can be KRB5_REALM_CANT_RESOLVE
     282                 * More error handling here? KRB5_CC_IO, KRB5KRB_AP_ERR_SKEW. */
     283 
     284                if ((ret == KRB5_KDC_UNREACH)
     285                    || (ret == KRB5_REALM_CANT_RESOLVE)) {
     286#if defined(DEBUG_KRB5_TKT_RENEWAL)
     287                        new_start = time(NULL) + 30;
     288#else
     289                        new_start = time(NULL) +
     290                                    MAX(30, lp_winbind_cache_time());
     291#endif
     292                        /* ticket is destroyed here, we have to regain it
     293                         * if it is possible */
     294                        add_krb5_ticket_gain_handler_event(entry, timeval_set(new_start, 0));
     295                        return;
     296                }
     297                /* This is evil, if the ticket was already expired.
     298                 * renew ticket function returns KRB5KRB_AP_ERR_TKT_EXPIRED.
     299                 * But there is still a chance that we can rekinit it.
     300                 *
     301                 * This happens when user login in online mode, and then network
     302                 * down or something cause winbind goes offline for a very long time,
     303                 * and then goes online again. ticket expired, renew failed.
     304                 * This happens when machine are put to sleep for a long time,
     305                 * but shorter than entry->renew_util.
     306                 * NB
     307                 * Looks like the KDC is reachable, we want to rekinit as soon as
     308                 * possible instead of waiting some time later. */
     309                if ((ret == KRB5KRB_AP_ERR_TKT_EXPIRED)
     310                    || (ret == KRB5_FCC_NOFILE)) goto rekinit;
     311 
    165312
    166313                return;
     
    168315
    169316done:
    170 
     317        /* in cases that ticket will be unrenewable soon, we don't try to renew ticket
     318         * but try to regain ticket if it is possible */
     319        if (entry->renew_until && expire_time
     320             && (entry->renew_until <= expire_time)) {
     321                /* try to regain ticket 10 seconds beforre expiration */
     322                expire_time -= 10;
     323                add_krb5_ticket_gain_handler_event(entry, timeval_set(expire_time, 0));
     324                return;
     325        }
     326       
     327        if (!entry->refresh_time) {
     328                entry->refresh_time = new_start;
     329        }
    171330        entry->event = event_add_timed(winbind_event_context(), entry,
    172331                                       timeval_set(new_start, 0),
     
    231390                        DEBUG(3,("krb5_ticket_gain_handler: could not kinit: %s\n",
    232391                                error_message(ret)));
     392                        /* evil. If we cannot do it, destroy any the __maybe__
     393                         * __existing__ ticket */
     394                        ads_kdestroy(entry->ccname);
    233395                        goto retry_later;
    234396                }
     
    241403
    242404  retry_later:
    243 
    244         entry->event = event_add_timed(winbind_event_context(), entry,
    245                                         timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
    246                                         "krb5_ticket_gain_handler",
    247                                         krb5_ticket_gain_handler,
    248                                         entry);
     405#if defined(DEBUG_KRB5_TKT_REGAIN)
     406        t = timeval_set(time(NULL) + 30, 0);
     407#else
     408        t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
     409#endif
     410        add_krb5_ticket_gain_handler_event(entry, t);
    249411
    250412        return;
     
    257419        t = timeval_set(KRB5_EVENT_REFRESH_TIME(entry->refresh_time), 0);
    258420#endif
    259 
     421       
     422        if (!entry->refresh_time) {
     423                entry->refresh_time = t.tv_sec;
     424        }
    260425        entry->event = event_add_timed(winbind_event_context(), entry,
    261426                                        t,
     
    315480{
    316481        struct WINBINDD_CCACHE_ENTRY *entry = NULL;
     482        NTSTATUS ntret;
     483#ifdef HAVE_KRB5
     484        int ret;
     485#endif
    317486
    318487        if ((username == NULL && princ_name == NULL) || ccname == NULL || uid < 0) {
     
    324493                return NT_STATUS_NO_MORE_ENTRIES;
    325494        }
     495
     496        /* If it is cached login, destroy krb5 ticket
     497         * to avoid surprise. */
     498#ifdef HAVE_KRB5
     499        if (postponed_request) {
     500                /* ignore KRB5_FCC_NOFILE error here */
     501                ret = ads_kdestroy(ccname);
     502                if (ret == KRB5_FCC_NOFILE) {
     503                        ret = 0;
     504                }
     505                if (ret) {
     506                        DEBUG(0, ("add_ccache_to_list: failed to destroy "
     507                                   "user krb5 ccache %s with %s\n", ccname,
     508                                   error_message(ret)));
     509                        return krb5_to_nt_status(ret);
     510                } else {
     511                        DEBUG(10, ("add_ccache_to_list: successfully destroyed "
     512                                   "krb5 ccache %s for user %s\n", ccname,
     513                                   username));
     514                }
     515        }
     516#endif
    326517
    327518        /* Reference count old entries */
     
    336527                        username, entry->ref_count));
    337528                /* FIXME: in this case we still might want to have a krb5 cred
    338                  * event handler created - gd*/
     529                 * event handler created - gd
     530                 * Add ticket refresh handler here */
     531               
     532                if (!lp_winbind_refresh_tickets() || renew_until <= 0) {
     533                        return NT_STATUS_OK;
     534                }
     535               
     536                if (!entry->event) {
     537                        struct timeval t;
     538                        if (postponed_request) {
     539                                t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
     540                                add_krb5_ticket_gain_handler_event(entry, t);
     541                        } else {
     542                                /* Renew at 1/2 the ticket expiration time */
     543#if defined(DEBUG_KRB5_TKT_RENEWAL)
     544                                t = timeval_set(time(NULL)+30, 0);
     545#else
     546                                t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
     547#endif
     548                                if (!entry->refresh_time) {
     549                                        entry->refresh_time = t.tv_sec;
     550                                }
     551                                entry->event = event_add_timed(winbind_event_context(),
     552                                                               entry,
     553                                                               t,
     554                                                               "krb5_ticket_refresh_handler",
     555                                                               krb5_ticket_refresh_handler,
     556                                                               entry);
     557                        }
     558
     559                        if (!entry->event) {
     560                                ntret = remove_ccache(username);
     561                                if (!NT_STATUS_IS_OK(ntret)) {
     562                                        DEBUG(0, ("add_ccache_to_list: Failed to remove krb5 "
     563                                                  "ccache %s for user %s\n", entry->ccname,
     564                                                  entry->username));
     565                                        DEBUG(0, ("add_ccache_to_list: error is %s\n",
     566                                                  nt_errstr(ntret)));
     567                                        return ntret;
     568                                }
     569                                return NT_STATUS_NO_MEMORY;
     570                        }
     571
     572                        DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n"));
     573                }
     574                 
    339575                return NT_STATUS_OK;
    340576        }
     
    382618
    383619        if (lp_winbind_refresh_tickets() && renew_until > 0) {
     620                struct timeval t;
    384621                if (postponed_request) {
    385                         entry->event = event_add_timed(winbind_event_context(), entry,
    386                                                 timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
    387                                                 "krb5_ticket_gain_handler",
    388                                                 krb5_ticket_gain_handler,
    389                                                 entry);
     622                        add_krb5_ticket_gain_handler_event(entry, t);
    390623                } else {
    391624                        /* Renew at 1/2 the ticket expiration time */
     625#if defined(DEBUG_KRB5_TKT_RENEWAL)
     626                        t = timeval_set(time(NULL)+30, 0);
     627#else
     628                        t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0);
     629#endif
     630                        if (!entry->refresh_time) {
     631                                entry->refresh_time = t.tv_sec;
     632                        }
    392633                        entry->event = event_add_timed(winbind_event_context(), entry,
    393 #if defined(DEBUG_KRB5_TKT_RENEWAL)
    394                                                 timeval_set(time(NULL)+30, 0),
    395 #else
    396                                                 timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0),
    397 #endif
     634                                                t,
    398635                                                "krb5_ticket_refresh_handler",
    399636                                                krb5_ticket_refresh_handler,
  • branches/samba-3.0/source/nsswitch/winbindd_dual.c

    r158 r165  
    195195        TALLOC_FREE(state->reply_timeout_event);
    196196
    197         SMB_ASSERT(state->child_pid != (pid_t)0);
    198 
    199         /* If not already reaped, send kill signal to child. */
    200         if (state->child->pid == state->child_pid) {
     197        /* If child exists and is not already reaped,
     198           send kill signal to child. */
     199
     200        if ((state->child->pid != (pid_t)0) &&
     201                        (state->child->pid != (pid_t)-1) &&
     202                        (state->child->pid == state->child_pid)) {
    201203                kill(state->child_pid, SIGTERM);
    202204
     
    293295        }
    294296
     297        /*
     298         * This may be a reschedule, so we might
     299         * have an existing timeout event pending on
     300         * the first entry in the child->requests list
     301         * (we only send one request at a time).
     302         * Ensure we free it before we reschedule.
     303         * Bug #5814, from hargagan <shargagan@novell.com>.
     304         * JRA.
     305         */
     306
     307        TALLOC_FREE(request->reply_timeout_event);
     308
    295309        if ((child->pid == 0) && (!fork_domain_child(child))) {
    296                 /* Cancel all outstanding requests */
     310                /* fork_domain_child failed.
     311                   Cancel all outstanding requests */
    297312
    298313                while (request != NULL) {
    299314                        /* request might be free'd in the continuation */
    300315                        struct winbindd_async_request *next = request->next;
    301                         request->continuation(request->private_data, False);
     316
     317                        async_request_fail(request);
    302318                        request = next;
    303319                }
     
    536552        child->pid = 0;
    537553
     554        if (child->requests) {
     555                /*
     556                 * schedule_async_request() will also
     557                 * clear this event but the call is
     558                 * idempotent so it doesn't hurt to
     559                 * cover all possible future code
     560                 * paths. JRA.
     561                 */
     562                TALLOC_FREE(child->requests->reply_timeout_event);
     563        }
     564
    538565        schedule_async_request(child);
    539566}
     
    753780{
    754781        struct winbindd_domain *domain;
     782        struct winbindd_domain *primary_domain = NULL;
    755783        const char *domainname = (const char *)buf;
    756784
     
    772800        }
    773801
     802        primary_domain = find_our_domain();
     803
    774804        /* Mark the requested domain offline. */
    775805
     
    781811                        DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name));
    782812                        set_domain_offline(domain);
     813                        /* we are in the trusted domain, set the primary domain
     814                         * offline too */
     815                        if (domain != primary_domain) {
     816                                set_domain_offline(primary_domain);
     817                        }
    783818                }
    784819        }
     
    791826{
    792827        struct winbindd_domain *domain;
     828        struct winbindd_domain *primary_domain = NULL;
    793829        const char *domainname = (const char *)buf;
    794830
     
    803839                return;
    804840        }
     841
     842        primary_domain = find_our_domain();
    805843
    806844        /* Set our global state as online. */
     
    818856                        winbindd_flush_negative_conn_cache(domain);
    819857                        set_domain_online_request(domain);
     858
     859                        /* we can be in trusted domain, which will contact primary domain
     860                         * we have to bring primary domain online in trusted domain process
     861                         * see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon()
     862                         * --> contact_domain = find_our_domain()
     863                         * */
     864                        if (domain != primary_domain) {
     865                                winbindd_flush_negative_conn_cache(primary_domain);
     866                                set_domain_online_request(primary_domain);
     867                        }
    820868                }
    821869        }
     
    881929}
    882930
     931bool reinit_after_fork(struct messaging_context *msg_ctx,
     932                        struct event_context *ev_ctx,
     933                        bool parent_longlived);
     934void ccache_remove_all_after_fork(void);
     935
     936bool winbindd_reinit_after_fork(const char *logfile)
     937{
     938        struct winbindd_domain *dom;
     939        struct winbindd_child *cl;
     940
     941        if (!reinit_after_fork(NULL,
     942                                winbind_event_context(), true)) {
     943                DEBUG(0, ("reinit_after_fork failed.\n"));
     944                return false;
     945        }
     946
     947        close_conns_after_fork();
     948
     949        if (!override_logfile && logfile) {
     950                lp_set_logfile(logfile);
     951                reopen_logs();
     952        }
     953
     954        /* Don't handle the same messages as our parent. */
     955        message_deregister(MSG_SMB_CONF_UPDATED);
     956        message_deregister(MSG_SHUTDOWN);
     957        message_deregister(MSG_WINBIND_OFFLINE);
     958        message_deregister(MSG_WINBIND_ONLINE);
     959        message_deregister(MSG_WINBIND_ONLINESTATUS);
     960
     961        ccache_remove_all_after_fork();
     962       
     963        for (dom = domain_list(); dom; dom = dom->next) {
     964                TALLOC_FREE(dom->check_online_event);
     965        }
     966
     967        for (cl = children; cl; cl = cl->next) {
     968                struct winbindd_async_request *request;
     969
     970                for (request = cl->requests; request; request = request->next) {
     971                        TALLOC_FREE(request->reply_timeout_event);
     972                }
     973                TALLOC_FREE(cl->lockout_policy_event);
     974        }
     975
     976        return true;
     977}
     978
    883979static BOOL fork_domain_child(struct winbindd_child *child)
    884980{
    885981        int fdpair[2];
    886982        struct winbindd_cli_state state;
    887         struct winbindd_domain *domain;
    888983        struct winbindd_domain *primary_domain = NULL;
    889984
     
    9161011                child->event.fd = fdpair[1];
    9171012                child->event.flags = 0;
    918                 child->requests = NULL;
    9191013                add_fd_event(&child->event);
    9201014                /* We're ok with online/offline messages now. */
     
    9321026
    9331027        /* tdb needs special fork handling */
    934         if (tdb_reopen_all(1) == -1) {
    935                 DEBUG(0,("tdb_reopen_all failed.\n"));
     1028        if (!winbindd_reinit_after_fork(child->logfilename)) {
     1029                DEBUG(0, ("winbindd_reinit_after_fork failed.\n"));
    9361030                _exit(0);
    9371031        }
    938 
    939         close_conns_after_fork();
    940 
    941         if (!override_logfile) {
    942                 lp_set_logfile(child->logfilename);
    943                 reopen_logs();
    944         }
    945 
    946         /* Don't handle the same messages as our parent. */
    947         message_deregister(MSG_SMB_CONF_UPDATED);
    948         message_deregister(MSG_SHUTDOWN);
    949         message_deregister(MSG_WINBIND_OFFLINE);
    950         message_deregister(MSG_WINBIND_ONLINE);
    951         message_deregister(MSG_WINBIND_ONLINESTATUS);
    9521032
    9531033        /* The child is ok with online/offline messages now. */
     
    9601040                         NULL);
    9611041
     1042        primary_domain = find_our_domain();
     1043
     1044        if (primary_domain == NULL) {
     1045                smb_panic("no primary domain found");
     1046        }
     1047
     1048        /* It doesn't matter if we allow cache login,
     1049         * try to bring domain online after fork. */
    9621050        if ( child->domain ) {
    9631051                child->domain->startup = True;
    9641052                child->domain->startup_time = time(NULL);
    965         }
    966 
    967         /* Ensure we have no pending check_online events other
    968            than one for this domain or the primary domain. */
    969 
    970         for (domain = domain_list(); domain; domain = domain->next) {
    971                 if (domain->primary) {
    972                         primary_domain = domain;
    973                 }
    974                 if ((domain != child->domain) && !domain->primary) {
    975                         TALLOC_FREE(domain->check_online_event);
    976                 }
    977         }
    978 
    979         /* Ensure we're not handling an event inherited from
    980            our parent. */
    981 
    982         cancel_named_event(winbind_event_context(),
    983                            "krb5_ticket_refresh_handler");
     1053                /* we can be in primary domain or in trusted domain
     1054                 * If we are in trusted domain, set the primary domain
     1055                 * in start-up mode */
     1056                if (!(child->domain->internal)) {
     1057                        set_domain_online_request(child->domain);
     1058                        if (!(child->domain->primary)) {
     1059                                primary_domain->startup = True;
     1060                                primary_domain->startup_time = time(NULL);
     1061                                set_domain_online_request(primary_domain);
     1062                        }
     1063                }
     1064        }
    9841065
    9851066        /* We might be in the idmap child...*/
  • branches/samba-3.0/source/nsswitch/winbindd_nss.h

    r124 r165  
    189189
    190190
    191 #define WBFLAG_PAM_INFO3_NDR            0x0001
    192 #define WBFLAG_PAM_INFO3_TEXT           0x0002
    193 #define WBFLAG_PAM_USER_SESSION_KEY     0x0004
    194 #define WBFLAG_PAM_LMKEY                0x0008
    195 #define WBFLAG_PAM_CONTACT_TRUSTDOM     0x0010
    196 #define WBFLAG_QUERY_ONLY               0x0020
    197 #define WBFLAG_PAM_UNIX_NAME            0x0080
    198 #define WBFLAG_PAM_AFS_TOKEN            0x0100
    199 #define WBFLAG_PAM_NT_STATUS_SQUASH     0x0200
     191#define WBFLAG_PAM_INFO3_NDR            0x00000001
     192#define WBFLAG_PAM_INFO3_TEXT           0x00000002
     193#define WBFLAG_PAM_USER_SESSION_KEY     0x00000004
     194#define WBFLAG_PAM_LMKEY                0x00000008
     195#define WBFLAG_PAM_CONTACT_TRUSTDOM     0x00000010
     196#define WBFLAG_QUERY_ONLY               0x00000020
     197#define WBFLAG_PAM_UNIX_NAME            0x00000080
     198#define WBFLAG_PAM_AFS_TOKEN            0x00000100
     199#define WBFLAG_PAM_NT_STATUS_SQUASH     0x00000200
    200200
    201201/* This is a flag that can only be sent from parent to child */
    202 #define WBFLAG_IS_PRIVILEGED            0x0400
     202#define WBFLAG_IS_PRIVILEGED            0x00000400
    203203/* Flag to say this is a winbindd internal send - don't recurse. */
    204 #define WBFLAG_RECURSE                  0x0800
    205 
    206 #define WBFLAG_PAM_KRB5                 0x1000
    207 #define WBFLAG_PAM_FALLBACK_AFTER_KRB5  0x2000
    208 #define WBFLAG_PAM_CACHED_LOGIN         0x4000
    209 #define WBFLAG_PAM_GET_PWD_POLICY       0x8000
     204#define WBFLAG_RECURSE                  0x00000800
     205
     206#define WBFLAG_PAM_KRB5                 0x00001000
     207#define WBFLAG_PAM_FALLBACK_AFTER_KRB5  0x00002000
     208#define WBFLAG_PAM_CACHED_LOGIN         0x00004000
     209#define WBFLAG_PAM_GET_PWD_POLICY       0x00008000
     210#define WBFLAG_BIG_NTLMV2_BLOB          0x00010000
    210211
    211212#define WINBINDD_MAX_EXTRA_DATA (128*1024)
  • branches/samba-3.0/source/nsswitch/winbindd_pam.c

    r140 r165  
    17631763        if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
    17641764                || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
    1765                 DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
    1766                           state->request.data.auth_crap.lm_resp_len,
    1767                           state->request.data.auth_crap.nt_resp_len));
    1768                 result = NT_STATUS_INVALID_PARAMETER;
    1769                 goto done;
     1765                if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB ||
     1766                     state->request.extra_len != state->request.data.auth_crap.nt_resp_len) {
     1767                        DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
     1768                                  state->request.data.auth_crap.lm_resp_len,
     1769                                  state->request.data.auth_crap.nt_resp_len));
     1770                                  result = NT_STATUS_INVALID_PARAMETER;
     1771                        goto done;
     1772                }
    17701773        }
    17711774
    17721775        lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp,
    17731776                                        state->request.data.auth_crap.lm_resp_len);
    1774         nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp,
    1775                                         state->request.data.auth_crap.nt_resp_len);
     1777        if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) {
     1778                nt_resp = data_blob_talloc(state->mem_ctx,
     1779                                           state->request.extra_data.data,
     1780                                           state->request.data.auth_crap.nt_resp_len);
     1781        } else {
     1782                nt_resp = data_blob_talloc(state->mem_ctx,
     1783                                           state->request.data.auth_crap.nt_resp,
     1784                                           state->request.data.auth_crap.nt_resp_len);
     1785        }
    17761786
    17771787        /* what domain should we contact? */
  • branches/samba-3.0/source/nsswitch/winbindd_passdb.c

    r140 r165  
    221221
    222222        if (!pdb_getsampwsid(user, user_sid ) ) {
     223                TALLOC_FREE( user );
    223224                return NT_STATUS_NO_SUCH_USER;
    224225        }
  • branches/samba-3.0/source/nsswitch/winbindd_proto.h

    r158 r165  
    199199/* The following definitions come from nsswitch/winbindd_cred_cache.c  */
    200200
     201void ccache_remove_all_after_fork(void);
     202void ccache_regain_all_now(void);
    201203BOOL ccache_entry_exists(const char *username);
    202204BOOL ccache_entry_identical(const char *username, uid_t uid, const char *ccname);
     
    346348/* The following definitions come from nsswitch/winbindd_rpc.c  */
    347349
    348 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
    349                             TALLOC_CTX *mem_ctx,
    350                             const char *domain_name,
    351                             const char *name,
    352                             DOM_SID *sid,
    353                             enum lsa_SidType *type);
    354 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
    355                             TALLOC_CTX *mem_ctx,
    356                             const DOM_SID *sid,
    357                             char **domain_name,
    358                             char **name,
    359                             enum lsa_SidType *type);
    360 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
    361                              TALLOC_CTX *mem_ctx,
    362                              const DOM_SID *sid,
    363                              uint32 *rids,
    364                              size_t num_rids,
    365                              char **domain_name,
    366                              char ***names,
    367                              enum lsa_SidType **types);
    368 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
    369                                   TALLOC_CTX *mem_ctx,
    370                                   uint32 num_sids, const DOM_SID *sids,
    371                                   uint32 *num_aliases, uint32 **alias_rids);
    372 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
    373                               TALLOC_CTX *mem_ctx,
    374                               SAM_UNK_INFO_12 *lockout_policy);
    375 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
    376                                TALLOC_CTX *mem_ctx,
    377                                SAM_UNK_INFO_1 *password_policy);
    378350
    379351/* The following definitions come from nsswitch/winbindd_sid.c  */
  • branches/samba-3.0/source/nsswitch/winbindd_rpc.c

    r71 r165  
    236236
    237237/* convert a single name to a sid in a domain */
    238 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
    239                             TALLOC_CTX *mem_ctx,
    240                             const char *domain_name,
    241                             const char *name,
    242                             DOM_SID *sid,
    243                             enum lsa_SidType *type)
     238static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
     239                                  TALLOC_CTX *mem_ctx,
     240                                  const char *domain_name,
     241                                  const char *name,
     242                                  DOM_SID *sid,
     243                                  enum lsa_SidType *type)
    244244{
    245245        NTSTATUS result;
     
    287287  convert a domain SID to a user or group name
    288288*/
    289 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
    290                             TALLOC_CTX *mem_ctx,
    291                             const DOM_SID *sid,
    292                             char **domain_name,
    293                             char **name,
    294                             enum lsa_SidType *type)
     289static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
     290                                  TALLOC_CTX *mem_ctx,
     291                                  const DOM_SID *sid,
     292                                  char **domain_name,
     293                                  char **name,
     294                                  enum lsa_SidType *type)
    295295{
    296296        char **domains;
     
    323323}
    324324
    325 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
    326                              TALLOC_CTX *mem_ctx,
    327                              const DOM_SID *sid,
    328                              uint32 *rids,
    329                              size_t num_rids,
    330                              char **domain_name,
    331                              char ***names,
    332                              enum lsa_SidType **types)
     325static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
     326                                    TALLOC_CTX *mem_ctx,
     327                                    const DOM_SID *sid,
     328                                    uint32 *rids,
     329                                    size_t num_rids,
     330                                    char **domain_name,
     331                                    char ***names,
     332                                    enum lsa_SidType **types)
    333333{
    334334        char **domains;
     
    531531}
    532532
    533 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
    534                                   TALLOC_CTX *mem_ctx,
    535                                   uint32 num_sids, const DOM_SID *sids,
    536                                   uint32 *num_aliases, uint32 **alias_rids)
     533static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
     534                                         TALLOC_CTX *mem_ctx,
     535                                         uint32 num_sids, const DOM_SID *sids,
     536                                         uint32 *num_aliases,
     537                                         uint32 **alias_rids)
    537538{
    538539        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     
    956957
    957958/* find the lockout policy for a domain */
    958 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
    959                               TALLOC_CTX *mem_ctx,
    960                               SAM_UNK_INFO_12 *lockout_policy)
     959static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
     960                                     TALLOC_CTX *mem_ctx,
     961                                     SAM_UNK_INFO_12 *lockout_policy)
    961962{
    962963        NTSTATUS result;
     
    988989
    989990/* find the password policy for a domain */
    990 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
    991                                TALLOC_CTX *mem_ctx,
    992                                SAM_UNK_INFO_1 *password_policy)
     991static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
     992                                      TALLOC_CTX *mem_ctx,
     993                                      SAM_UNK_INFO_1 *password_policy)
    993994{
    994995        NTSTATUS result;
  • branches/samba-3.0/source/nsswitch/winbindd_util.c

    r140 r165  
    772772
    773773        while(temp != NULL) {
    774                 struct getent_state *next;
     774                struct getent_state *next = temp->next;
    775775
    776776                /* Free sam entries then list entry */
     
    778778                SAFE_FREE(state->sam_entries);
    779779                DLIST_REMOVE(state, state);
    780                 next = temp->next;
    781780
    782781                SAFE_FREE(temp);
Note: See TracChangeset for help on using the changeset viewer.