[1803] in Moira

home help back first fref pref prev next nref lref last post

windcm.gen

daemon@ATHENA.MIT.EDU (Qing Dong)
Tue Jun 12 10:38:54 2001

Message-Id: <200106121438.KAA18440@melbourne-city-street.mit.edu>
Date: Tue, 12 Jun 2001 10:38:39 -0400
To: moiradev@mit.edu
From: Qing Dong <dongq@MIT.EDU>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"

The Pismere team needs a DCM-like process to synchronize
Active Directory with Moira. The following program generates 
the text files containing Moira user, list, list membership, and 
user homedirectory info to be used by Windows AD update.
Our process will be used to perform the AD initial bulk-load, 
occasional synchronization between AD and moira, and
begin-term and end-of-term operations. 

Let me know if you have any questions and comments. 

Thanks. 
Qing

/* $Id: windcm.pc,v 1.1.1.1 2001/06/11 20:54:02 dongq Exp $
 *
 * This generates the user, list, list membership, filesys data
 * for windows active directory update
 *
 * (c) Copyright 1988-2001 by the Massachusetts Institute of Technology.
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 */

#include <mit-copyright.h>
#include <moira.h>
#include <moira_site.h>

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "util.h"

EXEC SQL INCLUDE sqlca;

#ifndef WINDCM_SUBDIR
#define WINDCM_SUBDIR "windcm"
#endif

char windcm_dir[MAXPATHLEN];
char *whoami = "windcm.gen";
char *db = "moira/moira";

int do_user(void);
int do_groups(void);
int do_groupmembership(void);
int do_filesys(void);


int main(int argc, char **argv)
{
  char cmd[64];
  struct stat sb;
  int changed = 0;

  if (argc > 2)
    {
      fprintf(stderr, "usage: %s [outfile]\n", argv[0]);
      exit(MR_ARGS);
    }

  initialize_sms_error_table();
  sprintf(windcm_dir, "%s/%s", DCM_DIR, WINDCM_SUBDIR);

  EXEC SQL CONNECT :db;

  changed = do_user();
  changed += do_groups();
  changed += do_groupmembership();
  changed += do_filesys();

  if (!changed)
  {
    fprintf(stderr, "No files updated.\n");
    if (argc == 2 && stat(argv[1], &sb) == 0)
	    exit(MR_NO_CHANGE);
  }

  if (argc == 2)
  {
    fprintf(stderr, "Building tar file.\n");
    sprintf(cmd, "cd %s; tar cf %s .", windcm_dir, argv[1]);
    if (system(cmd))
	    exit(MR_TAR_FAIL);
  }

  exit(MR_SUCCESS);
}


int do_user(void)
{
  FILE *fout;
  char foutf[MAXPATHLEN];
  char foutft[MAXPATHLEN];
  EXEC SQL BEGIN DECLARE SECTION;
  char login[USERS_LOGIN_SIZE];
  char mit_id[USERS_CLEARID_SIZE];
  int users_id, unix_uid, status;
  EXEC SQL END DECLARE SECTION;

  sprintf(foutf, "%s/winuser.db", windcm_dir);
  sprintf(foutft, "%s~", foutf);

  fout = fopen(foutft, "w");
  if (!fout)
  {
    perror("cannot open winuser.db for write");
    exit(MR_OCONFIG);
  }

  EXEC SQL DECLARE u_cursor CURSOR FOR
    SELECT users_id, login, unix_uid, status, clearid
    FROM users
    ORDER BY users_id;
  EXEC SQL OPEN u_cursor;
  while (1)
    {
      EXEC SQL FETCH u_cursor INTO :users_id, :login, :unix_uid, :status,
:mit_id;
      if (sqlca.sqlcode)
	      break;
      strtrim(login);
      strtrim(mit_id);
      
      fprintf(fout, "%d %s %d %d %s\n",
		    users_id, login, unix_uid, status, mit_id);
	}

  if (sqlca.sqlcode < 0)
    db_error(sqlca.sqlcode);
  EXEC SQL CLOSE u_cursor;
  EXEC SQL COMMIT;

  if (fclose(fout))
  {
    fprintf(stderr, "Unsuccessful file close of winuser.db\n");
    exit(MR_CCONFIG);
  }

  fix_file(foutf);

  return 1;
}

int do_groups(void)
{
  FILE *fout;
  char foutf[MAXPATHLEN];
  char foutft[MAXPATHLEN];
  EXEC SQL BEGIN DECLARE SECTION;
  char listname[LIST_NAME_SIZE];
  int list_id, active, maillist, grouplist;
  EXEC SQL END DECLARE SECTION;

  sprintf(foutf, "%s/wingroup.db", windcm_dir);
  sprintf(foutft, "%s~", foutf);

  fout = fopen(foutft, "w");
  if (!fout)
  {
    perror("cannot open wingroup.db for write");
    exit(MR_OCONFIG);
  }

  EXEC SQL DECLARE l_cursor CURSOR FOR
    SELECT list_id, name, active, maillist, grouplist
    FROM list
    ORDER BY list_id;
  EXEC SQL OPEN l_cursor;
  while (1)
    {
      EXEC SQL FETCH l_cursor INTO :list_id, :listname, :active, :maillist,
:grouplist;
      
      if (sqlca.sqlcode)
	      break;
      strtrim(listname);
      
      fprintf(fout, "%d %s %d %d %d\n",
		    list_id, listname, active, maillist, grouplist);
	}

  if (sqlca.sqlcode < 0)
    db_error(sqlca.sqlcode);
  EXEC SQL CLOSE l_cursor;
  EXEC SQL COMMIT;

  if (fclose(fout))
  {
    fprintf(stderr, "Unsuccessful file close of wingroup.db\n");
    exit(MR_CCONFIG);
  }

  fix_file(foutf);
  return 1;
}

