Logo Search packages:      
Sourcecode: gadmin-proftpd version File versions  Download package

osx_functions.c

/* GADMIN-PROFTPD - An easy to use GTK+ frontend for the ProFTPD standalone server.
 * Copyright (C) 2001 - 2008 Magnus Loef <magnus-swe@telia.com> 
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
*/



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
#include "allocate.h"
#include "chars_are_digits.h"

/* This file will be created from nidump passwd / itll then be read
 * and removed (cant use /etc/passwd since its not kept current) */
#define GP_OSX_PASS_DUMP "/etc/gp_osx_passdump"



int 
niutil_run_command(char *command)
{
    /* Run a command */
    FILE * fp;
    int i=0;

    if((fp=popen(command, "r"))==NULL)
    {
        printf("\nError running %s\n", command);
    }
    else
      {
        pclose(fp);
        i = 1;
      }

    return i;
}


int
unlink_file(char *entity)
{
    char *command;
    int unlink=0;
    
    if( ! file_exists(entity) )
    {
      printf("Unlink: the file [%s] does not exist.\n", entity);
      unlink = 1;
    }
    else
      {
        command = allocate(8192);

        /* Remove the temporary file */
        sprintf(command, "rm -f /etc/%s", entity);
        if( ! niutil_run_command(command) )
        {
           printf("Error running: %s\n", command);
           free(command);
           exit (1);
        }
        
        free(command);
          unlink = 1;
      }

    return unlink;
}


int
niutil_user_exists(G_CONST_RETURN gchar *username)
{
    /* Checks if the system user exists */
    FILE *fp;
    long conf_size;
    int x, user_exists=0;
    char tempname[4096]="";
    char *check_buffer, *command;

    command = allocate(8192);

    sprintf(command, "/usr/bin/nidump passwd / > %s", GP_OSX_PASS_DUMP);
    
    if( ! niutil_run_command(command) )
    {
      free(command);
        return user_exists;
    }

    free(command);

    /* Checks if the user exists in passwd */
    if((fp=fopen(GP_OSX_PASS_DUMP,"r"))==NULL)
    {
      printf("Cannot open the nidump:ed passwd file.\n");
      return user_exists;
    }
    else
      {
          fseek(fp, 0, SEEK_END);
          conf_size = ftell(fp);
          rewind(fp);
          check_buffer = allocate(conf_size);
          while(fgets(check_buffer, conf_size, fp)!=NULL)
          {
            for(x=0; check_buffer[x]; x++)
            {
                if(check_buffer[x]==':')
                {
                  sprintf(tempname, check_buffer);
                  tempname[x]='\0';
                  if( ! strcmp(username, tempname) )
                  {
                      user_exists=1;
                      break;
                  }
                }
                if( check_buffer[x]=='\0' || check_buffer[x]=='\n' )
                break;
            }
            if( user_exists )
              break;
          }
          free(check_buffer);
          fclose(fp);
      }

    unlink_file(GP_OSX_PASS_DUMP);
    return user_exists;
}


