]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/plugins/winbind.c
pppd: Handle SIGINT and SIGTERM during interrupted syscalls (#148)
[ppp.git] / pppd / plugins / winbind.c
index 1c91a4cfb48ac3bc6f9ebee2b39e274bc8043ff7..0c395c34711af6cef39d3ac01e3603f7205ebbc5 100644 (file)
@@ -209,42 +209,33 @@ static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01
  **/
 char * base64_encode(const char *data)
 {
-       int bits = 0;
-       int char_count = 0;
        size_t out_cnt = 0;
        size_t len = strlen(data);
-       size_t output_len = strlen(data) * 2 + 2;
+       size_t output_len = 4 * ((len + 2) / 3) + 2;
+       const unsigned char *ptr = (const unsigned char *) data;
        char *result = malloc(output_len); /* get us plenty of space */
-
-       while (len-- && out_cnt < (output_len) - 5) {
-               int c = (unsigned char) *(data++);
-               bits += c;
-               char_count++;
-               if (char_count == 3) {
-                       result[out_cnt++] = b64[bits >> 18];
-                       result[out_cnt++] = b64[(bits >> 12) & 0x3f];
-                       result[out_cnt++] = b64[(bits >> 6) & 0x3f];
-           result[out_cnt++] = b64[bits & 0x3f];
-           bits = 0;
-           char_count = 0;
-       } else {
-           bits <<= 8;
+       unsigned int bits;
+
+       for (; len >= 3; len -= 3) {
+               bits = (ptr[0] << 16) + (ptr[1] << 8) + ptr[2];
+               ptr += 3;
+               result[out_cnt++] = b64[bits >> 18];
+               result[out_cnt++] = b64[(bits >> 12) & 0x3f];
+               result[out_cnt++] = b64[(bits >> 6) & 0x3f];
+               result[out_cnt++] = b64[bits & 0x3f];
        }
-    }
-    if (char_count != 0) {
-       bits <<= 16 - (8 * char_count);
-       result[out_cnt++] = b64[bits >> 18];
-       result[out_cnt++] = b64[(bits >> 12) & 0x3f];
-       if (char_count == 1) {
-           result[out_cnt++] = '=';
-           result[out_cnt++] = '=';
-       } else {
-           result[out_cnt++] = b64[(bits >> 6) & 0x3f];
-           result[out_cnt++] = '=';
+       if (len != 0) {
+               bits = ptr[0] << 16;
+               if (len > 1)
+                       bits |= ptr[1] << 8;
+               result[out_cnt++] = b64[bits >> 18];
+               result[out_cnt++] = b64[(bits >> 12) & 0x3f];
+               result[out_cnt++] = (len > 1)? b64[(bits >> 6) & 0x3f]: '=';
+               result[out_cnt++] = '=';
        }
-    }
-    result[out_cnt] = '\0';    /* terminate */
-    return result;
+
+       result[out_cnt] = '\0'; /* terminate */
+       return result;
 }
 
 unsigned int run_ntlm_auth(const char *username, 
@@ -305,15 +296,18 @@ unsigned int run_ntlm_auth(const char *username,
 
        if (forkret == 0) {
                /* child process */
+               uid_t uid;
+
                close(child_out[0]);
                close(child_in[1]);
 
                /* run winbind as the user that invoked pppd */
                setgid(getgid());
-               setuid(getuid());
+               uid = getuid();
+               if (setuid(uid) == -1 || getuid() != uid)
+                       fatal("pppd/winbind: could not setuid to %d: %m", uid);
                execl("/bin/sh", "sh", "-c", ntlm_auth, NULL);  
-               perror("pppd/winbind: could not exec /bin/sh");
-               exit(1);
+               fatal("pppd/winbind: could not exec /bin/sh: %m");
        }
 
         /* parent */
@@ -438,6 +432,7 @@ unsigned int run_ntlm_auth(const char *username,
 
         /* parent */
         if (close(child_out[0]) == -1) {
+                close(child_in[1]);
                 notice("error closing pipe?!? for child OUT[0]");
                 return NOT_AUTHENTICATED;
         }
@@ -448,7 +443,7 @@ unsigned int run_ntlm_auth(const char *username,
                 return NOT_AUTHENTICATED;
         }
 
-       while ((wait(&status) == -1) && errno == EINTR)
+       while ((wait(&status) == -1) && errno == EINTR && !got_sigterm)
                 ;
 
        if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) {