int do_groupmembership(void)
{
  FILE *fout;
  char foutf[MAXPATHLEN];
  char foutft[MAXPATHLEN];
  EXEC SQL BEGIN DECLARE SECTION;
  char member_type[IMEMBERS_MEMBER_TYPE_SIZE];
  char member_name[STRINGS_STRING_SIZE];
  int list_id;
  EXEC SQL END DECLARE SECTION;

  sprintf(foutf, "%s/wingmember.db", windcm_dir);
  sprintf(foutft, "%s~", foutf);

  fout = fopen(foutft, "w");
  if (!fout)
  {
    perror("cannot open wingmember.db for write");
    exit(MR_OCONFIG);
  }

  EXEC SQL DECLARE list_cursor CURSOR FOR
    SELECT list_id
    FROM list
    ORDER BY list_id;
  EXEC SQL OPEN list_cursor;
  while (1)
    {
      EXEC SQL FETCH list_cursor INTO :list_id;
      
      if (sqlca.sqlcode)
	      break;
      
      /* get all the users */
      EXEC SQL DECLARE csr001 CURSOR FOR
        SELECT i.member_type, u.login
        FROM users u, imembers i
        WHERE i.list_id = :list_id AND i.member_type = 'USER'
        AND i.member_id = u.users_id 
        ORDER BY u.login;

      EXEC SQL OPEN csr001;
      while(1)
      {
        EXEC SQL FETCH csr001 into :member_type, :member_name;
        if (sqlca.sqlcode)
          break;
        fprintf(fout, "%d %s %s\n",
		      list_id, member_type, member_name);
      }

      if (sqlca.sqlcode < 0)
        db_error(sqlca.sqlcode);
      EXEC SQL CLOSE csr001;

      /* get all the KERBEROS AND STRINGS */
      EXEC SQL DECLARE csr002 CURSOR FOR
        SELECT i.member_type, s.string
        FROM strings s, imembers i
        WHERE i.list_id = :list_id AND 
        (i.member_type = 'KERBEROS' OR i.member_type = 'STRING')
        AND i.member_id = s.string_id 
        ORDER BY s.string;

      EXEC SQL OPEN csr002;
      while(1)
      {
        EXEC SQL FETCH csr002 into :member_type, :member_name;
        if (sqlca.sqlcode)
          break;
        fprintf(fout, "%d %s %s\n",
		      list_id, member_type, member_name);
      }

      if (sqlca.sqlcode < 0)
        db_error(sqlca.sqlcode);

      EXEC SQL CLOSE csr002;
	}

  if (sqlca.sqlcode < 0)
    db_error(sqlca.sqlcode);

  EXEC SQL CLOSE list_cursor;
  EXEC SQL COMMIT;

  if (fclose(fout))
  {
    fprintf(stderr, "Unsuccessful file close of wingmember.db\n");
    exit(MR_CCONFIG);
  }

  fix_file(foutf);
  return 1;
}


int do_filesys(void)
{
  FILE *fout;
  char foutf[MAXPATHLEN];
  char foutft[MAXPATHLEN];
  EXEC SQL BEGIN DECLARE SECTION;
  char type[FILESYS_TYPE_SIZE];
  char name[FILESYS_NAME_SIZE];
  int users_id;
  EXEC SQL END DECLARE SECTION;

  sprintf(foutf, "%s/winfilesys.db", windcm_dir);
  sprintf(foutft, "%s~", foutf);

  fout = fopen(foutft, "w");
  if (!fout)
  {
    perror("cannot open winfilesys.db for write");
    exit(MR_OCONFIG);
  }

  EXEC SQL DECLARE f_cursor CURSOR FOR
    SELECT owner, type, name
    FROM filesys 
    where lockertype = 'HOMEDIR'
    ORDER BY owner;
  EXEC SQL OPEN f_cursor;
  while (1)
    {
      EXEC SQL FETCH f_cursor INTO :users_id, :type, :name;
      if (sqlca.sqlcode)
	      break;
      strtrim(type);
      strtrim(name);
      
      fprintf(fout, "%d %s %s\n",
		    users_id, type, name);
	}

  if (sqlca.sqlcode < 0)
    db_error(sqlca.sqlcode);
  EXEC SQL CLOSE f_cursor;
  EXEC SQL COMMIT;

  if (fclose(fout))
  {
    fprintf(stderr, "Unsuccessful file close of winfilesys.db\n");
    exit(MR_CCONFIG);
  }

  fix_file(foutf);
  return 1;
}



home help back first fref pref prev next nref lref last post