int
niutil_get_free_uid_above_500_()
{
    FILE *fp;
    int i=0, begin=0, end=0, colon=0;
    long length, uid=0, num=0;
    char *command, *buffy, *tempuid, *gp_err=NULL;
    
    command = allocate(8192);

    sprintf(command, "/usr/bin/nidump passwd / > %s", GP_OSX_PASS_DUMP);
    if( ! niutil_run_command(command) )
    {
      free(command);
        return uid;
    }

    free(command);

    if( ! file_exists(GP_OSX_PASS_DUMP) )
    {
      printf("\nError: passwd file not found: %s\n", GP_OSX_PASS_DUMP);
      unlink_file(GP_OSX_PASS_DUMP);
        return uid;
    } 


    /* Determine what gid is free and above 500 */
    if((fp=fopen(GP_OSX_PASS_DUMP, "r"))==NULL)
    {
      unlink_file(GP_OSX_PASS_DUMP);
      return uid;    
    }

    fseek(fp, 0, SEEK_END);
    length=ftell(fp);
    rewind(fp);
        
    buffy = allocate(length);

    tempuid = allocate(8192);

    while(fgets(buffy, length, fp)!=NULL)
    {
      /* Dont acctept bad input */
      if( strlen(buffy) < 3 || strlen(buffy) > 1024 )
        continue;

      colon=0; num=0;
      begin=0; end=0;
      
      /* Get the beginning of the gid */
      for(i=0; buffy[i]!='\0'; i++)
      {
          if( buffy[i]==':' )
            colon++;
              
          /* We have found the beginning of the uid */
          if( colon==2 )
          {
              begin=++i;
              break;
          }
      }

      /* Get the end of the uid */
      for(i=i; buffy[i]!='\0'; i++)
      {
          end++;
          if( buffy[i]==':' )
          {
            --end;
            /* strncpy(tempgid, &buffy[begin], end); grr */
            sprintf(tempuid, &buffy[begin]);

            /* Terminate it after the last digit */
            tempuid[end]='\0';
                
            /* Collect the greatest uid */
            if( chars_are_digits(tempuid) )
            {
                /* Conversion to a valid long uid_t */
                num = (uid_t) strtol(tempuid, &gp_err, 10);
                if( gp_err && *gp_err )
                  printf("Error Converting a valid long uid\n");
                else              
                if( num > uid )
                  uid=num;

                if(LONG_MIN==num)
                  printf("LONG_MIN Conversion for uid\n");

                if(LONG_MAX==num)
                  printf("LONG_MAX Conversion for uid\n");

                if(errno==ERANGE)
                  printf("Conversion out of range for uid\n");
            }
            /* No need to report a non digit or a negative value */
            break;
          }
      }
    }

    free(buffy);
    free(tempuid);

    unlink_file(GP_OSX_PASS_DUMP);

    /* Add 1 to uid */
    uid++;

    if( uid <= 499 )
      return 500;
    else
      return uid;
}


int
niutil_get_free_gid_above_500_()
{
    /* FIXME USE uid_t and gid_t */
    FILE *fp;
    int i=0, begin=0, end=0, colon=0;
    long length, gid=0, num=0;
    char *command, *buffy, *tempgid, *gp_err=NULL;
    
    command = allocate(8192);

    sprintf(command, "/usr/bin/nidump passwd / > %s", GP_OSX_PASS_DUMP);
    if( ! niutil_run_command(command) )
    {
      free(command);
        return gid;
    }

    free(command);


    if( ! file_exists(GP_OSX_PASS_DUMP) )
    {
      printf("\nError: passwd file not found: %s\n", GP_OSX_PASS_DUMP);
        return gid;
    } 


    /* Determine what gid is free and above 500 */
    if((fp=fopen(GP_OSX_PASS_DUMP, "r"))==NULL)
    {
      return gid;    
    }

    fseek(fp, 0, SEEK_END);
    length=ftell(fp);
    rewind(fp);
        
    buffy = allocate(length);

    tempgid = allocate(8192);

    while(fgets(buffy, length, fp)!=NULL)
    {
      /* Dont acctept bad input */
      if( strlen(buffy) < 3 || strlen(buffy) > 1024 )
        continue;

      colon=0; num=0;
      begin=0; end=0;
      
      /* Get the beginning of the gid */
      for(i=0; buffy[i]!='\0'; i++)
      {
          if( buffy[i]==':' )
            colon++;
              
          /* We have found the beginning of the gid */
          if( colon==3 )
          {
              begin=++i;
              break;
          }
      }

      /* Get the end of the gid */      
      for(i=i; buffy[i]!='\0'; i++)
      {
          end++;
          if( buffy[i]==':' )
          {
            --end;
            sprintf(tempgid, &buffy[begin]);
            /* Terminate it after the last digit */
            tempgid[end]='\0';
                
            /* Collect the greatest gid */
            if( chars_are_digits(tempgid) )
            {
                /* Conversion to a valid long gid_t */
                num = (gid_t) strtol(tempgid, &gp_err, 10);
                if( gp_err && *gp_err )
                  printf("Error Converting a valid long gid \n");
                else              
                if( num > gid )
                  gid=num;

                if(LONG_MIN==num)
                  printf("LONG_MIN Conversion error for gid\n");

                if(LONG_MAX==num)
                  printf("LONG_MAX Conversion error for gid\n");

                if(errno==ERANGE)
                  printf("Conversion out of range for gid\n");
            }
            /* No need to report a non digit or a negative value */
            break;
          }
      }
    }

    free(buffy);
    free(tempgid);

    unlink_file(GP_OSX_PASS_DUMP);

    /* Add 1 to gid */
    gid++;
    
    if( gid <= 499 )
      return 500;
    else
      return gid;
}


