Ignore:
Timestamp:
May 27, 2009, 9:09:42 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.2 branch to 3.2.8

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.2.x/source/winbindd/winbindd_dual.c

    r228 r232  
    881881{
    882882        struct winbindd_domain *domain;
     883        struct winbindd_domain *primary_domain = NULL;
    883884        const char *domainname = (const char *)data->data;
    884885
     
    893894                return;
    894895        }
     896
     897        primary_domain = find_our_domain();
    895898
    896899        /* Mark the requested domain offline. */
     
    903906                        DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name));
    904907                        set_domain_offline(domain);
     908                        /* we are in the trusted domain, set the primary domain
     909                         * offline too */
     910                        if (domain != primary_domain) {
     911                                set_domain_offline(primary_domain);
     912                        }
    905913                }
    906914        }
     
    916924{
    917925        struct winbindd_domain *domain;
     926        struct winbindd_domain *primary_domain = NULL;
    918927        const char *domainname = (const char *)data->data;
    919928
     
    928937                return;
    929938        }
     939
     940        primary_domain = find_our_domain();
    930941
    931942        /* Set our global state as online. */
     
    943954                        winbindd_flush_negative_conn_cache(domain);
    944955                        set_domain_online_request(domain);
     956
     957                        /* we can be in trusted domain, which will contact primary domain
     958                         * we have to bring primary domain online in trusted domain process
     959                         * see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon()
     960                         * --> contact_domain = find_our_domain()
     961                         * */
     962                        if (domain != primary_domain) {
     963                                winbindd_flush_negative_conn_cache(primary_domain);
     964                                set_domain_online_request(primary_domain);
     965                        }
    945966                }
    946967        }
     
    10201041}
    10211042
    1022 
    1023 static bool fork_domain_child(struct winbindd_child *child)
    1024 {
    1025         int fdpair[2];
    1026         struct winbindd_cli_state state;
     1043void ccache_remove_all_after_fork(void);
     1044
     1045bool winbindd_reinit_after_fork(const char *logfilename)
     1046{
    10271047        struct winbindd_domain *domain;
    1028         struct winbindd_domain *primary_domain = NULL;
    1029 
    1030         if (child->domain) {
    1031                 DEBUG(10, ("fork_domain_child called for domain '%s'\n",
    1032                            child->domain->name));
    1033         } else {
    1034                 DEBUG(10, ("fork_domain_child called without domain.\n"));
    1035         }
    1036 
    1037         if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) {
    1038                 DEBUG(0, ("Could not open child pipe: %s\n",
    1039                           strerror(errno)));
    1040                 return False;
    1041         }
    1042 
    1043         ZERO_STRUCT(state);
    1044         state.pid = sys_getpid();
    1045 
    1046         child->pid = sys_fork();
    1047 
    1048         if (child->pid == -1) {
    1049                 DEBUG(0, ("Could not fork: %s\n", strerror(errno)));
    1050                 return False;
    1051         }
    1052 
    1053         if (child->pid != 0) {
    1054                 /* Parent */
    1055                 close(fdpair[0]);
    1056                 child->next = child->prev = NULL;
    1057                 DLIST_ADD(children, child);
    1058                 child->event.fd = fdpair[1];
    1059                 child->event.flags = 0;
    1060                 child->requests = NULL;
    1061                 add_fd_event(&child->event);
    1062                 return True;
    1063         }
    1064 
    1065         /* Child */
    1066 
    1067         /* Stop zombies in children */
    1068         CatchChild();
    1069 
    1070         state.sock = fdpair[0];
    1071         close(fdpair[1]);
    1072 
    1073         if (!reinit_after_fork(winbind_messaging_context(), true)) {
     1048        struct winbindd_child *cl;
     1049
     1050        if (!reinit_after_fork(winbind_messaging_context(),
     1051                               winbind_event_context(), true)) {
    10741052                DEBUG(0,("reinit_after_fork() failed\n"));
    1075                 _exit(0);
     1053                return false;
    10761054        }
    10771055
    10781056        close_conns_after_fork();
    10791057
    1080         if (!override_logfile) {
    1081                 lp_set_logfile(child->logfilename);
     1058        if (!override_logfile && logfilename) {
     1059                lp_set_logfile(logfilename);
    10821060                reopen_logs();
    10831061        }
    1084 
    1085         /*
    1086          * For clustering, we need to re-init our ctdbd connection after the
    1087          * fork
    1088          */
    1089         if (!NT_STATUS_IS_OK(messaging_reinit(winbind_messaging_context())))
    1090                 exit(1);
    10911062
    10921063        /* Don't handle the same messages as our parent. */
     
    11081079                             MSG_DEBUG, NULL);
    11091080
    1110         /* Handle online/offline messages. */
    1111         messaging_register(winbind_messaging_context(), NULL,
    1112                            MSG_WINBIND_OFFLINE, child_msg_offline);
    1113         messaging_register(winbind_messaging_context(), NULL,
    1114                            MSG_WINBIND_ONLINE, child_msg_online);
    1115         messaging_register(winbind_messaging_context(), NULL,
    1116                            MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus);
    1117         messaging_register(winbind_messaging_context(), NULL,
    1118                            MSG_DUMP_EVENT_LIST, child_msg_dump_event_list);
    1119         messaging_register(winbind_messaging_context(), NULL,
    1120                            MSG_DEBUG, debug_message);
    1121 
     1081        /* We have destroyed all events in the winbindd_event_context
     1082         * in reinit_after_fork(), so clean out all possible pending
     1083         * event pointers. */
     1084
     1085        /* Deal with check_online_events. */
     1086
     1087        for (domain = domain_list(); domain; domain = domain->next) {
     1088                TALLOC_FREE(domain->check_online_event);
     1089        }
     1090
     1091        /* Ensure we're not handling a credential cache event inherited
     1092         * from our parent. */
     1093
     1094        ccache_remove_all_after_fork();
     1095
     1096        /* Destroy all possible events in child list. */
     1097        for (cl = children; cl != NULL; cl = cl->next) {
     1098                struct winbindd_async_request *request;
     1099
     1100                for (request = cl->requests; request; request = request->next) {
     1101                        TALLOC_FREE(request->reply_timeout_event);
     1102                }
     1103                TALLOC_FREE(cl->lockout_policy_event);
     1104
     1105                /* Children should never be able to send
     1106                 * each other messages, all messages must
     1107                 * go through the parent.
     1108                 */
     1109                cl->pid = (pid_t)0;
     1110        }
     1111        /*
     1112         * This is a little tricky, children must not
     1113         * send an MSG_WINBIND_ONLINE message to idmap_child().
     1114         * If we are in a child of our primary domain or
     1115         * in the process created by fork_child_dc_connect(),
     1116         * and the primary domain cannot go online,
     1117         * fork_child_dc_connection() sends MSG_WINBIND_ONLINE
     1118         * periodically to idmap_child().
     1119         *
     1120         * The sequence is, fork_child_dc_connect() ---> getdcs() --->
     1121         * get_dc_name_via_netlogon() ---> cm_connect_netlogon()
     1122         * ---> init_dc_connection() ---> cm_open_connection --->
     1123         * set_domain_online(), sends MSG_WINBIND_ONLINE to
     1124         * idmap_child(). Disallow children sending messages
     1125         * to each other, all messages must go through the parent.
     1126         */
     1127        cl = idmap_child();
     1128        cl->pid = (pid_t)0;
     1129
     1130        return true;
     1131}
     1132
     1133static bool fork_domain_child(struct winbindd_child *child)
     1134{
     1135        int fdpair[2];
     1136        struct winbindd_cli_state state;
     1137        struct winbindd_domain *primary_domain = NULL;
     1138
     1139        if (child->domain) {
     1140                DEBUG(10, ("fork_domain_child called for domain '%s'\n",
     1141                           child->domain->name));
     1142        } else {
     1143                DEBUG(10, ("fork_domain_child called without domain.\n"));
     1144        }
     1145
     1146        if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) {
     1147                DEBUG(0, ("Could not open child pipe: %s\n",
     1148                          strerror(errno)));
     1149                return False;
     1150        }
     1151
     1152        ZERO_STRUCT(state);
     1153        state.pid = sys_getpid();
     1154
     1155        child->pid = sys_fork();
     1156
     1157        if (child->pid == -1) {
     1158                DEBUG(0, ("Could not fork: %s\n", strerror(errno)));
     1159                return False;
     1160        }
     1161
     1162        if (child->pid != 0) {
     1163                /* Parent */
     1164                close(fdpair[0]);
     1165                child->next = child->prev = NULL;
     1166                DLIST_ADD(children, child);
     1167                child->event.fd = fdpair[1];
     1168                child->event.flags = 0;
     1169                add_fd_event(&child->event);
     1170                return True;
     1171        }
     1172
     1173        /* Child */
     1174
     1175        /* Stop zombies in children */
     1176        CatchChild();
     1177
     1178        state.sock = fdpair[0];
     1179        close(fdpair[1]);
     1180
     1181        if (!winbindd_reinit_after_fork(child->logfilename)) {
     1182                DEBUG(0, ("winbindd_reinit_after_fork failed.\n"));
     1183                _exit(0);
     1184        }
     1185 
     1186        /* Handle online/offline messages. */
     1187        messaging_register(winbind_messaging_context(), NULL,
     1188                           MSG_WINBIND_OFFLINE, child_msg_offline);
     1189        messaging_register(winbind_messaging_context(), NULL,
     1190                           MSG_WINBIND_ONLINE, child_msg_online);
     1191        messaging_register(winbind_messaging_context(), NULL,
     1192                           MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus);
     1193        messaging_register(winbind_messaging_context(), NULL,
     1194                           MSG_DUMP_EVENT_LIST, child_msg_dump_event_list);
     1195        messaging_register(winbind_messaging_context(), NULL,
     1196                           MSG_DEBUG, debug_message);
     1197       
     1198        primary_domain = find_our_domain();
     1199
     1200        if (primary_domain == NULL) {
     1201                smb_panic("no primary domain found");
     1202        }
     1203
     1204        /* It doesn't matter if we allow cache login,
     1205         * try to bring domain online after fork. */
    11221206        if ( child->domain ) {
    11231207                child->domain->startup = True;
    11241208                child->domain->startup_time = time(NULL);
    1125         }
    1126 
    1127         /* Ensure we have no pending check_online events other
    1128            than one for this domain or the primary domain. */
    1129 
    1130         for (domain = domain_list(); domain; domain = domain->next) {
    1131                 if (domain->primary) {
    1132                         primary_domain = domain;
    1133                 }
    1134                 if ((domain != child->domain) && !domain->primary) {
    1135                         TALLOC_FREE(domain->check_online_event);
    1136                 }
    1137         }
    1138 
    1139         /* Ensure we're not handling an event inherited from
    1140            our parent. */
    1141 
    1142         cancel_named_event(winbind_event_context(),
    1143                            "krb5_ticket_refresh_handler");
     1209                /* we can be in primary domain or in trusted domain
     1210                 * If we are in trusted domain, set the primary domain
     1211                 * in start-up mode */
     1212                if (!(child->domain->internal)) {
     1213                        set_domain_online_request(child->domain);
     1214                        if (!(child->domain->primary)) {
     1215                                primary_domain->startup = True;
     1216                                primary_domain->startup_time = time(NULL);
     1217                                set_domain_online_request(primary_domain);
     1218                        }
     1219                }
     1220        }
     1221       
     1222        /*
     1223         * We are in idmap child, make sure that we set the
     1224         * check_online_event to bring primary domain online.
     1225         */
     1226        if (child == idmap_child()) {
     1227                set_domain_online_request(primary_domain);
     1228        }
    11441229
    11451230        /* We might be in the idmap child...*/
     
    12251310                        TALLOC_FREE(frame);
    12261311                        perror("select");
    1227                         return False;
     1312                        _exit(1);
    12281313                }
    12291314
     
    12331318                if (state.finished) {
    12341319                        /* we lost contact with our parent */
    1235                         exit(0);
     1320                        _exit(0);
    12361321                }
    12371322
Note: See TracChangeset for help on using the changeset viewer.