int
niutil_useradd(G_CONST_RETURN gchar *username, G_CONST_RETURN gchar *shell)
{
    char *command;
    long uid=0, gid=0, gp_id=0;

    command = allocate(8192);

    /* Create the new users database record */
    sprintf(command, "/usr/bin/niutil -create / /users/%s", username);
    if( ! niutil_run_command(command) )
    {
      printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    /* Add a comment for this user */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s realname %s", username, "ftp-user");
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    if( ! (gid=niutil_get_free_gid_above_500_()) )
    {
        printf("\nError: get_free_gid\n");
      free(command);
      exit (1);
    }

    if( ! (uid=niutil_get_free_uid_above_500_()) )
    {
        printf("\nError: get_free_uid\n");
      free(command);
        exit (1);
    }

    /* We want uid's and gid's to be the same */
    if( uid > gid )
      gp_id = uid;
    else
      gp_id = gid;

    /* Set this users gid */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s gid %li", username, gp_id);
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    /* Set this users uid */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s uid %li", username, gp_id);
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    /* Set this users homedirectory to /dev/null */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s home %s", username, "/dev/null");
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    /* Set the name of the user */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s name %s", username, username);
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }
            
    /* Set the users shell */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s shell %s", username, shell);
    if( ! niutil_run_command(command) )
    {
        printf("Error running: %s\n", command);
      free(command);
      exit (1);
    }

    /*      /usr/bin/niutil -createprop . /users/username change changetime */
    /*      /usr/bin/niutil -createprop . /users/username expire expiretime */

    free(command);

    /* Return true if the user exists */
    return niutil_user_exists(username);
}


int
niutil_userdel(G_CONST_RETURN gchar *username)
{
    int i=0;
    char *command;

    /* Verify that the user really exists */
    if( ! niutil_user_exists(username) )
      return i;

    command = allocate(8192);

    sprintf(command, "/usr/bin/niutil -destroy / /users/%s", username);
    if( ! niutil_run_command(command) )
    {
       printf("Error running: %s\n", command);
    }
    else
      i = 1;

    free(command);

    return i;
}


int
niutil_password_user(G_CONST_RETURN gchar *username, G_CONST_RETURN gchar *password)
{
    /* Password a user */
    int i=0;
    char *command, *encrypted_pass;

    /*      Verify that the user really exists */
    if( ! niutil_user_exists(username) )
      return i;

    /* Crypt return value should not be freed */
    encrypted_pass = encrypt_password(password);

    if( encrypted_pass == NULL )
    {
      printf("\nCrypt failed.\n");
      exit (1);
    }

    command = allocate(8192);

    /* 'Encrypted Password' otherwise the shell might swallow it */
    sprintf(command, "/usr/bin/niutil -createprop / /users/%s passwd '%s'", username, encrypted_pass);
    if( ! niutil_run_command(command) )
    {
       printf("Error running: %s\n", command);
       free(command);
       exit (1);
    }
    else
      i = 1;

    free(command);

    return i;
}

Generated by  Doxygen 1.6.0   Back to index